2012-03-25 8 views
0

私は巨大なグリッドを生成する新しいゲームを作っています(1000x1000と言うことができます)。プレイヤーは真ん中でスタートし、「ポイント」を探し回って移動します。プレーヤーはウィンドウ内の大きなグリッドの一部(15x15)しか見ることができません。今私はちょうど私が作成した汚れブロックのbufferedimageをペイントする矩形の巨大な配列を持っています。質問:私はこれらのすべての画像を格納するために使用すべきより良い変数タイプがありますか?Java Swing Huge Grid

これは、(はRECT、および最初に生成された画像を保持している)のような私のダートクラスが見えるものです:

public class Dirt extends Spot{ 
    private int index; 

    public Dirt(int temp){ 
     index = temp; 
    } 

    public Image getImageIndex(){return index;} 
} 

そして、ここでは、離れて、すべての汚れを描く私の取締役クラスのです

public class Board extends JPanel{ 
    private final int BLOCK_SIZE;         //Holds the size of each block 
    private final int SIZE;          //Holds the size of the board 
    private DirtImages[] imgs_Dirt = new DirtImages[20]; //Holds 20 random dirt images - generated at begtinning 

    private Spot[][] spots; 

    public Board(int size, int blocksize){ 
     SIZE = size; 
     BLOCK_SIZE = blocksize; 
     //Board 
     setSize(SIZE,SIZE); 
     //Timer Label 
     add(JTimerLabel.getInstance()); 

     //Create 20 random Images of dirt to use for the rest of dirts 
     for(int i = 0; i < 20; i++){ 
      imgs_Dirt[i] = new DirtImages(new Rectangle(0,0,BLOCK_SIZE,BLOCK_SIZE)); 
      add(imgs_Dirt[i]); 
     } 

     //Create Dirt 
     spots = new Dirt[500][500]; 
     java.util.Random randomGenerator = new java.util.Random(); 
     for(int i = 0; i < spots.length; i++){ 
      for(int j = 0; j < spots.length; j++) 
       spots[i][j] = new Dirt(randomGenerator.nextInt(20)); 
     } 
    } 

    public void paint(Graphics g){ 
     super.paint(g); 
     Graphics2D g2d = (Graphics2D)g; 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

     //Draw Grid #First 
     for(int i = 0; i < spots.length; i++){ 
      for(int j = 0; j < spots.length; j++) 
       if(spots[i][j] != null) 
        g2d.drawImage(imgs_Dirt[((Dirt)spots[i][j]).getImageIndex()].getImage(), BLOCK_SIZE*i,BLOCK_SIZE*j,BLOCK_SIZE,BLOCK_SIZE, null); 
     } 

     Toolkit.getDefaultToolkit().sync(); 
     g2d.dispose(); 
     requestFocus(); 
    } 

私は汚れ(塗装されたとき)がタイル張りのように見えないがランダムであるように、20の汚れ画像を作成する。だから、私の汚れの配列では、各汚れはランダムな画像を指しています。

その他の質問:私は巨大なグリッドを作成したので、どのようにしてプレイヤーが中心から始まり、周囲のセルを描くのですか。現在、私は配列の左上隅にある配列の先頭から始めます。描画する必要があるかどうかの各汚れに対してブール値のフラグを作成する必要がありますか?

+2

で決定しています。 [paint(Graphics)]ではなく 'JPanel'を' paintComponent(Graphics) 'に置き換えます –

+0

http://codereview.stackexchange.com/ –

+0

また、JLabelのグリッドを作成し、ImageIconを作成することもできますJLabelsの間で共有されます。 –

答えて

3

埃が1,000,000枚あり、画像が20枚ある場合は、それぞれの汚れに画像を保存するのは無駄です。代わりにインデックスを使用できます。

あなたはあなたの全体のグリッドを描くように見える(0-1000,0-1000を):だからあなたが更新され、質問のために

imgsDirt[((Dirt)spots[i][j]).getImageIndex()] 

を引く代わりに

((Dirt)spots[i][j]).getImage() 

を描く、描画します。あなたが本当に望んでいるのは、15x15の生存可能な領域をペイントすることです。だからではなく、

//Draw Grid #First 
    for(int i = 0; i < spots.length; i++){ 
     for(int j = 0; j < spots.length; j++) 

のそれは

//Draw Grid #First 
    for(int i = player.xpos-7; i < player.xpos+7; i++){ 
     for(int j = player.ypos - 7; j < player.ypos+7; j++) 

あなたは、それはまだあなたのウィンドウの左上に描画を開始しますことを確認するために、drawImageメソッドで適切なシフトが必要になるだろう。

+0

に加えて、なぜ各インスタンスは長方形を格納する必要がありますか?彼らはタイルです...すべて同じサイズ – Ozzy

+0

恐ろしい!それは私が逃した本当に良い点です。正常に動作します。 – mbreen

+0

今度は、私がrepaintメソッドを呼び出すたびに、汚れイメージがパターンを変更する理由を理解する必要があります。 – mbreen

1

は一緒にこれらすべてを入れ、可視JComponentsは、それが同じ汚れブロックである場合は、1つのインスタンスを保持し、必要な場所&としてペイントJViewPort

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Random; 
import javax.swing.*; 

public class TilePainter extends JPanel implements Scrollable { 

    private static final long serialVersionUID = 1L; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       JFrame frame = new JFrame("Tiles"); 
       frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       frame.getContentPane().add(new JScrollPane(new TilePainter())); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 
    private final int TILE_SIZE = 50; 
    private final int TILE_COUNT = 100; 
    private final int visibleTiles = 10; 
    private final boolean[][] loaded; 
    private final boolean[][] loading; 
    private final Random random; 

    public TilePainter() { 
     setPreferredSize(new Dimension(TILE_SIZE * TILE_COUNT, TILE_SIZE * TILE_COUNT)); 
     loaded = new boolean[TILE_COUNT][TILE_COUNT]; 
     loading = new boolean[TILE_COUNT][TILE_COUNT]; 
     random = new Random(); 
    } 

    public boolean getTile(final int x, final int y) { 
     boolean canPaint = loaded[x][y]; 
     if (!canPaint && !loading[x][y]) { 
      loading[x][y] = true; 
      Timer timer = new Timer(random.nextInt(500), 
        new ActionListener() { 

         @Override 
         public void actionPerformed(ActionEvent e) { 
          loaded[x][y] = true; 
          repaint(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE); 
         } 
        }); 
      timer.setRepeats(false); 
      timer.start(); 
     } 
     return canPaint; 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Rectangle clip = g.getClipBounds(); 
     int startX = clip.x - (clip.x % TILE_SIZE); 
     int startY = clip.y - (clip.y % TILE_SIZE); 
     for (int x = startX; x < clip.x + clip.width; x += TILE_SIZE) { 
      for (int y = startY; y < clip.y + clip.height; y += TILE_SIZE) { 
       if (getTile(x/TILE_SIZE, y/TILE_SIZE)) { 
        g.setColor(Color.GREEN); 
       } else { 
        g.setColor(Color.RED); 
       } 
       g.fillRect(x, y, TILE_SIZE - 1, TILE_SIZE - 1); 
      } 
     } 
    } 

    @Override 
    public Dimension getPreferredScrollableViewportSize() { 
     return new Dimension(visibleTiles * TILE_SIZE, visibleTiles * TILE_SIZE); 
    } 

    @Override 
    public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { 
     return TILE_SIZE * Math.max(1, visibleTiles - 1); 
    } 

    @Override 
    public boolean getScrollableTracksViewportHeight() { 
     return false; 
    } 

    @Override 
    public boolean getScrollableTracksViewportWidth() { 
     return false; 
    } 

    @Override 
    public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { 
     return TILE_SIZE; 
    } 
}