【问题标题】:How to stop one drawImage from overlapping another? - Java如何阻止一个drawImage重叠另一个? - 爪哇
【发布时间】:2014-01-31 09:26:26
【问题描述】:

我正在尝试使用一个 drawImage 的 2D 数组为 RPG 制作平铺背景。但是由于某种原因,Java自动将背景与播放器重叠,我尝试在背景之前绘制播放器,但没有区别,代码:

地图代码:

Tiles[][] t;

public Map()
{
    t = new Tiles[640 / 32][480 / 32];

    for (int x = 0; x < 640 / 32; x++)
    {
        for (int y = 0; y < 480 / 32; y++)
        {
            t[x][y] = new Tiles(x, y, 32, 32, "./res/grass.png");
        }
    }
}

public void paint(Graphics g)
{
    super.paint(g);

    for (int x = 0; x < 640 / 32; x++)
    {
        for (int y = 0; y < 480 / 32; y++)
        {
            t[x][y].paint(g);
        }
    }

    this.repaint();
}

绘制代码(在扩展JPanel的其他类中):

public void paint(Graphics g)
{
    super.paint(g);

    p.paint(g);
    m.paint(g);

    this.repaint();
}

注意:上面代码所在的类扩展了 JPanel,所以我创建了另一个名为 Window 的类,它将它添加到 JFrame,然后在静态 void main 中,我完成了所有初始化。

【问题讨论】:

  • this.repaint()paint 方法中看起来很可疑 - 它可能会再次递归地绘制组件。如果这不是问题,请记住您必须在背景之后绘制玩家。顺便说一句:你不应该在 JComponents 中覆盖paint,而是应该覆盖paintComponent。
  • 1) 为了尽快获得更好的帮助,请发帖 MCVE。 2) 例如,获取图像的一种方法是热链接到this answer 中看到的图像。
  • 将图形视为画布。你在方法中最后绘制的任何内容都将在之前以相同方法绘制的任何内容之上。所以你可能想最后画你的球员。并且一定要遵循 Njol 的建议:重写paintComponent 而不是paint,并且永远不要从任何绘画方法中调用repaint。

标签: java swing graphics 2d


【解决方案1】:

如果没有完整的代码,就很难判断你在哪里做错了。不过我可以指出一些事情

  • 看起来你 Map 也是 JPanel,因为你打电话给 super.paint。您不需要将Map 设为JPanel,只需将其设为带有drawTiles 方法的常规模型类,您可以将Graphics 上下文传递给该方法。

  • 不要从组件类中显式调用paint 方法。

  • 不要从paint方法内部调用repaint()

  • 覆盖paintComponent 而不是JPanel


这是我提出的一个示例,在修复上述问题的同时使用了您的一些代码原则

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class PaintTiles extends JPanel {

    BufferedImage playerImg;
    BufferedImage tileImg;
    Map map;
    Player player;
    int playerX, playerY;

    public PaintTiles() throws MalformedURLException, IOException {
        playerImg = ImageIO.read(new URL("http://th05.deviantart.net/fs71/PRE/f/2013/055/0/d/super_mario_by_tachin-d5w51ob.png"));
        tileImg = ImageIO.read(new URL("https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcTc0ep9G8CyvdJSpBbn8AFdZDlimas7Hcc6jqiVVxBe4nfWJYQy7A"));

        map = new Map(tileImg);

        playerX = 250;
        playerY = 250;
        player = new Player(playerX, playerY, 100, 100, playerImg);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (map != null && player != null) {
            map.paintTiles(g);
            player.paintPlayer(g);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(640, 480);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Test");
                try {
                    frame.add(new PaintTiles());
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(PaintTiles.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }
}

class Map {

    Image img;
    Tile[][] tiles;

    int tileSize = 32;
    private static final int SCREEN_W = 640;
    private static final int SCREEN_H = 480;
    int xInc = SCREEN_W / tileSize;
    int yInc = SCREEN_H / tileSize;


    public Map(Image img) {
        this.img = img;
        tiles = new Tile[xInc][yInc];

        for (int x = 0; x < xInc; x++) {
            for (int y = 0; y < yInc; y++) {
                tiles[x][y] = new Tile(x * tileSize, y * tileSize, tileSize, tileSize, img);
            }
        }
    }

    public void paintTiles(Graphics g) {
        if (tiles != null) {
            for (Tile[] tile : tiles) {
                for (Tile t : tile) {
                    t.drawTile(g);
                }
            }
        }
    }
}

class Player {

    int x, y, w, h;
    Image player;

    public Player(int x, int y, int w, int h, Image player) {
        this.x = x;
        this.y = y;
        this.h = h;
        this.w = w;
        this.player = player;
    }

    public void paintPlayer(Graphics g) {
        g.drawImage(player, x, y, w, h, null);
    }
}

class Tile {

    int x, y, w, h;
    Image img;

    public Tile(int x, int y, int w, int h, Image img) {
        this.x = x;
        this.y = y;
        this.h = h;
        this.w = w;
        this.img = img;
    }

    public void drawTile(Graphics g) {
        g.drawImage(img, x, y, w, h, null);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-12
    • 2012-11-19
    • 2015-07-17
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多