Попытка создать движущийся спрайт в Java, но есть остаточное изображение - PullRequest
1 голос
/ 11 мая 2019

Я пытаюсь создать движущийся спрайт в 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 Ответ

0 голосов
/ 12 мая 2019

Итак, ваша проблема связана с использованием ...

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

По сути, вы недостаточно покрываете «существующую» область, которая используется для его «полного» удаления.

Вы можете просто использовать repaint() вместо этого, и это решит вашу основную проблему. Я бы не стал беспокоиться об этом уровне оптимизации, пока он не станет проблемой.

Если вы хотите использовать его, я бы сделал снимок местоположения медицинской помощи до того, как она была перемещена (то есть, захватил ее текущую позицию х / у), и объединил ее с ее новым местоположением, чтобы вы покрыли обе области. Это, или позвоните 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 привязки клавиш , который решит проблемы, от которых KeyListener страдает

Я бы также рекомендовал использовать ImageIO более ImageIcon в качестве более надежного способа загрузки изображений, см. Чтение / загрузка изображения для получения более подробной информации

...