有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

试图用java创建移动精灵的动画,但有后像

我试图在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);
    });
}


}

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


共 (1) 个答案

  1. # 1 楼答案

    所以,你的问题源于使用

    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