如何让角色在java中顺利移动?

时间:2017-05-10 19:43:17

标签: java eclipse graphics

如果按下一个键,我正在日食中通过在改变的X坐标中重新绘制它来使“Hero”在日食中移动。这是有效的,但运动是粗糙的,甚至显得滞后。我真的很感激任何帮助/建议,代码看起来很长,但它是非常基本的。

级别代码

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);
}

}

2 个答案:

答案 0 :(得分:0)

尝试使用双重或三重缓冲 看一下这个! How do you double buffer in java for a game?

来自Wiki的更多信息: 在计算机图形学中,双缓冲是一种绘制图形的技术,它不会显示(或更少)口吃,撕裂和其他伪影。

程序很难绘制显示,因此像素不会改变多次。例如,当更新文本页面时,清除整个页面然后绘制字母要比以某种方式擦除所有不在旧字母和新字母中的像素更容易。但是,该中间图像被用户视为闪烁。此外,计算机显示器不断地重绘可见视频页面(大约每秒60次),因此即使是完美的更新也可以作为“新”图像和未重新绘制的“旧”图像之间的水平分隔线暂时可见,已知撕裂。

https://en.wikipedia.org/wiki/Multiple_buffering#Double_buffering_in_computer_graphics

答案 1 :(得分:0)

首先看看Painting in AWT and SwingPerforming Custom Painting,了解有关绘画如何运作以及如何与之互动的详细信息。

Swing中的绘画使用被动渲染算法,这意味着绘画循环可以在任何时候出于任何原因而无法控制或知识。

这意味着可以随时调用paint。绘画应该尽快完成,以免降低应用程序的性能。

为此,您不应该加载资源,做出过于复杂的逻辑决策或从paint方法中更新状态。

首先将图像加载到其他地方,可能在构造函数中作为示例。

绘画是一系列复杂的链式方法调用("绘画链"),很容易被破坏,这会导致各种各样的怪异。作为一般性建议,建议您覆盖paintComponent来执行自定义绘画,您还应该调用super.paintComponent以维护原始"绘画链"

我还建议使用Key Bindings API而不是KeyListener,除了提供更灵活和可重复使用的解决方案外,它还解决了KeyListener的焦点相关问题