⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 world.java

📁 SIMULATION FOURMILIERE -3D-ISOMETRIQUE
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package fr.umlv.fourmIR2000.world;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import fr.umlv.fourmIR2000.Game;
import fr.umlv.fourmIR2000.insect.Insect;
import fr.umlv.fourmIR2000.insect.Team;
import fr.umlv.fourmIR2000.pictures.Values;
import fr.umlv.lawrence.impl.DefaultGridModel;


/**
 * World to use with the game.
 * This is a sort of container of all objects that must be drawn on the JPanel.
 */
public final class World implements Serializable {
	
    /** For serialization : version of the class */
    private final static long serialVersionUID = 1L;
    
    /** Model used to draw pictures  BE CAREFUL : We don't want it to be serializable !!! */
    private transient DefaultGridModel<Values> model;

    /** Shortest path finding */
    private transient PathFinding path;
    
    /** Size X of the game */
    private int sizeX;
    
    /** Size Y of the game */
    private int sizeY;
    
    /** Matrix of Floor elements */
    private Floor tab[][];  
    
    /** Array of teams playing */
    private ArrayList<Team> tabTeam;
    
    /** Array of food present in the game */
    private ArrayList<WorldPoint> tabFood;

    /** The point of the map who has the focus */
    private WorldPoint selectedPoint;
    
    
    /**
     * Create a new World for playing
     * @param sizeX     Size X of the game (the real size is this size + size of the left menu)
     * @param sizeY     Size Y of the game
     */
    public World(int sizeX, int sizeY) {
        // Errors detection
        if (sizeX < 1) sizeX = 1;
        if (sizeY < 1) sizeY = 1;
        
        // Initialization of the variables
        this.sizeX = sizeX;
        this.sizeY = sizeY;
        tabTeam = new ArrayList<Team>();
        tabFood = new ArrayList<WorldPoint>();
        path = null;
        selectedPoint = null;
        initializeGridModel();
    }
    

    /**
     * Give the GridModel used by the world
     * @return the DefaultGridModel to use in a GridPane
     * @see fr.umlv.lawrence.GridPane
     */
    public DefaultGridModel<Values> getModel() {
        return model;
    }

    
    /**
     * Generate an new world, and store the position of the two antHills
     * >> The first antHill is the one we play with
     * @param maxX          new X maximal coord
     * @param maxY          new Y maximal coord
     * @param percentDesert percent of desert tiles in the map
     * @param percentWater  percent of water tiles in the map
     * @param percentRocks  % of rocks to have in the map
     * @param percentFood   % of food to have in the map
     */
    public void generateNewWorld(int maxX, int maxY, int percentDesert, int percentWater, int percentRocks, int percentFood) {
        sizeX = maxX;
        sizeY = maxY;
        RandomWorld rndWorld = new RandomWorld(sizeX, sizeY, percentDesert, percentWater, percentRocks, percentFood);
        tab = rndWorld.getWorld();
        tabTeam.clear();
        path = new PathFinding(this);
        initializeGridModel();
        refresh();
    }
    
    
    /**
     * Initialize a new GridModel with the current 'Floor' elements 
     */
    private void initializeGridModel() {
        @SuppressWarnings("unchecked")
        Set<Values>[] array = (Set<Values>[]) new Set<?>[sizeX * sizeY];
        int i = 0;
        for (int y=0; y < sizeY; ++y)
            for (int x=0; x < sizeX; ++x) {
            	array[i]=EnumSet.noneOf(Values.class);
            	if (tab == null)
            		array[i].add(Values.grass);
            	else
            		array[i].addAll(tab[y][x].getPictures());
            	i++;
            }
        model = new DefaultGridModel<Values>(sizeY, sizeX, Arrays.asList(array));
    }
    
    
    /**
     * Store the food positions in an array. This way, all insects can find where is the nearest food.
     */
    public void storeFood() {
        tabFood.clear();
        for (int y = 0; y < sizeY; ++y)
            for (int x = 0; x < sizeX; ++x)
                if (tab[y][x].getType() == Values.food)
                    tabFood.add(tab[y][x].getPoint());
    }

    
    /**
     * Give the width of the map
     * @return the width of the map (+ the size of the menu)
     */
    public int getWidth() {
        return sizeX;
    }
    
    
    /**
     * Give the height of the map
     * @return the height of the map
     */
    public int getHeight() {
        return sizeY;
    }

    
    /**
     * Return the value of the element at this tile
     * @param x X position
     * @param y Y position
     * @return the value
     */
    public Values getElement(int x, int y) {
        if (isPositionAvailable(x, y))
            return tab[y][x].getType();
        return null;
    }

    
    /**
     * Return the value of the background element at this tile
     * @param x X position
     * @param y Y position
     * @return the value
     */
    public Values getBackgroundElement(int x, int y) {
        if (isPositionAvailable(x, y))
            return tab[y][x].getBackgroundType();
        return null;
    }
    
    
    /**
     * Assign an element for the backgroun of a specific tile
     * @param x         X posiiton
     * @param y         Y position
     * @param type value to assign
     * @param isDirect true to redraw immediately, false to wait for a refresh() call
     * @see #refresh()
     */
    public void setElement(int x, int y, Values type, boolean isDirect) {
        if (isPositionAvailable(x, y)) {
            // We update the ground element
            tab[y][x].setType(type);
            tab[y][x].setObstacle(Values.isObstacle(type));
            // And we inform the model that it has changed
            updateModelAndAdjacentTiles(x, y, isDirect);
        }
    }
    
    
    /**
     * Assign an element for the backgroun of a specific tile
     * @param floor		the floor element to update
     * @param isDirect true to redraw immediately, false to wait for a refresh() call
     * @see #refresh()
     */
    public void setElement(Floor floor, boolean isDirect) {
        int x = floor.getPoint().getX();
        int y = floor.getPoint().getY();
    	if (isPositionAvailable(x, y)) {
            // We update the ground element and the graphics of tiles around
            tab[y][x] = floor;
            WorldBlur.blurFloor(tab, floor);
            WorldBlur.blurAdjacentFloors(tab, floor);
            // And we inform the model that it has changed
            updateModelAndAdjacentTiles(x, y, isDirect);
     
        }
    }
    

    /**
     * Try to update the pictures of all adjacent tiles
     * @param x	the X coord of the main tile
     * @param y	the Y coord of the main tile
     * @param isDirect true to redraw immediately, false to wait for a refresh() call
     * @see #refresh()
     */
    private void updateModelAndAdjacentTiles(int x, int y, boolean isDirect) {
        updateModel(x, y, isDirect);
        if (isPositionAvailable(x-1, y)) updateModel(x-1, y, isDirect);
        if (isPositionAvailable(x+1, y)) updateModel(x+1, y, isDirect);
        if (isPositionAvailable(x, y-1)) updateModel(x, y-1, isDirect);
        if (isPositionAvailable(x, y+1)) updateModel(x, y+1, isDirect);
    }
    

    /**
     * Indicate if the specified position is crossable or not, without
     * regarding if there is an insect or not in the tile. 
     * @param p The position to check
     * @return true if it is crossable
     */
    private boolean isBackgroundCrossable(WorldPoint p) {
        return isPositionAvailable(p) && !tab[p.getY()][p.getX()].isObstacle();
    }

    
    /**
     * Indicate if the specified position is crossable or not, regarding
     * if there is an insect on it
     * @param p The position to check
     * @return true if it is crossable
     */
    public boolean isCrossable(WorldPoint p) {
        return isBackgroundCrossable(p) && tab[p.getY()][p.getX()].getInsect() == null;
    }


    /**
     * Indicate if the specified position is available for an insect or not
     * @param x     X position
     * @param y     Y position
     * @return true if the tile is free
     * @see #isPositionAvailable(WorldPoint)
     */
    public boolean isPositionAvailable(int x, int y) {
        return (x < 0 || y < 0 || x >= sizeX || y >= sizeY) ? false : true;
    }
    

    /**
     * Indicate if the specified position is available for an insect or not
     * @param p the point to check
     * @return true if the tile is free
     * @see #isPositionAvailable(int, int) 
     */
    boolean isPositionAvailable(final WorldPoint p) {
        return isPositionAvailable(p.getX(), p.getY());
    }
        
    
    /**
     * Tell us if we can move to the chosen destination.
     * Be careful: we can only move of one tile ! 
     * @param src   the source Point
     * @param dest  the destination Point
     * @return true if we can go there
     */
    public boolean canMoveHere(WorldPoint src, WorldPoint dest) {
        int destX = dest.getX();
        int destY = dest.getY();
        
        // Bad position ? We quit immediatly
        if (src.distance(dest) >= 2 || ! isPositionAvailable(dest) || tab[destY][destX].isObstacle())
            return false;
        /* We check for diagonals : we can't move in a diagonal if there are block all around.
         * ie. if we want to go Upper/Left, and if there are rocks on left and upper, we can't go. */
        int x = src.getX();
        int y = src.getY();
        final WorldPoint UpLeft =    getPoint(x - 1, y - 1);
        final WorldPoint Up =        getPoint(x,     y - 1);
        final WorldPoint UpRight =   getPoint(x + 1, y - 1);
        final WorldPoint Left =      getPoint(x - 1, y);
        final WorldPoint Right =     getPoint(x + 1, y);
        final WorldPoint DownLeft =  getPoint(x - 1, y + 1);
        final WorldPoint Down =      getPoint(x,     y + 1);
        final WorldPoint DownRight = getPoint(x + 1, y + 1);
        if (   (dest.equals(UpLeft)    && !isCrossable(Up)   && !isCrossable(Left))
            || (dest.equals(UpRight)   && !isCrossable(Up)   && !isCrossable(Right))
            || (dest.equals(DownLeft)  && !isCrossable(Down) && !isCrossable(Left))
            || (dest.equals(DownRight) && !isCrossable(Down) && !isCrossable(Right))
        )
            return false;
        return true;
    }
    
    
     /**
     * Give the list of all insects that are around a point
     * @param me        insect who calls the verification
     * @param radius    the radius to check around the insect
     * @param wantAFriend if true return our friends. If false, return the ennemies
     * @return true if exists or false;
     */
    public LinkedList<Insect> giveInsectAround(Insect me, int radius, boolean wantAFriend) {
        WorldPoint p = me.getPos();
        LinkedList<Insect> result= new LinkedList<Insect>();

        for(int y = p.getY() - radius; y <= p.getY() + radius; y++) {
            for (int x = p.getX() - radius; x <= p.getX() + radius; x++) {
                if (isPositionAvailable(x, y)) {
                    Floor floor = tab[y][x];
                    if (! floor.getPoint().equals(p)) {
                        Insect insect = floor.getInsect();
                        if (insect != null) {
                            boolean isOurTeam = insect.getTeam().equals(me.getTeam());
                            if ((isOurTeam && wantAFriend) || (!isOurTeam && !wantAFriend))
                                result.add(insect);
                        }
                    }
                }
            }
        }
        return result;
    }
    
    
    /**
     * Add a team of insects to the world. The first team would be the team we play with !
     * >> it works because we use an ArrayList
     * @param antHill    point of the antHill
     * @param color      color of the team
     * @param game       the gameassociated (to perform some special actions when an antQueen die for example)
     */
    public void addTeam(WorldPoint antHill, int color, Game game) {
        Team team = new Team(this, antHill, color, game);
        team.addMaster();
        tabTeam.add(team);
    }

    
    /**
     * Add an insect in the game
     * @param insect    new insect to add
     * @return          true if we can add the insect in the specified place
     */
    public boolean addInsect(Insect insect) {
        if (insect == null)
            return false;
        WorldPoint p = insect.getPos();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -