尝试在Java中创建移动精灵,但是有残像

时间:2019-05-11 20:57:34

标签: java animation sprite

我试图在Java中创建一个移动的精灵,我设法做到了,除了每次移动它时,都有一个跟随该精灵的残像。有什么方法可以轻松地解决此问题,而无需彻底更改代码?

我完全无法解决此问题。

要获得完整的上下文,我必须发布所有三个文件。

这是第一个文件:

package gameproject;

import java.awt.Image;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;

public class CarMovement {

private int dx;
private int dy;
private int x = 635;
private int y = 550;
private int w;
private int h;
private Image moveimage;

public CarMovement() {

    loadImage();
}

private void loadImage() {

    ImageIcon q = new ImageIcon("racecar.png");
    moveimage = q.getImage(); 

    w = moveimage.getWidth(null);
    h = moveimage.getHeight(null);
}

public void move() {

    x += dx;
    y += dy;
}

public int getX() {

    return x;
}

public int getY() {

    return y;
}

public int getWidth() {

    return w;
}

public int getHeight() {

    return h;
}    

public Image getImage() {

    return moveimage;
}

public void keyPressed(KeyEvent e) {

    int key = e.getKeyCode();

    if (key == KeyEvent.VK_A) {
        dx = -10;
    }

    if (key == KeyEvent.VK_D) {
        dx = 10;
    }

    if (key == KeyEvent.VK_W) {
        dy = -10;
    }

    if (key == KeyEvent.VK_S) {
        dy = 10;
    }
}

public void keyReleased(KeyEvent e) {

    int key = e.getKeyCode();

    if (key == KeyEvent.VK_A) {
        dx = 0;
    }

    if (key == KeyEvent.VK_D) {
        dx = 0;
    }

    if (key == KeyEvent.VK_W) {
        dy = 0;
    }

    if (key == KeyEvent.VK_S) {
        dy = 0;
    }
}
}

第二个:

 package gameproject;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
import javax.swing.Timer;

public class CarMovement2 extends JPanel implements ActionListener {

private Timer timer;
private CarMovement racecar;
private final int DELAY = 10;

public CarMovement2() {

    initBoard();
}

private void initBoard() {

    addKeyListener(new TAdapter());
    setBackground(Color.black);
setFocusable(true);

    racecar = new CarMovement();

    timer = new Timer(DELAY, this);
    timer.start();
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(new Color(0, 204, 0));
    g.fillRect(0, 0, 400, 1100);
    g.fillRect(1525, 0, 400, 1100);
    g.setColor(new Color(102, 102, 102));
    g.fillRect(400, 0, 1125, 1100);
    g.setColor(new Color(255, 255, 255));
    g.fillRect(940, 25, 25, 100);
    g.fillRect(940, 325, 25, 100);
    g.fillRect(940, 475, 25, 100);
    g.fillRect(940, 625, 25, 100);
    g.fillRect(940, 775, 25, 100);
    g.fillRect(940, 925, 25, 100);
    g.setColor(new Color(255, 255, 255));
    g.fillRect(400, 175, 1125, 100);
    g.setColor(new Color(0, 0, 0));
    g.fillRect(400, 225, 50, 50);
    g.fillRect(450, 175, 50, 50);
    g.fillRect(500, 225, 50, 50);
    g.fillRect(550, 175, 50, 50);
    g.fillRect(600, 225, 50, 50);
    g.fillRect(650, 175, 50, 50);
    g.fillRect(700, 225, 50, 50);
    g.fillRect(750, 175, 50, 50);
    g.fillRect(800, 225, 50, 50);
    g.fillRect(850, 175, 50, 50);
    g.fillRect(900, 225, 50, 50);
    g.fillRect(950, 175, 50, 50);
    g.fillRect(1000, 225, 50, 50);
    g.fillRect(1050, 175, 50, 50);
    g.fillRect(1100, 225, 50, 50);
    g.fillRect(1150, 175, 50, 50);
    g.fillRect(1200, 225, 50, 50);
    g.fillRect(1250, 175, 50, 50);
    g.fillRect(1300, 225, 50, 50);
    g.fillRect(1350, 175, 50, 50);
    g.fillRect(1400, 225, 50, 50);
    g.fillRect(1450, 175, 50, 50);
    g.fillRect(1500, 225, 25, 50);
    g.setColor(new Color(255, 255, 255));
    g.fillRect(380, 0, 20, 1100);
    g.fillRect(1525, 0, 20, 1100);
    doDrawing(g);

    Toolkit.getDefaultToolkit().sync();
}

private void doDrawing(Graphics g) {

    Graphics2D g2d = (Graphics2D) g;

    g2d.drawImage(racecar.getImage(), racecar.getX(), 
        racecar.getY(), this);
}

@Override
public void actionPerformed(ActionEvent e) {

    step();
}

private void step() {

    racecar.move();

    repaint(racecar.getX()-1, racecar.getY()-1, 
            racecar.getWidth()+2, racecar.getHeight()+2);
}    

private class TAdapter extends KeyAdapter {

    @Override
    public void keyReleased(KeyEvent e) {
        racecar.keyReleased(e);
    }

    @Override
    public void keyPressed(KeyEvent e) {
        racecar.keyPressed(e);
    }
}
}

第三个:

package gameproject;


import java.awt.EventQueue;
import javax.swing.JFrame;
public final class CarMovement3 extends JFrame {

 public CarMovement3() {

    InitUI();
}

private void InitUI() {

    add(new CarMovement2());

    setTitle("Top Speed Triumph");
    setSize(1900, 1100);
    setResizable(false);

    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public static void main(String[] args) {

    EventQueue.invokeLater(() -> {
        CarMovement3 ex = new CarMovement3();
        ex.setVisible(true);
    });
}


}

以及指向sprite的链接: http://www.clker.com/clipart-red-sports-car-top-view.html

1 个答案:

答案 0 :(得分:0)

因此,您的问题源于使用...

repaint(racecar.getX() - 1, racecar.getY() - 1,
        racecar.getWidth() + 2, racecar.getHeight() + 2);

基本上,您没有涵盖用来完全“删除”该区域的“现有”区域。

您可以简单地使用repaint()来解决基本问题。在真正成为问题之前,我会避免担心这种优化级别。

如果要使用它,那么我将在照护移动之前对其进行快照(即,抓住它的当前x / y位置),然后将其与新位置合并,以便覆盖两个区域。或两次致电repaint(x, y, width, height),一次是在旧职位上,一次是在新职位上

private void step() {
    Rectangle old = new Rectangle(racecar.getX(), racecar.getY(), racecar.getWidth(), racecar.getHeight());

    racecar.move();

    Rectangle now = new Rectangle(racecar.getX(), racecar.getY(), racecar.getWidth(), racecar.getHeight());

    repaint(old);
    repaint(now);
}

此外,您会发现KeyListener不可靠,我建议您使用the key bindings API来解决KeyListener所面临的问题

我还建议在ImageIO上使用ImageIcon作为加载图像的更可靠方法,有关更多详细信息,请参见Reading/Loading an Image