试图在Java中创建一个移动的精灵,但有一个余数



我正在尝试在Java中创建一个移动的精灵,我设法做到了,除了每次移动时,都有一个遵循Sprite的余数。我有什么方法可以轻松解决此问题而不会更改我的代码?

我对解决此问题的任何方式完全感到困惑。

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

这是第一个文件:

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

}

和指向精灵的链接:http://www.clker.com/clipart-red-sports-car-top-view.html

所以,您的问题源于使用...

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是不可靠的,我建议使用关键绑定API,该键bi将解决KeyListener遭受

的问题

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

最新更新