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

📄 islandinfinity.java

📁 good project for programmer,,
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////////   IslandInfinity.java//  Lux Map Generator//  Makes maps consisting of groups of connected islands////  Version: 1.0//  Date last modified: 5/28/2006//  By: Greg McGlynn//////////////////////////////////////////package org.mcglynns.lux;import com.sillysoft.lux.*;import java.io.*;import java.util.*;import java.awt.*;import java.awt.geom.*;public class IslandInfinity implements LuxMapGenerator {  Random rand;  //used in making names  static char[] consonants = new char[]{'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm',                                        'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'z'};  static char[] vowels = new char[]{'a', 'e', 'i', 'o', 'u'};  static int numConsonants = consonants.length;  static int numVowels = vowels.length;  Vector countryPolygons; //shapes of the countrys  Vector connections;     //vector of vectors of integers that say which countries a country connects to  //the game calls this when it wants a map  //write a map xml to out  public boolean generate(PrintWriter out, String choice, int seed, MapLoader m) {    //seed must completely determine our map    rand = new Random(seed);    countryPolygons = new Vector();    connections = new Vector();    //set size & conts based on user choice    int width = 600;    int height = 400;    int numContinents = 6;    if(choice == CHOICE_BIG) {      width = 700;      height = 480;      numContinents = 10;    } else if(choice == CHOICE_HUGE) {      width = 800;      height = 550;      numContinents = 17;    } else if (choice == CHOICE_REALLYHUGE) {      width = 1100;      height = 700;      numContinents = 25;    }    int contVariation = numContinents/6; //numContinents can vary (+/- 1/6)    numContinents += rand.nextInt(2*contVariation+1)-contVariation;    //the header of our xml file    out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +              "<luxboard>\n" +              "<version>1.0</version>\n" +              "<width>" + width + "</width>\n" +              "<height>" + height + "</height>\n" +              "<theme>Ocean</theme>\n" +              "<author>IslandInfinity Generator (by Greg McGlynn)</author>\n" +              "<email>greg@mcglynns.org</email>\n" +              "<webpage>www.sillysoft.net</webpage>\n" +              "<title>" + choice + " #" + seed + "</title>\n" +              "<description>This map was made by the IslandInfinity LuxMapGenerator. Type: " + choice +                       ",  Number of continents: " + numContinents  + "</description>\n");    debug("placing continents...");    //determine where our continents will go    Rectangle[] contBounds = placeContinents(numContinents, width, height);    Point[] contCenters = getContCenters(contBounds);    int[] contIndices = new int[numContinents+1]; //the starting index of each cont's countries in the Vectors    for(int i = 0; i < numContinents; i += 1) {      debug("new cont: " + i);      contIndices[i] = countryPolygons.size();      addNewContinent(contBounds[i]); //determine the shapes and connections of the cont's countries    }    contIndices[numContinents] = countryPolygons.size();    debug("Making connections...");    //connect up the continents:    Vector lines = makeConnectionsBetweenContinents(contIndices, contCenters, contBounds, numContinents);    //now write the continents to out    for(int i = 0; i < numContinents; i += 1) {      debug("writing cont: " + i);      int start = contIndices[i];      int end = contIndices[i+1];      writeContinent(start, end, out);    }    debug("drawing lines");    //write the lines representing intercontinent connections    for(int i = 0; i < lines.size(); i += 1) {      writeLine(out, (Line2D.Double)lines.get(i));    }    //done    debug("done");    out.write("</luxboard>");    return true;  }  //this function places numContiennts rectangles in a box of size width-height  //so that none overlap. we use this to choose where our continents will go  private Rectangle[] placeContinents(int numContinents, int width, int height) {    //minimum and maximum sizes of the rectangles    int minWidth = 75;    int minHeight = 60;    int maxWidth = 150;    int maxHeight = 120;    contplacement:    while(true) {  //loops until we have a valid arrangement      Rectangle[] ret = new Rectangle[numContinents];      for(int i = 0; i < numContinents; i += 1) { //place the conts one at a time        boolean success = false; //whether we successfully placed this cont        placetry:        for(int k = 0; k < 15; k += 1) { //try to place this cont 15 times          int contWidth = rand.nextInt(maxWidth-minWidth) + minWidth;          int contHeight = rand.nextInt(maxHeight-minHeight) + minHeight;          int x = rand.nextInt(width - contWidth);          int y = rand.nextInt(height - contHeight);          ret[i] = new Rectangle(x, y, contWidth, contHeight);          //expandedI creates a buffer between continents          Rectangle expandedI = new Rectangle(x-20, y-20, contWidth+40, contHeight+40);          for(int j = 0; j < i; j += 1) {            if(ret[j].intersects(expandedI))  //overlap              continue placetry; //try again...          }          success = true; //no intersections          break; //success in placing this cont        }        if(!success) continue contplacement; //couldn't place this cont, start over      }      return ret; //made it through all conts: done    }  }  //determines the centerpoint of each continent  private Point[] getContCenters(Rectangle[] contBounds) {    Point[] ret = new Point[contBounds.length];    for(int i = 0; i < ret.length; i += 1) {      ret[i] = new Point(contBounds[i].x + contBounds[i].width/2,                         contBounds[i].y + contBounds[i].height/2);    }    return ret;  }  //pick a name for a continent (consonant - vowel - consonant)  private String makeContinentName() {    return new String(new char[]{Character.toUpperCase(consonants[rand.nextInt(numConsonants)]),                                  vowels[rand.nextInt(numVowels)],                                  consonants[rand.nextInt(numConsonants)]});  }  //pick a name for a country (contName - vowel - consonant)  private String makeCountryName(String continentName) {    return continentName + new String(new char[]{vowels[rand.nextInt(numVowels)],                                                 consonants[rand.nextInt(numConsonants)]});  }  //output the xml of a continent  //start and end are indices in the polygon and connection Vectors  private void writeContinent(int start, int end, PrintWriter out) {    String continentName = makeContinentName();    int countries = end-start;    int numBorders = 0;    for(int i = start; i < end; i += 1) {      Vector theseConns = (Vector)connections.get(i);      boolean isABorder = false;      for(int j = 0; j < theseConns.size(); j += 1) {        int connIndex = ((Integer)theseConns.get(j)).intValue();        if(connIndex < start || connIndex >= end) {          isABorder = true;        }      }      if(isABorder) numBorders += 1;    }    int bonus = numBorders;    out.write("<continent>\n" +	"  <continentname>" + continentName + "</continentname>\n" +	"  <bonus>" + bonus + "</bonus>\n");    for(int i = start; i < end; i += 1) { //write out each country      out.write("  <country>\n" +		"    <id>" + i + "</id>\n" +		"    <name>" + makeCountryName(continentName) + "</name>\n");      writeConnections(out, (Vector)connections.get(i));      writePolygon(out, (Polygon)countryPolygons.get(i));      out.write("  </country>\n");    }    out.write("</continent>\n");  }  //continent shapes  static final int CONT_RECT = 0;  static final int CONT_ELLIPSE = 1;  static final int numContTypes = 2;  //set up a continent's interior: countries and connections  private void addNewContinent(Rectangle bounds) {    //pick a shape:    int contType = rand.nextInt(numContTypes);    int indexStart = countryPolygons.size(); //starting index in the Vectors    //countries in continent = area/2000 +/- 1    int area = bounds.width*bounds.height;    int countries = area/2000 + rand.nextInt(3)-1;    if(countries < 1) countries = 1;    for(int i = 0; i < countries; i += 1) {      connections.add(new Vector());    }    //each country has a "center." the country consists of the locus of points    //within the continent boundary and closer to the country's center than to    //any other country's center. this means that boundaries consist of the cont    //boundaries and the perpendicular bisectors of segments between close centers    //pick center locations, ensuring that no two are two close,    //as this leads to tiny countries    Point[] centers = new Point[countries];    double minDist = Math.sqrt(area/(double)countries - 750);    boolean done = false;    centerplacement:    while(!done) {      for(int i = 0; i < countries; i += 1) {        centers[i] = getPointInContinent(bounds, contType);        for(int j = 0; j < i; j += 1) {          if(dist(centers[i], centers[j]) < minDist) continue centerplacement;        }      }      done = true;    }    //now create the country polygons. these consist of 100 points. the points have    //2*pi/100 radians between them angularly, but can be at different radii.    Polygon[] polygons = new Polygon[countries];    for(int i = 0; i < countries; i += 1) {      polygons[i] = new Polygon();      for(double theta = 0; theta < 2*Math.PI; theta += Math.PI/50) {        Point borderPoint = getPointOnContinentBorder(centers[i], theta, bounds, contType);        int lastNeighbor = -1;        //now cycle through the other centers and make sure this point is closer to        //this center than any other        for(int p = 0; p < countries; p += 1) {          if(dist(borderPoint, centers[p]) < dist(borderPoint, centers[i])) {            lastNeighbor = p;            int radius = (int)dist(borderPoint, centers[i]);            int movement = radius/2;            for(int j = 0; j < 40; j += 1) {              borderPoint = new Point((int)(centers[i].x + radius*Math.cos(theta)),                                      (int)(centers[i].y + radius*Math.sin(theta)));              if(dist(borderPoint, centers[p]) < dist(borderPoint, centers[i])) {                radius -= movement;              } else {                radius += movement;              }              movement /= 2;            }          }        }        //if this point is a boundary between two countries, make a connection between them        if(lastNeighbor != -1) {          ((Vector)connections.get(indexStart + lastNeighbor)).add(new Integer(indexStart + i));          ((Vector)connections.get(indexStart + i)).add(new Integer(indexStart + lastNeighbor));        }        polygons[i].addPoint(borderPoint.x, borderPoint.y);      }//      if(((Vector)connections.get(i)).size() == 0) debug("didn't connect " + i + " to anything");//      else debug("" + i + " connects to " + ((Integer)((Vector)connections.get(i)).get(0)).intValue());      countryPolygons.add(polygons[i]);    }  }  //pick a random point within the given cont shape  private Point getPointInContinent(Rectangle bounds, int contType) {    if(contType == CONT_RECT) {      return new Point(bounds.x + rand.nextInt(bounds.width),                       bounds.y + rand.nextInt(bounds.height));    } else if(contType == CONT_ELLIPSE) {      while(true) {

⌨️ 快捷键说明

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