2013-10-06 24 views
0

我在製作基於瓷磚的遊戲,我使用perlin的噪音生成隨機地圖。當我的地圖是100 * 100的地圖時,效果很好,但是當我的地圖是1000 * 1000的地圖時,我遇到了性能問題,我通過檢查我的地圖是否在相機視圖中而不是繪製它們來解決其中的大部分問題,但它仍然存在問題。下面是我的一些代碼:檢查瓷磚是否在相機視圖時的性能問題java swing

加載

void loadMap(int size) 
{ 
    blocks.clear(); 
    float[][] seed1 = Perlin.GenerateWhiteNoise(size, size); 
    float[][] seed = Perlin.GenerateSmoothNoise(seed1, 3); 
    for (int i = 0; i < seed.length; i++) 
    { 
     for (int j = 0; j < seed[i].length; j++) 
     { 
      if(seed[i][j] < 0.5) 
      { 
       blocks.add(new Block(i * Block.blockSize, j * Block.blockSize, eBlockType.WATER)); 
      } 

      else if(seed[i][j] > 0.8) 
      { 
       blocks.add(new Block(i * Block.blockSize, j * Block.blockSize, eBlockType.GRASS)); 
      } 

      else 
      { 
       blocks.add(new Block(i * Block.blockSize, j * Block.blockSize, eBlockType.SAND)); 
      } 
     } 
    } 
} 

繪圖

public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 
    Graphics2D g2 = (Graphics2D)g; 
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
    cameraX = -player.getX() + getWidth()/2; 
    cameraY = -player.getY() + getHeight()/2; 
    g.translate(cameraX, cameraY); 
    for(Block block : blocks) 
    { 
     //System.out.println(block.getX() + " " + cameraX); 
     Rectangle cameraView = new Rectangle(-(cameraX+cameraPadding), -(cameraY+cameraPadding), this.getWidth()+cameraPadding , this.getHeight()+cameraPadding); 
     if(cameraView.contains(block.getX(), block.getY())) 
     { 
      block.draw(g2); 
     } 

     else if(block.getX() > cameraView.getMaxX() && block.getY() > cameraView.getMaxY()) 
     { 
      break; 
     } 
    } 

    player.draw(g2); 
} 

塊類

package com.ymail.sanchixx.game; 

import java.awt.Graphics; 
import java.awt.Rectangle; 

public class Block 
{ 

    enum eBlockType 
    { 
     NULL(-1), STONE(0), STONEBRICK(1), // these are collision 
     COLLISION_BLOCKS(2), // PlaceHolder 
     GRASS(3), PLANK(4), WATER(5), SAND(6); // these are non-collision 

     private int code; 

     eBlockType(int c) 
     { 
      code = c; 
     } 

     public int getCode() 
     { 
      return code; 
     } 
    }; 

    eBlockType m_type = eBlockType.NULL; 
    int m_x; 
    int m_y; 
    static int blockSize = 16; 

    Block(int x, int y, eBlockType type) 
    { 
     m_x = x; 
     m_y = y; 
     m_type = type; 
    } 

    boolean isNonCollisionBlock() 
    { 
     if(m_type.getCode() > eBlockType.COLLISION_BLOCKS.getCode()) 
     { 
      return true; 
     } 

     return false; 
    } 

    static boolean collisionDown(Entity e, int v) 
    { 
     Rectangle player = new Rectangle(e.getX(), e.getY() + v, e.getWidth(), e.getHeight()); 
     for(Block i : Game.blocks) 
     { 
      if(!i.isNonCollisionBlock()) 
      { 
       int blockWidth = blockSize; 
       int blockHeight = blockSize; 
       Rectangle block = new Rectangle(i.getX(), i.getY(), blockWidth, blockHeight); 
       if (player.intersects(block)) 
       { 
        e.setY(e.getY() - (e.getY() - (i.getY() - e.getHeight()))); 
        return true; 
       } 
      } 
     } 
     return false; 
    } 

    static boolean collisionUp(Entity e, int v) 
    { 
     Rectangle player = new Rectangle(e.getX(), e.getY() -v, e.getWidth(), e.getHeight()); 
     for(Block i : Game.blocks) 
     { 
      if(!i.isNonCollisionBlock()) 
      { 
       int blockWidth = blockSize; 
       int blockHeight = blockSize; 
       Rectangle block = new Rectangle(i.getX(), i.getY(), blockWidth, blockHeight); 
       if (player.intersects(block)) 
       { 
        e.setY(e.getY() - (e.getY() - (i.getY())) + blockHeight); 
        return true; 
       } 
      } 
     } 
     return false; 
    } 

    static boolean collisionRight(Entity e, int v) 
    { 
     Rectangle player = new Rectangle(e.getX() + v, e.getY(), e.getWidth(), e.getHeight()); 
     for(Block i : Game.blocks) 
     { 
      if(!i.isNonCollisionBlock()) 
      { 
       int blockWidth = blockSize; 
       int blockHeight = blockSize; 
       Rectangle block = new Rectangle(i.getX(), i.getY(), blockWidth, blockHeight); 
       if (player.intersects(block)) 
       { 
        e.setX(e.getX() - (e.getX() - (i.getX() - e.getWidth()))); 
        return true; 
       } 
      } 
     } 
     return false; 
    } 

    static boolean collisionLeft(Entity e, int v) 
    { 
     Rectangle player = new Rectangle(e.getX() - v, e.getY(), e.getWidth(), e.getHeight()); 
     for(Block i : Game.blocks) 
     { 
      if(!i.isNonCollisionBlock()) 
      { 
       int blockWidth = blockSize; 
       int blockHeight = blockSize; 
       Rectangle block = new Rectangle(i.getX(), i.getY(), blockWidth, blockHeight); 
       if (player.intersects(block)) 
       { 
        e.setX(e.getX() - (e.getX() - (i.getX())) + e.getWidth()); 
        return true; 
       } 
      } 
     } 
     return false; 
    } 

    static Boolean swimmingInBlock(Entity e, eBlockType type) 
    { 
     Rectangle player = new Rectangle(e.getX(), e.getY() + e.getHeight()/2, e.getWidth(), e.getHeight()/2); 
     for(Block i : Game.blocks) 
     { 
      if(i.isNonCollisionBlock()) 
      { 
       int blockWidth = blockSize; 
       int blockHeight = blockSize; 
       Rectangle block = new Rectangle(i.getX(), i.getY(), blockWidth, blockHeight); 
       if (player.intersects(block)) 
       { 
        if(i.getType() != type) 
        { 
         return false; 
        } 
       } 
      } 
     } 

     return true; 
    } 

    eBlockType getType() 
    { 
     return m_type; 
    } 

    int getX() 
    { 
     return m_x; 
    } 

    int getY() 
    { 
     return m_y; 
    } 

    void draw(Graphics g) 
    { 
     switch(m_type) 
     { 
     case GRASS: 
      g.drawImage(Game.blockImg[0], m_x, m_y, null); 
      break; 
     case WATER: 
      g.drawImage(Game.blockImg[4], m_x, m_y, null); 
      break; 
     case SAND: 
      g.drawImage(Game.blockImg[6], m_x, m_y, null); 
      break; 
     case STONE: 
      g.drawImage(Game.blockImg[1], m_x, m_y, null); 
      break; 

     default: 
      break; 
     } 
    } 
} 

謝謝

回答

1

你還在訪問ñ瓷磚測試的可見性,即使您選擇只渲染某些瓷磚。相反,請使用flyweight pattern來僅渲染可見瓦片,其中可見度可以僅由面板/瓦片幾何體確定。概述爲here的方法用於優化JTable