2015-04-07 65 views
0

我對Java很新鮮,但我想創建一個探索型遊戲。我研究了最近2周,並能夠實現鑽石平方算法的一些漂亮的地形。但是現在我在嘗試弄清如何移動地圖以及如何繼續隨機生成時遇到了困難。這是迄今爲止我所擁有的。Java - 移動隨機生成的Tilemap

Game.java

package com.game.main; 

import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.image.BufferStrategy; 
import java.util.Random; 
//import java.util.Random; 

public class Game extends Canvas implements Runnable{ 

    private static final long serialVersionUID = 5420209024354289119L; 

    public static final int WIDTH = 1000, HEIGHT = WIDTH/12 * 9; 

    private Thread thread; 
    private boolean running = false; 

    //private Random r; 
    private Handler handler; 

    public Game(){ 
     handler = new Handler(); 
     this.addKeyListener(new KeyInput(handler)); 

     new Window(WIDTH, HEIGHT, "Game", this); 
     final int[][] map = DSAlgorithm.makeHeightMap(10, 45, 200); 

     //r = new Random(); 


     handler.addObject(new Player(WIDTH/2 - 32, HEIGHT/2 - 32, ID.Player)); 
     //handler.addObject(new World(0, 0, ID.World)); 
     int squareSize = 10; 
     for(int y = 0; y < map.length; y+=squareSize){ 
      for(int x = 0; x < map.length; x+=squareSize){ 
       int value = map[x][y]; 
       handler.addObject(new TerrianTile(x, y, value)); 
      } 
     } 
    } 

    public synchronized void start(){ 
     thread = new Thread(this); 
     thread.start(); 
     running = true; 
    } 

    public synchronized void stop(){ 
     try { 
      thread.join(); 
      running = false; 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public void run(){ 
     long lastTime = System.nanoTime(); 
     double amountOfTicks = 60.0; 
     double ns = 1000000000/amountOfTicks; 
     double delta = 0; 
     long timer = System.currentTimeMillis(); 
     int frames = 0; 
     while (running){ 
      long now = System.nanoTime(); 
      delta += (now - lastTime)/ns; 
      lastTime = now; 
      while(delta >= 1){ 
       tick(); 
       delta --; 

      } 
      if (running) 
       render(); 
      frames++; 

      if (System.currentTimeMillis() - timer > 1000){ 
       timer += 1000; 
       System.out.println("FPS: " + frames); 
       frames = 0; 
      } 
     } 
     stop(); 
    } 

    private void tick(){ 
     handler.tick(); 
    } 

    private void render(){ 
     BufferStrategy bs = this.getBufferStrategy(); 
     if (bs == null){ 
      this.createBufferStrategy(3); 
      return; 
     } 

     Graphics g = bs.getDrawGraphics(); 

     g.setColor(Color.black); 
     g.fillRect(0, 0, WIDTH, HEIGHT); 

     handler.render(g); 

     g.dispose(); 
     bs.show(); 
    } 

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

    public static int randInt(int min, int max){ 
     Random rand = new Random(); 
     int randomNum = rand.nextInt((max - min) + 1) + min; 
     return randomNum; 
    } 

} 

Window.java

package com.game.main; 

import java.awt.Canvas; 
import java.awt.Dimension; 

import javax.swing.JFrame; 

public class Window extends Canvas { 

    private static final long serialVersionUID = -1478604005915452565L; 

    public Window(int width, int height, String title, Game game) { 
     JFrame frame = new JFrame(title); 

     frame.setPreferredSize(new Dimension(width, height)); 
     frame.setMaximumSize(new Dimension(width, height)); 
     frame.setMinimumSize(new Dimension(width, height)); 

     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setResizable(false); 
     frame.setLocationRelativeTo(null); 
     frame.add(game); 
     frame.setVisible(true); 
     game.start(); 
    } 
} 

DSAlgorithm.java

package com.game.main; 

public class DSAlgorithm { 

    /** 
    * This method uses the seed value to initialize the four corners of the 
    * map. The variation creates randomness in the map. The size of the array 
    * is determined by the amount of iterations (i.e. 1 iteration -> 3x3 array, 
    * 2 iterations -> 5x5 array, etc.). 
    * 
    * @param iterations 
    *   the amount of iterations to do (minimum of 1) 
    * @param seed 
    *   the starting value 
    * @param variation 
    *   the amount of randomness in the height map (minimum of 0) 
    * @return a height map in the form of a 2-dimensional array containing 
    *   integer values or null if the arguments are out of range 
    */ 
    public static int[][] makeHeightMap(int iterations, int seed, int variation) { 
     if (iterations < 1 || variation < 0) { 
       return null; 
     } 

     int size = (1 << iterations) + 1; 
     int[][] map = new int[size][size]; 
     final int maxIndex = map.length - 1; 

     // seed the corners 
     map[0][0] = seed; 
     map[0][maxIndex] = seed; 
     map[maxIndex][0] = seed; 
     map[maxIndex][maxIndex] = seed; 

     for (int i = 1; i <= iterations; i++) { 
       int minCoordinate = maxIndex >> i;// Minimum coordinate of the 
                 // current map spaces 
       size = minCoordinate << 1;// Area surrounding the current place in 
               // the map 

       diamondStep(minCoordinate, size, map, variation); 
       squareStepEven(minCoordinate, map, size, maxIndex, variation); 
       squareStepOdd(map, size, minCoordinate, maxIndex, variation); 

       variation = variation >> 1;// Divide variation by 2 
     } 

     return map; 
    } 

    /** 
    * Calculates average values of four corner values taken from the smallest 
    * possible square. 
    * 
    * @param minCoordinate 
    *   the x and y coordinate of the first square center 
    * @param size 
    *   width and height of the squares 
    * @param map 
    *   the height map to fill 
    * @param variation 
    *   the randomness in the height map 
    */ 
    private static void diamondStep(int minCoordinate, int size, int[][] map, 
       int variation) { 
     for (int x = minCoordinate; x < (map.length - minCoordinate); x += size) { 
       for (int y = minCoordinate; y < (map.length - minCoordinate); y += size) { 
        int left = x - minCoordinate; 
        int right = x + minCoordinate; 
        int up = y - minCoordinate; 
        int down = y + minCoordinate; 

        // the four corner values 
        int val1 = map[left][up]; // upper left 
        int val2 = map[left][down]; // lower left 
        int val3 = map[right][up]; // upper right 
        int val4 = map[right][down];// lower right 

        calculateAndInsertAverage(val1, val2, val3, val4, variation, 
          map, x, y); 
       } 
     } 
    } 

    /** 
    * Calculates average values of four corner values taken from the smallest 
    * possible diamond. This method calculates the values for the even rows, 
    * starting with row 0. 
    * 
    * @param minCoordinate 
    *   the x-coordinate of the first diamond center 
    * @param map 
    *   the height map to fill 
    * @param size 
    *   the length of the diagonals of the diamonds 
    * @param maxIndex 
    *   the maximum index in the array 
    * @param variation 
    *   the randomness in the height map 
    */ 
    private static void squareStepEven(int minCoordinate, int[][] map, 
       int size, int maxIndex, int variation) { 
     for (int x = minCoordinate; x < map.length; x += size) { 
       for (int y = 0; y < map.length; y += size) { 
        if (y == maxIndex) { 
         map[x][y] = map[x][0]; 
         continue; 
        } 

        int left = x - minCoordinate; 
        int right = x + minCoordinate; 
        int down = y + minCoordinate; 
        int up = 0; 

        if (y == 0) { 
         up = maxIndex - minCoordinate; 
        } else { 
         up = y - minCoordinate; 
        } 

        // the four corner values 
        int val1 = map[left][y]; // left 
        int val2 = map[x][up]; // up 
        int val3 = map[right][y];// right 
        int val4 = map[x][down]; // down 

        calculateAndInsertAverage(val1, val2, val3, val4, variation, 
          map, x, y); 
       } 
     } 
    } 

    /** 
    * Calculates average values of four corner values taken from the smallest 
    * possible diamond. This method calculates the values for the odd rows, 
    * starting with row 1. 
    * 
    * @param minCoordinate 
    *   the x-coordinate of the first diamond center 
    * @param map 
    *   the height map to fill 
    * @param size 
    *   the length of the diagonals of the diamonds 
    * @param maxIndex 
    *   the maximum index in the array 
    * @param variation 
    *   the randomness in the height map 
    */ 
    private static void squareStepOdd(int[][] map, int size, int minCoordinate, 
       int maxIndex, int variation) { 
     for (int x = 0; x < map.length; x += size) { 
       for (int y = minCoordinate; y < map.length; y += size) { 
        if (x == maxIndex) { 
         map[x][y] = map[0][y]; 
         continue; 
        } 

        int left = 0; 
        int right = x + minCoordinate; 
        int down = y + minCoordinate; 
        int up = y - minCoordinate; 

        if (x == 0) { 
         left = maxIndex - minCoordinate; 
        } else { 
         left = x - minCoordinate; 
        } 

        // the four corner values 
        int val1 = map[left][y]; // left 
        int val2 = map[x][up]; // up 
        int val3 = map[right][y];// right 
        int val4 = map[x][down]; // down 

        calculateAndInsertAverage(val1, val2, val3, val4, variation, 
          map, x, y); 
       } 
     } 
    } 

    /** 
    * Calculates an average value, adds a variable amount to that value and 
    * inserts it into the height map. 
    * 
    * @param val1 
    *   first of the values used to calculate the average 
    * @param val2 
    *   second of the values used to calculate the average 
    * @param val3 
    *   third of the values used to calculate the average 
    * @param val4 
    *   fourth of the values used to calculate the average 
    * @param variation 
    *   adds variation to the average value 
    * @param map 
    *   the height map to fill 
    * @param x 
    *   the x-coordinate of the place to fill 
    * @param y 
    *   the y-coordinate of the place to fill 
    */ 
    private static void calculateAndInsertAverage(int val1, int val2, int val3, 
       int val4, int variation, int[][] map, int x, int y) { 
     int avg = (val1 + val2 + val3 + val4) >> 2;// average 
     int var = (int) ((Math.random() * ((variation << 1) + 1)) - variation); 
     map[x][y] = avg + var; 
    } 

    public static void main(String[] args) { 

    } 

} 

Handler.java

package com.game.main; 

import java.awt.Graphics; 
import java.util.LinkedList; 

public class Handler { 

    LinkedList<GameObject> object = new LinkedList<GameObject>(); 
    LinkedList<Tiles> tile = new LinkedList<Tiles>(); 

    public void tick(){ 
     for (int i = 0; i < object.size(); i++){ 
      GameObject tempObject = object.get(i); 

      tempObject.tick(); 
     } 

     for (int t = 0; t < tile.size(); t++){ 
      Tiles tempObject = tile.get(t); 

      tempObject.tick(); 
     } 
    } 

    public void render(Graphics g){ 
     for (int i = 0; i < object.size(); i++){ 
      GameObject tempObject = object.get(i); 

      tempObject.render(g); 
     } 

     for (int t = 0; t < tile.size(); t++){ 
      Tiles tempObject = tile.get(t); 

      tempObject.render(g); 
     } 
    } 

    public void addObject(GameObject object){ 
     this.object.add(object); 
    } 

    public void removeObject(GameObject object){ 
     this.object.remove(object); 
    } 

    public void addObject(Tiles tile){ 
     this.tile.add(tile); 
    } 

    public void removeObject(Tiles tile){ 
     this.tile.remove(tile); 
    } 

} 

Tiles.java

package com.game.main; 

import java.awt.Graphics; 
import java.util.LinkedList; 

public class Handler { 

    LinkedList<GameObject> object = new LinkedList<GameObject>(); 
    LinkedList<Tiles> tile = new LinkedList<Tiles>(); 

    public void tick(){ 
     for (int i = 0; i < object.size(); i++){ 
      GameObject tempObject = object.get(i); 

      tempObject.tick(); 
     } 

     for (int t = 0; t < tile.size(); t++){ 
      Tiles tempObject = tile.get(t); 

      tempObject.tick(); 
     } 
    } 

    public void render(Graphics g){ 
     for (int i = 0; i < object.size(); i++){ 
      GameObject tempObject = object.get(i); 

      tempObject.render(g); 
     } 

     for (int t = 0; t < tile.size(); t++){ 
      Tiles tempObject = tile.get(t); 

      tempObject.render(g); 
     } 
    } 

    public void addObject(GameObject object){ 
     this.object.add(object); 
    } 

    public void removeObject(GameObject object){ 
     this.object.remove(object); 
    } 

    public void addObject(Tiles tile){ 
     this.tile.add(tile); 
    } 

    public void removeObject(Tiles tile){ 
     this.tile.remove(tile); 
    } 

} 

TerrianTile.java

package com.game.main; 

import java.awt.Color; 
import java.awt.Graphics; 

public class TerrianTile extends Tiles { 

    public TerrianTile(int x, int y, int tileType) { 
     super(x, y, tileType); 
    } 

    public void tick(){ 

    } 

    public void render(Graphics g){ 
     if (tileType <= 0){ 
      g.setColor(Color.BLUE); 
      g.fillRect(x, y, 10, 10); 
     } 
     //water 
     if (tileType > 0 && tileType < 40){ 
      g.setColor(Color.BLUE); 
      g.fillRect(x, y, 10, 10); 
     } 
     //sand 
     if (tileType >= 40 && tileType < 55){ 
      g.setColor(Color.YELLOW); 
      g.fillRect(x, y, 10, 10); 
     } 
     //grass 
     if (tileType >= 55 && tileType < 120){ 
      g.setColor(Color.GREEN); 
      g.fillRect(x, y, 10, 10); 
     } 
     //forest 
     if (tileType >= 120 && tileType < 140){ 
      g.setColor(Color.LIGHT_GRAY); 
      g.fillRect(x, y, 10, 10); 
     } 
     //stone 
     if (tileType >= 140 && tileType < 170){ 
      g.setColor(Color.GRAY); 
      g.fillRect(x, y, 10, 10); 
     } 
     //snow 
     if (tileType >= 170){ 
      g.setColor(Color.WHITE); 
      g.fillRect(x, y, 10, 10); 
     } 
    } 
} 

KeyInput.java

package com.game.main; 

import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 

public class KeyInput extends KeyAdapter{ 

    private Handler handler; 

    public KeyInput(Handler handler){ 
     this.handler = handler; 
    } 

    public void keyPressed(KeyEvent e){ 
     int key = e.getKeyCode(); 

     for (int i = 0; i < handler.object.size(); i++){ 
      GameObject tempObject = handler.object.get(i); 

      if (tempObject.getId() == ID.Player){ 
       // key events for player 1 
       if (key == KeyEvent.VK_W) tempObject.setVelY(-5); 
       if (key == KeyEvent.VK_S) tempObject.setVelY(5); 
       if (key == KeyEvent.VK_D) tempObject.setVelX(5); 
       if (key == KeyEvent.VK_A) tempObject.setVelX(-5); 
      } 
     } 
    } 

    public void keyReleased(KeyEvent e){ 
     int key = e.getKeyCode(); 

     for (int i = 0; i < handler.object.size(); i++){ 
      GameObject tempObject = handler.object.get(i); 

      if (tempObject.getId() == ID.Player){ 
       // key events for player 1 
       if (key == KeyEvent.VK_W) tempObject.setVelY(0); 
       if (key == KeyEvent.VK_S) tempObject.setVelY(0); 
       if (key == KeyEvent.VK_D) tempObject.setVelX(0); 
       if (key == KeyEvent.VK_A) tempObject.setVelX(0); 
      } 
     } 
    } 

} 

不知道是否有辦法容器矩形瓦片,然後移動矩形。任何幫助將非常感激。

回答

0

我真的不知道你的意思是移動矩形中的瓷磚,但如果你只是簡單地想要將它們全部移動到某個方向,可以在繪製它們之前使用g.translate(dx,dY)。

或者,如果地形不變,您可以在開始時在圖像上繪製它們,然後在不同位置繪製圖像。