Java图形 - 重绘图像而不删除另一个图像

时间:2015-05-16 18:57:54

标签: java image swing graphics repaint

我正在使用Graphics g为我的播放器和地图绘制图像。每当玩家移动时,我想要将玩家图像更新到新位置而不更新地图图像。我怎么能这样做?

提前感谢您的回复!

对我的杂乱代码感到抱歉。

   Main:
package Main;
import java.awt.Dimension;

import javax.swing.JFrame;

public class Main {
    public static JFrame frame;

    static int size = 32;
    static int width = size*20;
    static int height = size*17;

    static playerObj p = new playerObj(200,200);

    static tileMap grid = new tileMap();

    public static void main(String[] args) {
        frame = new JFrame("Game");
        frame.getContentPane().setPreferredSize(new Dimension(width-9, height-9));
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.add(new drawGraphics());
        frame.setVisible(true);
    }
}

drawGraphics:
package Main;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class drawGraphics extends JPanel implements Runnable {
    private static final long serialVersionUID = 1L;

    boolean running = true;
    boolean renderMap = true;

    playerObj p = Main.p;
    int size = Main.size;
    static int x = 0;
    static int y = 0;

    Thread thread = new Thread(this);

    public drawGraphics() {
        setFocusable(true);
        addKeyListener(new controls());
        start();
    }

    public void start() {
        thread.start();
    }

    public void paint(Graphics g) {
        Graphics2D d = (Graphics2D) g;
        super.paintComponent(g);

        if (renderMap) {
            map(d);
        }

        player(g);

        repaint();
    }

    public void player(Graphics g) {
        try {
            BufferedImage pImg = ImageIO.read(new File("images/player.png"));
            g.drawImage(pImg, p.getX(), p.getY(), null);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void map(Graphics g) {
        System.out.println("2dfsdf");
        Graphics2D d = (Graphics2D) g;
        for (int i = 0; i < tileMap.map.length; i++) {
            for (int j = 0; j < tileMap.map[i].length; j++) {
                d.setColor(tileMap.map[i][j].getC());
                d.fillRect(tileMap.map[i][j].getX(), tileMap.map[i][j].getY(),
                        Main.size, Main.size);
                if (tileMap.map[i][j].solid()) {
                    d.setColor(Color.BLACK);
                    d.drawRect(tileMap.map[i][j].getX(),
                            tileMap.map[i][j].getY(), Main.size, Main.size);
                }
            }
        }
    }

    public void move() {
        if (controls.up) {
            controls.goUp();
            y--;
            repaint();
        }
        if (controls.down) {
            controls.goDown();
            y++;
            repaint();
        }
        if (controls.left) {
            controls.goLeft();
            x--;
            repaint();
        }
        if (controls.right) {
            controls.goRight();
            x++;
            repaint();
        }
        if (controls.place) {
            repaint();
        }
    }

    public void run() {
        while (running == true) {
            move();
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:4)

不要直接在JFrame中绘制,而是在JFrame中显示的JPanel中绘制。

如果您使用Swing作为GUI库,则将背景绘制为BufferedImage,并在paintComponent方法中首先绘制它。然后在下一个需要的位置绘制你的图像精灵:

@Override  // this is in a JPanel extended class
protected void paintComponent(Graphics g) {
   super.paintComponent(g);
   if (backgroundImg != null) {
      g.drawImage(backgroundImg, 0, 0, null);
   }
   if (spriteImg != null) {
      g.drawImage(spriteImg, spriteX, spriteY, null);
   }
}

您的代码存在一些问题:

  • 不要覆盖paint,然后在其中调用super.paintComponent
  • 而是覆盖paintComponent并在内部调用相同的超级方法。
  • 永远不要在paint或paintComponent中调用repaint()。改为使用Swing Timer。
  • player(...)方法中,每次调用方法时都会重新读取图像,这会使绘画速度变慢。不要这样做,而是一次读取图像,并将其保存到变量中。