我目前正在使"英雄"在日食中移动,方法是在按下一个键时将其重新绘制为更改的 X 坐标。这是有效的,但是运动很粗糙,甚至看起来滞后。我真的很感激任何帮助/建议,代码看起来很长,但它真的很基本。
关卡代码
JFrame window = new JFrame("Level");
Hero hero = new Hero(0, 800);
public Level()
{
this.setFocusable(true);
this.addKeyListener(this);
window.add(this);
window.setSize(1400, 980);
window.setLocation(40,20);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
}
public void paint(Graphics g)
{
try {
Image i = ImageIO.read(getClass().getResource("/Sprites/Background.jpg"));
g.drawImage(i, 0, 0, null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
hero.drawHero(g);
}
@Override
public void keyPressed(KeyEvent kp)
{
if(kp.getKeyCode()==KeyEvent.VK_RIGHT)
{
hero.setxAxis(hero.getxAxis()+5);
this.repaint();
}
if(kp.getKeyCode()==KeyEvent.VK_LEFT)
{
hero.setxAxis(hero.getxAxis()-5);
this.repaint();
}
}
英雄的代码
public class Hero {
int xAxis;
int yAxis;
Image heroImage;
public Hero(int xAxis, int yAxis)
{
super();
this.xAxis = xAxis;
this.yAxis = yAxis;
try {
heroImage = ImageIO.read(getClass().getResource("/Sprites/Pic1.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public int getxAxis() {
return xAxis;
}
public void setxAxis(int xAxis) {
this.xAxis = xAxis;
}
public int getyAxis() {
return yAxis;
}
public void setyAxis(int yAxis) {
this.yAxis = yAxis;
}
public void drawHero(Graphics g) {
g.drawImage(heroImage, xAxis, yAxis, null);
}
}
尝试使用双重或三重缓冲 看看这个!如何在 java 中为游戏提供双重缓冲区?
来自维基的更多信息: 在计算机图形学中,双缓冲是一种用于绘制图形的技术,它不显示(或更少)卡顿、撕裂和其他伪影。
程序很难绘制显示,以使像素不会多次更改。例如,在更新文本页面时,清除整个页面然后绘制字母比以某种方式擦除新旧字母中没有的所有像素要容易得多。但是,此中间图像被用户视为闪烁。此外,计算机显示器不断重绘可见视频页面(每秒约60次),因此即使是完美的更新也可能作为"新"图像和未重绘的"旧"图像之间的水平分隔线暂时可见,称为撕裂。
https://en.wikipedia.org/wiki/Multiple_buffering#Double_buffering_in_computer_graphics
首先查看 AWT 中的绘画和 摆动和执行自定义绘画 有关绘画如何工作以及如何与之交互的更多详细信息。
在 Swing 中绘画使用被动渲染算法,这意味着绘画周期可能随时发生,原因多种多样,许多原因都是在您的控制或不知情的情况下发生的。
这意味着可以随时调用paint
。 喷漆应尽快完成,以免降低应用程序的性能。
为此,您不应该加载资源,做出过于复杂的逻辑决策或从绘制方法中更新状态。
首先将图像加载到其他地方,例如在构造函数中。
绘画是一系列复杂的链式方法调用("油漆链"),很容易被打破,从而导致各种怪异。 作为一般建议,建议覆盖paintComponent
来执行自定义绘画,您还应该调用super.paintComponent
以保持原始的"油漆链">
我还建议使用 键绑定 API 而不是KeyListener
,除了提供更灵活和可重用的解决方案外,它还解决了与焦点相关的KeyListener