【问题标题】:Deleting image after moving around in java在java中移动后删除图像
【发布时间】:2021-03-01 13:19:45
【问题描述】:

spaceship 移动后,我无法处理删除图像的问题

首先我有我的 MovingSprite 类来制作 Board:

公共类 MovingSpriteEx 扩展 JFrame {

private static final long serialVersionUID = 1L;

public MovingSpriteEx() {
    initUI();
}

private void initUI() {
    add(new Board());
    
    setTitle("Moving sprite");
    setSize(500,400);
    
    setLocationRelativeTo(null);
    System.out.println("calling");
    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public static void main(String[] args) {

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

}

我的 Board 类正在使用 paintComponent 从 Spaceship 类中进行绘制,如下所示:

公共类 Board 扩展 JPanel 实现 ActionListener {

private static final long serialVersionUID = 1L;
private Timer timer;
private Spaceship ship;
private final int DELAY = 10;
private boolean incrementX = true;
private boolean incrementY=true;

public Board() {
    
    initBoard();
    
}

private void initBoard() {//building the frame
    addKeyListener(new TAdapter());//listens to the KeyAdapter that can read on the keyboards input
    setBackground(Color.black);
    setFocusable(true);
    
    ship = new Spaceship();
    timer = new Timer(DELAY,this);
    timer.start();
    
    
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    
    
        doDrawing(g);
        Toolkit.getDefaultToolkit().sync();
    
    
    
}

private void doDrawing(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    g2d.drawImage(ship.getImage(),ship.getX(), ship.getY(), this);
    
}

@Override
public void actionPerformed(ActionEvent arg0) {
    step();
}

private void step() {
    
    
    ship.move();
    
    
    repaint(ship.getX()-1,ship.getY()-1,ship.getWidth()+2,ship.getHeight()+2);
}


private class TAdapter extends KeyAdapter{
    @Override
    public void keyReleased(KeyEvent e) {
        ship.keyReleased(e);
    }
    
    @Override
    public void keyPressed(KeyEvent e) {
        ship.keyPressed(e);
    }
}

}

和宇宙飞船类:

公共类宇宙飞船{

private int dx;
private int dy;
private int x = 40;
private int y = 60;
private int w;
private int h;
private Image image;

public Spaceship() {

    loadImage();
}

private void loadImage() {
    
    ImageIcon ii =  createImageIcon("../Images/spaceship.jpg","something");
    
    
    image = ii.getImage(); 
    
    
    w = ii.getIconWidth();
    h = ii.getIconHeight();
}

private ImageIcon createImageIcon(String path, String description) {
    java.net.URL imgURL = getClass().getResource(path);
    if (imgURL != null) {
        return new ImageIcon(imgURL, description);
    } else {
        System.err.println("Couldn't find file: " + path);
        return 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 image;
}

public void keyPressed(KeyEvent e) {

    int key = e.getKeyCode();

    if (key == KeyEvent.VK_LEFT) {
        dx = -2;
    }

    if (key == KeyEvent.VK_RIGHT) {
        dx = 2;
        
    }

    if (key == KeyEvent.VK_UP) {
        dy = -2;
    }

    if (key == KeyEvent.VK_DOWN) {
        dy = 2;
    }
}

public void keyReleased(KeyEvent e) {
    
    int key = e.getKeyCode();

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

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

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

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

public static void main(String [] args) {
    
    
}

}

希望有人能看到我做错了什么

拉斯穆斯

【问题讨论】:

  • 请对代码和代码 sn-ps、HTML/XML 等结构化文档或输入/输出使用代码格式。为此,请选择文本并单击消息发布/编辑表单顶部的{} 按钮。您可以随时edit您的问题。

标签: java swing jpanel awt paintcomponent


【解决方案1】:

您的代码在每一帧都将船舶图像绘制到您的板 (JPanel),但不会清除之前绘制的帧的图像,JPanel 不会为您执行此操作。保留调用 drawImage 时使用的坐标的副本,然后下次清除该区域,对于纯背景,您可以使用 fillRect。

例如,当您在纯黑色背景上绘图时,您可以将以下内容添加到您的 Spaceship 类中并调用它,而不是在 doDrawing 中调用 drawImage。

private java.awt.Rectangle dirtyArea;
public void draw(java.awt.Graphics2D g2d, java.awt.image.ImageObserver observer) {
    if (dirtyArea != null) {
        g2d.setColor(java.awt.Color.BLACK);
        g2d.fillRect(dirtyArea.x, dirtyArea.y, dirtyArea.width, dirtyArea.height);
    }
    int shipX = getX();
    int shipY = getY();
    Image shipImage = getImage();
    g2d.drawImage(shipImage, shipX, shipY, observer);

    if (dirtyArea == null || dirtyArea.width == -1) {  // -1 check is there just in case the image wasn't loaded when this code ran before
        dirtyArea = new java.awt.Rectangle();
        dirtyArea.setSize(shipImage.getWidth(null), shipImage.getHeight(null)); // don't need observer as we're checking for -1 next time round
    }
    dirtyArea.setLocation(shipX, shipY);
}

【讨论】:

  • 只是补充一点,一旦你在屏幕上同时有多个精灵,你会想要在绘制第一个精灵之前清除所有的脏区域(所以 fillRects 不会模糊任何精灵),上面的方法只是最简单的示例,而您只绘制一艘船,如果您继续使用这种方法,您可能会向 Spaceship 添加一个新方法来清除脏区域( != null 块内的部分),然后 doDrawing 将为所有精灵调用清除脏区方法,然后为所有精灵调用 draw 方法。
  • "Just to add,.." 最好用edit 来表示答案。
猜你喜欢
  • 2021-03-07
  • 2018-09-05
  • 1970-01-01
  • 2022-06-15
  • 2014-01-24
  • 1970-01-01
  • 1970-01-01
  • 2020-02-17
  • 1970-01-01
相关资源
最近更新 更多