?? castleinfinity.java
字號(hào):
//draw houses and such in the countryside private void drawCountrysideDecorations() { //get the images from the Castle Lux SI foreground BufferedImage house1 = siForeground.getSubimage(305, 190, 40, 40); BufferedImage house2 = siForeground.getSubimage(775, 193, 35, 35); BufferedImage house3 = siForeground.getSubimage(790, 228, 35, 35); BufferedImage house4 = siForeground.getSubimage(65, 391, 40, 40); BufferedImage house5 = siForeground.getSubimage(420, 200, 52, 40); BufferedImage[] houses = new BufferedImage[]{house1, house2, house3, house4, house5}; double[] maxRadii = new double[]{15, 21, 21, 15, 12}; boolean[] used = new boolean[countryPolygons.size()]; for(int i = 0; i < used.length; i += 1) used[i] = false; loop: for(int i = 0; i < countryPolygons.size()/2; i += 1) { int index; do { index = rand.nextInt(countryPolygons.size()); } while(used[index]); used[index] = true; int houseType = rand.nextInt(houses.length); Point center = polygonCenter((Polygon)countryPolygons.get(index)); double radius = 10 + rand.nextDouble()*(maxRadii[houseType]-10); double angle = rand.nextDouble()*Math.PI*2; center.x += (int)(radius*Math.cos(angle)); center.y += (int)(radius*Math.sin(angle)); for(int c = 0; c < numCastles; c += 1) { if(dist(polygonCenter(castleCenters[c]), center) < Math.sqrt(2)*cOR + 15) continue loop; } BufferedImage house = houses[houseType]; foreG.drawImage(house, center.x-house.getWidth()/2, height - (center.y + house.getWidth()/2), this); } } private static final Point[] siCastlePoints = new Point[]{new Point(260, 100)}; private static final int siCastleWidth = 40; private static final int siCastleHeight = 40; //draw the image of a castle at point c private void drawCastleAt(Point c) { int i = rand.nextInt(siCastlePoints.length); backG.setColor(Color.green.darker().darker()); backG.fillRect(c.x - cOR, height - (c.y + cOR), 2*cOR, 2*cOR); foreG.drawImage(siForeground.getSubimage(siCastlePoints[i].x-siCastleWidth, siCastlePoints[i].y-siCastleHeight, 2*siCastleWidth, 2*siCastleHeight), c.x-siCastleWidth, height - (c.y+siCastleHeight), this); } //remove a hexagon from the map private void removeHexagon(Polygon h) { int index = countryPolygons.indexOf(h); if(index != -1) { countryPolygons.remove(index); connections.remove(index); } } //can a hexagon be the center of a castle? only if it's far enough from the edge private boolean canBeCastleCenter(int index) { Point center = polygonCenter((Polygon)countryPolygons.get(index)); if(center.x > hexRad*3 && center.y > hexRad*3 && center.x < width-hexRad*3 && center.y < height-hexRad*3) { return true; } else { return false; } } //find the index of the closest castle to a polygon private int closestCastle(Polygon p) { int closestCastle = -1; double closestDist = 100000; for(int i = 0; i < numCastles; i += 1) { double dist = dist(polygonCenter(castleCenters[i]), polygonCenter(p)); if(dist < closestDist) { closestDist = dist; closestCastle = i; } } return closestCastle; } //test if a line intersects any of a polygon's edges private boolean lineIntersectsPolygon(Line2D.Double l, Polygon p) { for(int i = 0; i < p.npoints; i += 1) { Line2D.Double l2 = new Line2D.Double(p.xpoints[i], p.ypoints[i], p.xpoints[(i+1)%p.npoints], p.ypoints[(i+1)%p.npoints]); if(l.intersectsLine(l2)) return true; } return false; } //draw Polygon p with g, but flip it upside-down first //theme and xml have different coordinate systems private void fillPolygon(Graphics g, Polygon p) { int[] ypoints = new int[p.npoints]; for(int i = 0; i < p.npoints; i += 1) { ypoints[i] = height - p.ypoints[i]; } g.fillPolygon(p.xpoints, ypoints, p.npoints); } private Point midpoint(Point a, Point b) { return new Point((a.x + b.x)/2, (a.y + b.y)/2); } private static final String[] suffixes = new String[]{"ville", "ton", " town", " city", " village"}; //generate a random name for a hexagon country from our list of players private String makeHexagonName() { return names[rand.nextInt(names.length)] + suffixes[rand.nextInt(suffixes.length)]; } //random castle name private String makeCastleName() { return new String(new char[]{Character.toUpperCase(consonants[rand.nextInt(numConsonants)]), vowels[rand.nextInt(numVowels)], consonants[rand.nextInt(numConsonants)], vowels[rand.nextInt(numVowels)], consonants[rand.nextInt(numConsonants)], vowels[rand.nextInt(numVowels)], consonants[rand.nextInt(numConsonants)]}) + " Castle"; } //random countryside name private String makeCountrysideName(String castleName) { String[] types = new String[]{"Lowlands", "Highlands", "Forest", "Countryside", "Plains", "Hills", "Valley"}; return castleName + " " + types[rand.nextInt(types.length)]; } private String makeWallName(int wall) { switch(wall) { case 0: return "NE Wall"; case 1: return "NW Wall"; case 2: return "SW Wall"; case 3: return "SE Wall"; } return "Castle Wall"; } //make a hexagon centered on point p private Polygon hexagonAround(Point p) { int[] xpoints = new int[6]; int[] ypoints = new int[6]; for(int i = 0; i < 6; i += 1) { xpoints[i] = (int)(p.x + (hexRad-1)*Math.cos(Math.PI/6 + i*Math.PI/3)); ypoints[i] = (int)(p.y + (hexRad-1)*Math.sin(Math.PI/6 + i*Math.PI/3)); } return new Polygon(xpoints, ypoints, 6); } //find the center of gravity of a polygon's points private Point polygonCenter(Polygon p) { double x = 0; double y = 0; for(int i = 0; i < p.npoints; i += 1) { x += p.xpoints[i]; y += p.ypoints[i]; } x /= p.npoints; y /= p.npoints; return new Point((int)x, (int)y); } //draw a line between the polygons with endpoints on their perimeters //we do this through a binary search for their boundaries private Line2D.Double drawLineBetween(Polygon a, Polygon b) { Point ca = polygonCenter(a); Point cb = polygonCenter(b); double theta = Math.atan2(ca.y - cb.y, ca.x - cb.x); double radius = dist(ca, cb); double movement = radius/2; for(int i = 0; i < 20; i += 1) { ca = new Point((int)(cb.x + radius*Math.cos(theta)), (int)(cb.y + radius*Math.sin(theta))); if(a.contains(ca)) { radius -= movement; } else { radius += movement; } movement /= 2; } radius += 5; //make sure the line isn't detached ca = new Point((int)(cb.x + radius*Math.cos(theta)), (int)(cb.y + radius*Math.sin(theta))); theta += Math.PI; radius = dist(ca, cb); movement = radius/2; for(int i = 0; i < 20; i += 1) { cb = new Point((int)(ca.x + radius*Math.cos(theta)), (int)(ca.y + radius*Math.sin(theta))); if(b.contains(cb)) { radius -= movement; } else { radius += movement; } movement /= 2; } radius += 5; //make sure the line isn't detached cb = new Point((int)(ca.x + radius*Math.cos(theta)), (int)(ca.y + radius*Math.sin(theta))); return new Line2D.Double(ca, cb); } //write the xml representation of a country polygon private void writePolygon(Polygon p) { out.write(" <polygon>"); for(int i = 0; i < p.npoints; i += 1) { out.write("" + p.xpoints[i] + "," + p.ypoints[i] + " "); } out.write("</polygon>\n"); } //write the xml representation of a country's adjoining list private void writeConnections(Vector conns) { out.write(" <adjoining>"); for(int i = 0; i < conns.size()-1; i += 1) { out.write("" + (Integer)conns.get(i) + ","); } if(conns.size() > 0) out.write("" + (Integer)conns.get(conns.size()-1)); out.write("</adjoining>\n"); } //write the xml representation of a line private void writeLine(Line2D.Double l) { out.write("<line><position>" + (int)l.x1 + "," + (int)l.y1 + " " + (int)l.x2 + "," + (int)l.y2 + "</position></line>\n"); } //dilate p by ratio ratio private Polygon dilatePolygon(Polygon p, double ratio) { Point c = polygonCenter(p); int[] xpoints = new int[p.npoints]; int[] ypoints = new int[p.npoints]; for(int i = 0; i < p.npoints; i += 1) { xpoints[i] = (int)(c.x + ratio*(p.xpoints[i] - c.x)); ypoints[i] = (int)(c.y + ratio*(p.ypoints[i] - c.y)); } return new Polygon(xpoints, ypoints, p.npoints); } //distance between two points private double dist(Point a, Point b) { return Math.sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); } //interface function. should be true on release public boolean canCache() { return false; } public String description() { return "CastleInfinity is a random map generator that makes maps in the style of Castle Lux SI, complete with a similar theme. Note that the randomly generated themes will only be seen by the host in network games.\n\nCredit for the graphics from Castle Lux SI goes to Mark Bauer."; } //user size choices static final String CHOICE_SMALL = "CastleInfinity - small"; static final String CHOICE_NORMAL = "CastleInfinity - normal"; static final String CHOICE_BIG = "CastleInfinity - big"; public java.util.List getChoices() { Vector v = new Vector(); v.add(CHOICE_SMALL); v.add(CHOICE_NORMAL); v.add(CHOICE_BIG); return v; } //interface function; unused public String message(String message, Object data) { return ""; } public String name() { return "CastleInfinity"; } public float version() { return 1.0f; } private void debug(String s) { System.out.println(":" + s); } //list of player names for naming hexagon countries, taken from http://sillysoft.net/lux/rankings/wins/alltime.php on June 14, 2006 String[] names = new String[]{"shopi","Loki","magpie","upeng2005","jOnNiE","Smedz","paranoiarodeo","mercer","obiwan","General K","tfPunx","Punkee.Munkee","MrBuckin the Impaler","Brewster","Jerry T","DR.Zuss","documan","what? oh yeah.","MASSHOLE","Darth Rellek","Mouldy Dog","PJR","'84 Tigers","Dad","JadePathMan","dustin","Gabo","michelle","Alexander_the_Great","futurist","Gryffindor","KingPatrick","shalafarky","bstevens","vargas","Yo Daddy","gary the cheater","shock-n-ya'll","stevedip","Grozoth","Mud","fink","Natya","mood in dhingo","fishflakes","Preacherman","mikey","Zo
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -