Java Paint组件刷新率?

时间:2012-04-20 20:09:24

标签: java swing animation buffer

我正在开发一个Java小游戏,我正在重写玩家移动系统不是基于网格的。它是一个2D侧卷轴,我想要实现的是基本的播放器移动,这样当用户按下并按住右键时,播放器向右移动,左键相同。我遇到的问题是另一个类中的Paint Component在屏幕上绘制了Player的图像,位置X和Y存储在Settings Class中。然后KeyListener类在用户按下Right时获取,并添加到X值(对于Left,相同,但每次减少1)。这会在屏幕上创建一个缓慢移动的角色,而我想要做的就是让他移动得更快,而不是每次增加超过1px,因为它看起来像是在跳过像素(我已经尝试过了)。

我想知道是否有更好的方法来解决这个问题,因为我使用的代码是最小的,我的结果将是一个平稳移动的播放器。

KeyListener代码段

public void keyPressed(KeyEvent arg0) {
    int key = arg0.getKeyCode();

    if(key == 39) { // Right Key
        Settings.player_pos_x++;
    }else if(key == 37) { // Left Key
        Settings.player_pos_x--;
    }

    main.Game.redo();
}

在屏幕上绘制用户:

g.drawImage(player_image, Settings.player_pos_x, Settings.player_pos_y, this);

如果您需要更多信息或代码,请随时提出帮助。

4 个答案:

答案 0 :(得分:3)

让我们再试一次:))

双缓冲

引用:http://msdn.microsoft.com/en-us/library/b367a457.aspx

  

在编程图形时,闪烁是一个常见问题。需要的图形操作       多个复杂的绘制操作可能导致渲染图像看起来闪烁       或者有一种不可接受的外表。

     

启用双缓冲后,首先将所有绘制操作渲染到内存中       缓冲而不是屏幕上的绘图表面。完成所有油漆操作后       完成后,将内存缓冲区直接复制到与之关联的绘图表面       它。因为在屏幕上只执行一个图形操作,所以图像       消除了与复杂绘画操作相关的闪烁。

引用:http://docs.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html

  

假设您必须在屏幕上逐个像素或逐行绘制整个图片       线。如果你要直接在屏幕上绘制这样的东西(比方说,使用       Graphics.drawLine),你可能会注意到它需要很多失望       一点时间。你甚至可能会注意到你的照片是如何产生的       画。大多数情况下,不是以这种方式和按照这种速度观察事物       程序员使用一种称为双缓冲的技术。

答案 1 :(得分:1)

也许您可以编写应用程序来向右侧重复多次重绘,每个键盘输入只接收1或2个像素。通过这种方式,您可以人为地设置您希望它移动的速度。否则,您将受限于用户如何设置键盘迭代速度。

此外,java的jPanel并不是寻找视频游戏效率的地方。只是说;你可能想看看像openGL这样的东西。

充其量,你可以优化它以在jpanel绘图逻辑之外有一个转换缓冲区,具有与jPanel相同的绘制功能,这样你就可以写入缓冲区,然后在writeImage调用期间复制整个缓冲区。我不知道你是否已经这样做了,但我认为它可以避免闪烁或其他东西......很久以前就读过它,它叫做双缓冲。

答案 2 :(得分:1)

虽然双缓冲可能会有所帮助,但您应首先解决每次计算距离的方式。

距离变化(dx)可定义为速度(v)乘以时间变化(dt),dx = v * dt。从我所看到的你省略dt(时间的变化)。您应该计算与上次移动角色时的时差,并将其乘以速度。这样,如果您的距离处理代码在10秒内执行10次或100次,则角色将始终移动相同的距离。

代码看起来像这样:

int currentTime = System.nanoTime();
int deltaTime = currentTime - previousTime;

Settings.player_pos_x += velX * deltaTime;

previousTime = currentTime;

使用此代码,您可能需要显着增加velX。通常我会有一个常数,我会乘以速度,所以它们是较小的数字。

此外,如果你想要更好的运动和物理观察JBox2D虽然它现在可能已经过度杀了你。他们的文档也可能有助于理解基础物理。

答案 3 :(得分:0)

为了回答你关于速度的问题,我见过的大多数游戏都存储了每个平面(x和y平面)中的速度的全局int,然后将速度应用到当前位置而不是简单地将其递增为你已经完成了上述工作。

public int velX = 2;
public int velY = 2;

public void keyPressed(KeyEvent arg0) { 
    int key = arg0.getKeyCode(); 

    if(key == 39) { // Right Key 
        Settings.player_pos_x += velX; 
    }else if(key == 37) { // Left Key 
        Settings.player_pos_x -= velX; 
    } 

    main.Game.redo(); 
} 

完成设置后,尝试添加可能会提高速度的操作(即长时间按住键或其他内容);

此外,尝试实施一个跳跃操作,玩家Y的位置会上升,并尝试添加一个重力场以使其恢复原状。