0

所以我刚刚开始使用 LWJGL,我正在尝试创建一个简单的 2D 平台游戏。我目前争论的问题是纹理加载。问题是,只要我将所有与纹理加载相关的方法保留在 main 方法的类中,一切都非常整洁。

只要我将它移到一个单独的类TextureHandler中,它就不会起作用,除非我将loadTexture()方法添加到drawTexture()方法中。那么问题是,据我所知,它每帧都会不断地制作新对象。我已经用谷歌搜索了几个小时,但我一生都找不到解决方案。

主类:

public class Main {
    String playerPath = "res/PlayerNeutral.png";

    public void render() {
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
    }

    public void initGL() {
        try {
            Display.setDisplayMode(new DisplayMode(800, 600));
            Display.create();
            Display.setVSyncEnabled(true);
        }
        catch (LWJGLException e) {
            e.printStackTrace();

            System.exit(0);
        }

        // Initiating OpenGL
        GL11.glViewport(0, 0, 800, 600);
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glEnable(GL11.GL_TEXTURE_2D);

        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

        // Enables the Alpha Blending
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

        GL11.glMatrixMode(GL11.GL_MODELVIEW);

        GL11.glOrtho(0, 800, 0, 600, 1, -1);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
    }

    public void start() {
        initGL();

        TextureHandler.loadTexture(Player.playerText, playerPath);

        while (!Display.isCloseRequested()) {
            render();
            TextureHandler.drawTexture(Player.playerText, playerPath);          
            Display.update();
        }

        Display.destroy();      
    }

    public static void main(String[] args) {
        Main test = new Main();
        test.start();
    }

TextureHandler 类:

public class TextureHandler {
    public static void textRelease(Texture text){
        text.release();
    }

    public static void loadTexture(Texture texture, String path){
        try {
            texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(path));

            System.out.println("Texture loaded: "+texture);
            System.out.println(">> Image width: "+texture.getImageWidth());
            System.out.println(">> Image height: "+texture.getImageHeight());
            System.out.println(">> Texture width: "+texture.getTextureWidth());
            System.out.println(">> Texture height: "+texture.getTextureHeight());
            System.out.println(">> Texture ID: "+texture.getTextureID());

            TextureImpl.unbind();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void drawTexture(Texture texture, String path) {
        try {
            texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(path));

            System.out.println("Texture loaded: "+texture);
            System.out.println(">> Image width: "+texture.getImageWidth());
            System.out.println(">> Image height: "+texture.getImageHeight());
            System.out.println(">> Texture width: "+texture.getTextureWidth());
            System.out.println(">> Texture height: "+texture.getTextureHeight());
            System.out.println(">> Texture ID: "+texture.getTextureID());
        } catch (IOException e) {
            e.printStackTrace();
        }

        Color.white.bind();
        texture.bind();

        GL11.glBegin(GL11.GL_QUADS);
            GL11.glTexCoord2f(0, 1);
            GL11.glVertex2f(100, 100);
            GL11.glTexCoord2f(1, 1);
            GL11.glVertex2f(100+texture.getTextureWidth(), 100);
            GL11.glTexCoord2f(1, 0);
            GL11.glVertex2f(100+texture.getTextureWidth(), 100+texture.getTextureHeight());
            GL11.glTexCoord2f(0, 0);
            GL11.glVertex2f(100, 100 + texture.getTextureHeight());
        GL11.glEnd();

        texture.release();
    }
}

球员等级:

public class Player {
    private int x;//x pos on screen
    private int y;//y pos on screen
    public static Texture playerText;

    // method for moving the player object around
    public void move() {
        if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT))
            x++;
        if (Keyboard.isKeyDown(Keyboard.KEY_LEFT))
            x--;
        if (Keyboard.isKeyDown(Keyboard.KEY_UP))
            y++;
        if (Keyboard.isKeyDown(Keyboard.KEY_DOWN))
            y--;
    }
}
4

1 回答 1

0

那是因为在您的drawTexture()方法中,您执行以下操作。

try {
    texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(path));

    System.out.println("Texture loaded: "+texture);
    System.out.println(">> Image width: "+texture.getImageWidth());
    System.out.println(">> Image height: "+texture.getImageHeight());
    System.out.println(">> Texture width: "+texture.getTextureWidth());
    System.out.println(">> Texture height: "+texture.getTextureHeight());
    System.out.println(">> Texture ID: "+texture.getTextureID());
} catch (IOException e) {
    e.printStackTrace();
}

drawTexture()只需从您的方法中删除上述代码即可。

loadTexture()纹理仍然会被加载,因为在进入渲染循环之前,您已经通过调用方法完成了一次。

编辑

我很确定我已经尝试过了。我确实想记住我把它放在那里,因为没有它它就无法工作,如果你愿意的话,这是一个“快速修复”。

正如你所说,我刚刚意识到一些事情。你的loadTexture()方法太离谱了。那可能是因为你不知道你不能做那样的事情。

在 Java 中,引用是按值传递的。这意味着,当您通过方法传递变量时,该变量就是该方法的局部变量。因此更改方法内部的变量不会更改原始变量。

例子

我希望你能理解下面的例子。如果你想给一个变量分配一些新的东西,你不能使用通过方法传递的变量来做到这一点。您需要返回它然后分配它。

public class PassingVariables {
    public static void main(String[] args) {
        String s = "Hello World!";

        System.out.println(s); // Prints | Hello World!

        test1(s);

        System.out.println(s); // Prints | Hello World!

        s = test2(s);

        System.out.println(s); // Prints | Testing...

        s = test3(s);

        System.out.println(s); // Prints | Hello World!
    }

    private static String test1(String s) {
        System.out.println(s); // Prints | Hello World!

        s = "Testing...";

        System.out.println(s); // Prints | Testing...
    }

    private static String test2(String s) {
        System.out.println(s); // Prints | Hello World!

        return "Testing...";
    }

    private static String test3(String s) {
        System.out.println(s); // Prints | Testing...

        return "Hello World!";
    }
}

新代码

这是您的代码,我在其中更改了一些内容,因此当我们考虑到上述内容时它将起作用。

public static Texture loadTexture(String path) {
    Texture texture = null;

    try {
        texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(path));

        /* Removed all your println to spare some lines in the answer */

        TextureImpl.unbind();
    }
    catch (IOException e) {
        e.printStackTrace();
    }

    return texture;
}

public static void drawTexture(Texture texture) {
    Color.white.bind();
    texture.bind();

    GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(0, 1);
        GL11.glVertex2f(100, 100);
        GL11.glTexCoord2f(1, 1);
        GL11.glVertex2f(100+texture.getTextureWidth(), 100);
        GL11.glTexCoord2f(1, 0);
        GL11.glVertex2f(100+texture.getTextureWidth(), 100+texture.getTextureHeight());
        GL11.glTexCoord2f(0, 0);
        GL11.glVertex2f(100, 100 + texture.getTextureHeight());
    GL11.glEnd();

    /* 
     * I don't recognize the release() method, but if it deletes the texture
     * then remove if. If it simply unbinds the texture then keep it. If it
     * does remove it, then change it to something like unbind(), if such
     * method exist.
     */
    texture.release();
}

public void start() {
    initGL();

    Player.playerText = TextureHandler.loadTexture(playerPath);

    while (!Display.isCloseRequested()) {
        render();
        TextureHandler.drawTexture(Player.playerText, playerPath);          
        Display.update();
    }

    Display.destroy();      
}
于 2013-11-08T05:15:29.570 回答