CreedVI / Raylib-J

Handmade Java binding for Raylib
zlib License
91 stars 15 forks source link

Not able to create objects in main game loop? #41

Closed BlueFalcon234 closed 1 year ago

BlueFalcon234 commented 1 year ago

So when I try creating my own object I made in the main game loop based on a mouse click, I got a Java NullPointerException error. In my main file, it shows the error occurs at the line right after when my object is created at the next use of the raylib-j object. I have tested this out, creating my objects in different places in the main loop, then seeing the error log says the line that causing the problem is the next use of the raylib-j object that comes right after the when my object is created. This seems to only apply to main raylib-j object (example rlj.shapes.DrawRectangle), and not the other raylib objects (example rCore.IsKeyDown())

To try to recreate this problem: Have a basic raylib-j example (like ball moment example), then create another class file to do anything basic, then create that object in the main game loop.

I am using a compiled version of the latest main branch of the Raylib-J library.

Is this a problem/bug on how the main rlj object works? Is there a fix?

EDIT: After a little more testing, I realized that the object it self was causing the error, as the object I was creating has the raylib object in the object. I did this so I can for example represent a player in its own object, with its own draw function inside. However calling this object outside the game loop works fine, just not in the game loop. Does that mean I can’t have my objects have the rlj object inside of them if I intend on creating my objects in the game loop? I want to do this, as so I can dynamically create objects, like being able to make Block objects wherever the player clicks.

Thanks in advance for any help

CreedVI commented 1 year ago

The Raylib-J object manages the OpenGL context, so creating multiple instances won't work. If you want to call Raylib-J methods from other classes it's recommended to use public static Raylib in your main class and import it in your other files.

BlueFalcon234 commented 1 year ago

Ah I see what your trying to say, but I’m getting some errors (I don’t think am exactly doing this right) If you don’t mind, can I see a quick example on how to got about doing this?

CreedVI commented 1 year ago

Main.java

package com.creedvi.example.imports;

import com.creedvi.example.imports.NewShape.Circle;
import com.raylib.java.Raylib;
import com.raylib.java.core.Color;
import com.raylib.java.core.rcamera.Camera2D;
import com.raylib.java.raymath.Vector2;

import java.util.ArrayList;

import static com.raylib.java.core.input.Mouse.MouseButton.MOUSE_BUTTON_LEFT;

public class Main {

    final static boolean DEBUG = true;

    public static Raylib rlj;

    final static int SCREEN_WIDTH = 800, SCREEN_HEIGHT = 600;

    static ArrayList<Circle> circles;
    static Camera2D camera;

    public static void main(String[] args) {

        rlj = new Raylib(SCREEN_WIDTH, SCREEN_HEIGHT, "Untitled Raylib-J Project");
        rlj.core.SetTargetFPS(60);

        camera = new Camera2D();
        camera.target = new Vector2();
        camera.offset = new Vector2();
        camera.rotation = 0.0f;
        camera.zoom = 1.0f;

        circles = new ArrayList<>();

        while (!rlj.core.WindowShouldClose()) {
            Update();
            Render();
        }

    }

    private static void Update() {
        if (rlj.core.IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
            circles.add(new Circle(rlj.core.GetMousePosition()));
            System.out.println("Circle " + circles.size() + " Pos: " + rlj.core.GetMouseX() + ", " + rlj.core.GetMouseY());
        }
        for (Circle c: circles) {
            c.Update();
        }
    }

    private static void Render() {
        rlj.core.BeginDrawing();
        rlj.core.ClearBackground(Color.RAYWHITE);
        rlj.core.BeginMode2D(camera);

        for (Circle c: circles) {
            c.Render();
        }

        rlj.core.EndMode2D();
        rlj.core.EndDrawing();
    }

}

Circle.java

package com.creedvi.example.imports.NewShape;

import com.raylib.java.core.Color;
import com.raylib.java.raymath.Vector2;

import static com.creedvi.example.imports.Main.rlj;

public class Circle {

    public Vector2 position;
    public float radius;
    public Color colour;

    public Circle() {
        position = new Vector2();
        radius = 10f;
        colour = new Color(rlj.core.GetRandomValue(0,255), rlj.core.GetRandomValue(0,255), rlj.core.GetRandomValue(0,255), 255);
    }

    public Circle(Vector2 position) {
        this.position = position;
        radius = 10f;
        colour = new Color(rlj.core.GetRandomValue(0,255), rlj.core.GetRandomValue(0,255), rlj.core.GetRandomValue(0,255), 255);
    }

    public void Update() {

    }

    public void Render() {
        rlj.shapes.DrawCircleV(position, radius, colour);
    }

}

Result: image

BlueFalcon234 commented 1 year ago

This actually makes a lot sense of why and how we use static in this case for the Raylib-J object. Thank you, this was great help CreedVI.