Graphics2D和Jpanel查询:更简单的方法?

时间:2014-07-30 01:43:26

标签: java swing jpanel paintcomponent graphics2d

是否有一种更简单的方法可以对我的程序进行编码,这样我就可以将基于图块的地图绘制到某个面板上(某种类型),这样每次调整窗口大小时都会重新绘制地图(可调整大小)?我意识到这对于调试和测试我的mapDrawing函数非常有用,但是,我也不认为我理想地做到了,或者甚至以一种聪明的方式做到了。

我的代码如下..如果由于某种原因需要我的子类,我也可以编辑它们。

import java.awt.*;
import javax.swing.*;


public class AhnkorMyst extends JPanel {  // main game class

static final int screenWidth = 760;
static final int screenHeight = 760;

    public void paintComponent(Graphics g) {
        super.paintComponent(g);    // paint background
        setBackground(Color.BLACK);

        Graphics2D g2d = (Graphics2D) g;
        Map newMap = new Map(g2d, screenWidth, screenHeight);
        newMap.generateBaseMap();
        newMap.populateSurroundings();
        newMap.quadSmoothingIteration ();

        int i, j;
        for (j = 0; j < (newMap.mapHeight / 20); j++) {
            for (i = 0; i < (newMap.mapWidth / 20); i++) {
                newMap.mainMap[i][j].paint();
            }
        }

    }

    public static void main (String[] args) {
        AhnkorMyst game = new AhnkorMyst();
        JFrame frame = new JFrame("Ahnkor Myst");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(game);
        frame.setSize(screenWidth + 10, screenHeight + 30);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.setResizable(false);

    }
}

编辑**我的地图是用generateBaseMap()函数随机生成的。

2 个答案:

答案 0 :(得分:4)

这是概念的“非常”基本的例子。基本上,这会重新构建BufferedImage,它代表每次JPanel无效时地图的基本“视图”。

你应该注意,我每次构建时都会简单地随机化地图,大概你会使用某种定义地图本身的虚拟结构,而不是用它来构建地图......

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
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.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestTiles {

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

    public TestTiles() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TileMap());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TileMap extends JPanel {

        private int tileColumns = 8;
        private int tileRows = 8;

        private BufferedImage tileSheet;
        private BufferedImage tileMap;

        public TileMap() {

            try {
                tileSheet = ImageIO.read(getClass().getResource("/TileSet.png"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

        }

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

        @Override
        public void invalidate() {
            tileMap = null;
            super.invalidate(); 
        }



        protected void buildMap() {

            tileMap = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = tileMap.createGraphics();
            int tileWidth = tileSheet.getWidth() / tileColumns;
            int tileHeight = tileSheet.getHeight() / tileRows;
            Random random = new Random();
            for (int x = 0; x < getWidth(); x += tileWidth) {
                for (int y = 0; y < getHeight(); y += tileHeight) {
                    int xCell = random.nextInt(tileColumns - 1) * tileWidth;
                    int yCell = random.nextInt(tileRows - 1) * tileHeight;
                    BufferedImage tile = tileSheet.getSubimage(xCell, yCell, tileWidth, tileHeight);
                    g2d.drawImage(tile, x, y, this);
                }
            }
            g2d.dispose();

        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (tileSheet != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                if (tileMap == null) {
                    buildMap();
                }
                g2d.drawImage(tileMap, 0, 0, this);
                g2d.dispose();
            }
        }
    }

}

您可以进一步采用此概念并将整个世界预生成为单个BufferedImage,并使用getSubImage来抓取您要显示的较小部分。这开始形成滚动的基本概念,因为您可以在世界中保持虚拟位置并计算需要显示地图的哪个部分来表示它......

答案 1 :(得分:4)

避免在paintComponent()的实施中进行冗长的计算和实例化。您可以使用此AnimationTest中显示的方法了解目标平台上的可用渲染预算。相反,尽可能预先计算。在此图块example中,地图完全是静态的,渲染由paintIcon()处理。检查了一个相关示例here

image