JavaGame角色在绘制时无法正确移动? [英] JavaGame character is not moving accurately while drawing?

查看:102
本文介绍了JavaGame角色在绘制时无法正确移动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于个人实践,我正在用Java来为桌面制作Flappy bird,我设法完成了所有支柱的生成,屏幕,bg的移动,但是现在我遇到了一个问题,那就是性能.

for personal practice, I am remaking Flappy bird for desktop with Java, I have managed to get all the pillars generating, screen, bg moving done, but now I have one problem, which is performance.

我有时会觉得游戏的移动速度不够快,有时会停留0.5秒钟左右,但事实并非如此,当我移动鸟时,它的运动有点怪异,看起来运动太多了向前&然后回到背面,以MP4格式观看gif:

I sometimes feel that the game isn't moving as fast, and sometimes gets stuck for 0.5 secs or something, but that's not the case, when I move my bird, it's moving a bit weird, looks like its moving too much forward & then to the back, watch the gif in MP4 format:

http://gyazo.com/d7e94c0b772192e5a5dd1d2b61b8c529

可能是什么原因造成的?这可能是我的游戏循环还是我绘制图形的方式?我不使用双重缓冲,我只是通过在jframe中调用.repaint来进行渲染,从而重新绘制我添加的JPanel.

What could be causing that? could this be my game loop or the way I draw the graphics? I don't use double buffering, I render simply by calling .repaint in jframe which repaints the JPanel I added.

游戏循环:

private void gameLoop() {
    new Thread() {
        private long last;
        private long start;
        private int wait;
        public void run() {
            while(game) {
                long now = System.nanoTime();
                long length = now - lastLoop;
                lastLoop = now;
                double delta = length / ((double) Constants.OPTIMAL);
                lastFps += length;
                fps++;
                if (lastFps >= 1000000000) {
                    System.out.println("FPS: " + fps);
                    lastFps = 0;
                    fps = 0;
                }
                update(delta);
                render();
                this.sleep
            }
        }
        private void sleep() {
            try {
                Thread.sleep((this.last - System.nanoTime() + Constants.OPTIMAL) / 1000000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }.start();
}

我的绘图区域:

public void paintComponent(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    int translateAmount = this.game.getLevel().getTranslate();
    g.translate(-translateAmount, 0);
    this.background.render(g2d);        
    this.game.getLevel().renderLevel(g2d);
    g.translate(0, 0);
    this.game.getBird().render(g2d);

}

我渲染背景的方式是这样的:我一个接一个地添加背景,如果背景不在框架之外,则不会渲染.

The way I render the backgrounds is this: I add backgrounds one after one, and if a background is outside of the frame, i won't render it.

public void render(Graphics2D g) {
    Iterator<RepeatedBackground> itr = this.repeats.iterator();
    while (itr.hasNext()) {
        RepeatedBackground b = itr.next();
        if (this.game.getLevel().getTranslate() - b.getX() >= 300) {
            itr.remove();
            continue;
        }
        if (b.getX() - this.game.getLevel().getTranslate() < Constants.WIDTH) {
            b.render(g);
        }
    }
}

这是我移动鸟的方式(我不使用三角洲,对此使用了一些教程):

This is how I move my bird (i dont use delta, used some tutorial on this):

private void update(double delta) {
    if (System.currentTimeMillis() - this.level.getTime() >= Constants.TRANSLATE_SPEED) {

        // move background
        this.level.updateTranslate();
        this.level.setTime();

        // move bird
        this.getBird().move();
    }
}

public void move() {
    this.x += 2 / 1.10;
}

是什么原因导致鸟类或背景出现滞后?我的渲染方式或游戏循环有问题吗?

What could be causing lag to the bird or the background? Is there something wrong with my rendering ways or game loop?

Fps始终打印此内容:

Fps always printing this:

FPS: 1724172
FPS: 1551857
FPS: 1494378
FPS: 1471987
FPS: 1434095
FPS: 1629905

推荐答案

您的游戏循环使我感到困惑-但这并不难;)

Your game loop confuses me - but that's not hard ;)

基本上,据我所知,它应该类似于...

Basically, as I understand these things, it should work something like...

while (gamming) {
    now = get current time;
    update game state
    delta = get current time - now
    delay = desired delay - delta
    wait for delay
}

您似乎没有考虑到renderupdate方法可能"执行所需的时间,并没有根据这些要求计算等待时间...

You don't seem to be taking into account the amount of time that the render and update methods "might" take to execute and calculating the time to wait based those requirements...

现在,我不确定您的delta值应该是...当前秒的时间?因此,我将其排除在示例之外...

Now, I'm not sure what your delta values is suppose to be...the time through the current second?? So I've left it out of my example...

以下示例为我提供了恒定的25fps,即使updaterender方法中存在随机延迟

The following example gives me a constant 25fps, even with the random delays in the update and render methods

现在,请原谅,我通常只需要几毫秒即可完成工作,但对我可怜的,虚弱的头脑来说,这只是简单一点.

Now, forgive me, I typically work in milli seconds, it's just simpler on my poor, feeble mind.

import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

public class TestGameLoop {

    public static void main(String[] args) {
        new TestGameLoop();
    }

    public TestGameLoop() {
        gameLoop();
    }

    public static class Constants {

        public static final double OPTIMAL = 25; // fps...

    }

    private boolean game = true;
    private long lastLoop;
    private long lastFps;
    private long fps;

    private void gameLoop() {
        new Thread() {

            private long last;
            private long start;
            private int wait;

            public void run() {

                // Calculate the optimal/maximum delay time
                // This is converted to nanos so it can be 
                // used to calculate the actual delay...
                long millisPerSecond = TimeUnit.MILLISECONDS.convert(1, TimeUnit.SECONDS);
                long optimalDelay =  Math.round(millisPerSecond / Constants.OPTIMAL);

                optimalDelay = TimeUnit.MILLISECONDS.toNanos(optimalDelay);

                // Last start of a "second" loop                    
                long loop = System.nanoTime();
                // While gaming...
                while (game) {
                    // Start of this cycle...
                    long now = System.nanoTime();

                    // Update the state and render the 
                    // current frame...
                    update();
                    render();

                    // How long did that update take??
                    long timeTaken = System.nanoTime();
                    long delta = timeTaken - now;

                    // Subtract the delay from the maximum delay
                    long delay = optimalDelay - delta;
                    if (delay > 0) {
                        try {
                            // Sleep expects milliseconds...
                            delay = TimeUnit.NANOSECONDS.toMillis(delay);
                            Thread.sleep(delay);
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }

                    // Calculate if we've being running for a second yet...
                    long loopDelay = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - loop);
                    // If the loop has been cycling for a second...
                    if (loopDelay >= 1) {
                        // Reset the loop time
                        loop = System.nanoTime();
                        System.out.println("FPS = " + fps);
                        fps = 0;
                    } else {
                        // Add another frame to the pile...
                        fps++;
                    }
                }
            }
        }.start();
    }

    public void update() {
        try {
            Thread.sleep(Math.round(Math.random() * 20));
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }

    public void render() {
        try {
            Thread.sleep(Math.round(Math.random() * 20));
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }

}

这篇关于JavaGame角色在绘制时无法正确移动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆