簡體   English   中英

Java-移動隨機生成的圖塊圖

[英]Java - Moving Randomly Generated Tilemap

我對Java非常了解,但是我想創建一個探索類游戲。 我研究了過去的兩周,並能夠在一些非常漂亮的地形上實現菱形平方算法。 但是現在我在嘗試弄清楚如何移動地圖以及如何繼續隨機生成方面遇到了麻煩。 到目前為止,這就是我所擁有的。

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);
            }
        }
    }

}

不知道是否有辦法將圖塊包裝成一個矩形,然后移動該矩形。 任何幫助將非常感激。

我真的不知道通過將矩形移動到矩形中是什么意思,但是如果您只是想將它們全部朝某個方向移動,則可以在繪制它們之前使用g.translate(dx,dY)。

或者,如果地形沒有變化,則可以在開始時將其繪制在圖像上,然后在不同位置的每一幀繪制圖像。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM