1

シンプルな 2D ゲーム、倉庫番 ( http://www.game-sokoban.com/ ) を作成しました。画面に 2 次元フィールドがあります。別の JPanel ボードが担当します。

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.io.IOException;
import java.util.Properties;

public class Board extends JPanel {

    private static final String CONFIG_FILE_NAME = "ImageConfig.txt";

    /** length px of a square cell */
    private static final int SPACE = 20;

    private Properties properties;

    private Map<Status, Image> Images = null;

    private Status[][] cells = null;

    private BufferedImage canvas = null;

    private Graphics2D g2d = null;

    public Board() {

        Properties properties = new Properties();
        try {
            //load a properties file
            properties.load(ClassLoader.getSystemResourceAsStream(CONFIG_FILE_NAME));
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }

        Images = new HashMap<Status, Image>();
        for (String key : properties.stringPropertyNames()) {
            switch (key) {
                case "AREA" : {
                    Images.put(Status.AREA, null);
                    break;
                }
                case "BAGGAGE" : {
                    Images.put(Status.BAGGAGE, null);
                    break;
                }
                case "FREE" : {
                    Images.put(Status.FREE, null);
                    break;
                }
                case "SOKO" : {
                    Images.put(Status.SOKO, null);
                    break;
                }
                case "WALL" : {
                    Images.put(Status.WALL, null);
                    break;
                }
            }
        }
        this.properties = properties;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;
        g2d.drawImage(this.canvas, cells.length, cells[0].length, this);
    }

    public void setSize_(int height, int width) {
        canvas = new BufferedImage(width * SPACE, height * SPACE, BufferedImage.TYPE_INT_RGB);
        g2d = canvas.createGraphics();
        setPreferredSize(new Dimension(width * SPACE, height * SPACE));
        cells = new Status[height][width];
    }

    public void drawCell(int i, int j, Status status) {
        cells[i][j] = status;
        try {
            g2d.drawImage(getImage(cells[i][j]), j * SPACE, i * SPACE, this);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        repaint();
    }
}

各移動で、フィールド上のプレーヤーが更新されますが、2 つまたは 3 つのセルのみが更新されます。すべてのフィールドを再描画するのではなく、g2d で drawImage (...) の一部の呼び出しのみを呼び出し、その変更が画面に表示されるようにしたいと考えています。それを実装するには(paintComponent()なしで)?

4

2 に答える 2

3

クリッピングを利用して、ペイント プロセスを高速化できます。setClip()メソッドを使用してクリップを設定できます。repaint()また、更新が必要な領域のみを定義する引数を取るのオーバーロードされたバージョンもあります。を呼び出すたびに、Swing がクリップを設定しますrepaint(x, y, width,height)。次に、内部paintComponent()でクリップを尊重することを選択できます。Graphicsメソッドで取得できますgetClipBounds()。そして必要な部分だけを塗ります。

詳細と例については、AWT と Swing でのペイントを参照してください。カスタム ペイントの実行チュートリアルも参照してください。クリッピングされたペイントを示す例があります。

于 2013-04-16T18:14:02.823 に答える
1

次のようなものを使用します。

Rectangle rect = new Rectangle(i * SPACE, j * SPACE, SPACE, SPACE);
repaint(50L, rect);

ミリ秒単位の遅延 50 は、再描画プロセスに適しています。i,j または j,i がわからない。

于 2013-04-16T17:02:44.323 に答える