Java绘制组件刷新率?
我正在用Java开发一个小游戏,我正在重写玩家移动系统,使其不基于网格。这是一个2D侧边滚动条,我试图实现的是播放器的基本移动,因此当用户按下并按住右键时,播放器会向右移动,左键也是如此。我遇到的问题是,另一个类中的Paint组件在屏幕上绘制播放器的图像,位置X和Y存储在设置类中。然后,当用户按下Right键时,一个KeyListener类会得到一个值,并将其添加到X值中(对于Left值也是如此,但每次都减1)。这会在屏幕上创建一个缓慢移动的角色,我想做的是让他移动得更快,而每次添加的像素数不会超过1px,因为他似乎跳过了像素(我已经尝试过) 我想知道是否有更好的方法来实现这一点,因为我使用的代码是最低限度的,我的结果将是一个平稳运行的播放器 KeyListener片段:Java绘制组件刷新率?,java,swing,animation,buffer,Java,Swing,Animation,Buffer,我正在用Java开发一个小游戏,我正在重写玩家移动系统,使其不基于网格。这是一个2D侧边滚动条,我试图实现的是播放器的基本移动,因此当用户按下并按住右键时,播放器会向右移动,左键也是如此。我遇到的问题是,另一个类中的Paint组件在屏幕上绘制播放器的图像,位置X和Y存储在设置类中。然后,当用户按下Right键时,一个KeyListener类会得到一个值,并将其添加到X值中(对于Left值也是如此,但每次都减1)。这会在屏幕上创建一个缓慢移动的角色,我想做的是让他移动得更快,而每次添加的像素数不会
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);
屏幕上的绘图用户:
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);
非常感谢您的帮助,如果您需要更多信息或代码,请随时询问。也许您可以编写应用程序,在右侧重复多次重画,每个键盘输入仅1或2像素。这样,你就可以人为地设定你想要它移动的速度。否则,您将受限于用户如何设置键盘迭代速度 另外,java的jPanel也不是一个追求视频游戏效率的地方。只是说说而已;为此,您可能希望使用类似openGL的工具 充其量,您可以优化它,使其在jpanel绘图逻辑之外有一个转换缓冲区,具有与jpanel相同的绘图功能,这样您可以写入缓冲区,然后在writeImage调用期间复制整个缓冲区。。。我不知道你是否已经这样做了,但我认为它可以避免闪烁或其他。。。很久以前就读过,它叫做双缓冲。让我们再试一次:) 双缓冲 引述: 闪烁是编程图形时常见的问题。需要 多个复杂的绘制操作可能会导致渲染图像出现闪烁 或者有不可接受的外表 启用双缓冲时,所有绘制操作首先渲染到内存中 缓冲区,而不是屏幕上的绘图面。所有喷漆操作完成后 完成后,内存缓冲区将直接复制到与关联的图形表面 信息技术因为在屏幕上只执行一个图形操作,所以图像 消除了与复杂绘制操作相关的闪烁 引述: 假设你必须在屏幕上画一幅完整的画,逐像素或逐行 线路。如果你把这样的东西直接画到屏幕上(比如, 图形。抽绳),您可能会非常失望地注意到 一点时间。你甚至可能会注意到你的照片是怎样的 绘制。而不是看着事物以这种方式和速度绘制,大多数 程序员使用一种称为双缓冲的技术
为了回答你关于速度的问题,我看过的大多数游戏都会在每个平面(x和y平面)中存储速度的全局整数,然后将速度应用到当前位置,而不是像上面那样简单地增加它
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位置上升时,尝试添加重力场使其下降。而双缓冲可能有助于您首先解决如何计算每次移动的距离 距离变化(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,尽管它现在对您来说可能已经太危险了。他们的文档也可能有助于理解基本物理。双缓冲@Ozzy我不是在开发小程序,这还能用吗?原理是一样的-双缓冲区!看看这个相关的问题:@Ozzy我会试试看。所以KeyListener很好,我应该继续使用它吗?如果你阅读我发布的applet教程链接(上面),你就会明白为什么你需要在动画中使用双缓冲,而监听器与此无关。一个监听器只听一些用户输入。问题不是闪烁,我根本没有。
我的结果将是一个平滑移动的播放器。
如果你想要平滑移动的精灵,你需要双缓冲。你没有注意到我为你发布的双缓冲教程链接中的3个小程序之间的区别吗?我想做的是让他移动得更快,而每次添加的像素数不超过1px,因为他似乎跳过了像素
你不能一次移动1px,并期望他以给定的速度移动,你必须以这个速度移动他,并使用双缓冲!你提到的跳过像素
就是我们正在讨论的闪烁。我注意到演示中的闪烁,是的,我将查看双b