📄 castleinfinity.java
字号:
if(!hasNeighborInContinent) { removeHexagon((Polygon)countryPolygons.get(i)); i -= 1; } } //draw land borders between continents //for each pair of polygons // if they are in two different continents and two of their sides are right next to each other // draw a thick white line along those sides foreG.setColor(Color.white); foreG.setStroke(new BasicStroke(5)); for(int ip = 0; ip < countryPolygons.size(); ip += 1) { Polygon p = (Polygon)countryPolygons.get(ip); int pClosestCastle = closestCastle(p); for(int jn = 0; jn < ((Vector)connections.get(ip)).size(); jn += 1) { Polygon n = (Polygon)(((Vector)connections.get(ip)).get(jn)); if(countryPolygons.contains(n) && pClosestCastle != closestCastle(n)) { //countryside border for(int i = 0; i < p.npoints; i += 1) { for(int j = 0; j < n.npoints; j += 1) { if(dist(new Point(p.xpoints[i], p.ypoints[i]), new Point(n.xpoints[j], n.ypoints[j])) < 10) { for(int iOff = -1; iOff <= 1; iOff += 2) { int i2 = (i+iOff+p.npoints)%p.npoints; for(int jOff = -1; jOff <= 1; jOff += 2) { int j2 = (j+jOff+n.npoints)%n.npoints; if(dist(new Point(p.xpoints[i2], p.ypoints[i2]), new Point(n.xpoints[j2], n.ypoints[j2])) < 10) { foreG.draw(new Line2D.Double((p.xpoints[i]+n.xpoints[j])/2, height - (p.ypoints[i]+n.ypoints[j])/2, (p.xpoints[i2]+n.xpoints[j2])/2, height - (p.ypoints[i2]+n.ypoints[j2])/2)); out.println("<line><position>" + (p.xpoints[i]+n.xpoints[j])/2 +"," + (p.ypoints[i]+n.ypoints[j])/2 + " " + (p.xpoints[i2]+n.xpoints[j2])/2 + "," + (p.ypoints[i2]+n.ypoints[j2])/2 + "</position><above>true</above></line>"); } } } } } } } } } } //create the polygons and connections of a bridge between hex a and hex b. private void makeBridgeBetween(Polygon a, Polygon b) { //line between hexagons' midpoints Line2D.Double line = drawLineBetween(a, b); //don't make tiny bridges if(dist(new Point((int)line.x1, (int)line.y1), new Point((int)line.x2, (int)line.y2)) < 20) { return; } double lineAngle = Math.atan2(line.y2 - line.y1, line.x2 - line.x1); double ang = lineAngle + Math.PI/2; double midX = (line.x2 + line.x1)/2; double midY = (line.y2 + line.y1)/2; //if a contracted version of the bridge intersects a polygon that is not //a or b, don't draw the bridge, as it will look funny Line2D.Double shortenedSide1 = new Line2D.Double(midX - 20*Math.cos(ang) - (line.x2 - line.x1)/4, midY - 20*Math.sin(ang) - (line.y2 - line.y1)/4, midX - 20*Math.cos(ang) + (line.x2 - line.x1)/4, midY - 20*Math.sin(ang) + (line.y2 - line.y1)/4); Line2D.Double shortenedSide2 = new Line2D.Double(midX + 20*Math.cos(ang) - (line.x2 - line.x1)/4, midY + 20*Math.sin(ang) - (line.y2 - line.y1)/4, midX + 20*Math.cos(ang) + (line.x2 - line.x1)/4, midY + 20*Math.sin(ang) + (line.y2 - line.y1)/4); for(int i = 0; i < countryPolygons.size(); i += 1) { Polygon p = (Polygon)countryPolygons.get(i); if(p != a && p != b && (lineIntersectsPolygon(shortenedSide1, p) || lineIntersectsPolygon(shortenedSide2, p) || p.contains(shortenedSide1.x1, shortenedSide1.y1) || p.contains(shortenedSide1.x2, shortenedSide1.y2) || p.contains(shortenedSide2.x1, shortenedSide2.y1) || p.contains(shortenedSide2.x2, shortenedSide2.y2))) return; //bridge intersects some other polygon, don't make it } Polygon aPart = new Polygon(); //side touching a aPart.addPoint((int)(line.x1 + 20*Math.cos(ang)), (int)(line.y1 + 20*Math.sin(ang))); aPart.addPoint((int)(line.x1 - 20*Math.cos(ang)), (int)(line.y1 - 20*Math.sin(ang))); aPart.addPoint((int)(midX - 20*Math.cos(ang)), (int)(midY - 20*Math.sin(ang))); aPart.addPoint((int)(midX + 20*Math.cos(ang)), (int)(midY + 20*Math.sin(ang))); Polygon bPart = new Polygon(); //side touching b bPart.addPoint((int)(midX - 20*Math.cos(ang)), (int)(midY - 20*Math.sin(ang))); bPart.addPoint((int)(midX + 20*Math.cos(ang)), (int)(midY + 20*Math.sin(ang))); bPart.addPoint((int)(line.x2 + 20*Math.cos(ang)), (int)(line.y2 + 20*Math.sin(ang))); bPart.addPoint((int)(line.x2 - 20*Math.cos(ang)), (int)(line.y2 - 20*Math.sin(ang))); //draw brown railings on the bridges foreG.setColor(new Color(139, 69, 19).darker()); //brown foreG.setStroke(new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)); Point[] postBases1 = new Point[5]; Point[] postBases2 = new Point[5]; for(int i = 0; i < 3; i += 1) { postBases1[i] = new Point((int)(aPart.xpoints[0] + i*(line.x2-line.x1)/2), (int)(aPart.ypoints[0] + i*(line.y2-line.y1)/2)); postBases2[i] = new Point((int)(aPart.xpoints[1] + i*(line.x2-line.x1)/2), (int)(aPart.ypoints[1] + i*(line.y2-line.y1)/2)); foreG.drawLine(postBases1[i].x, height-postBases1[i].y, postBases1[i].x, height-(postBases1[i].y + 15)); foreG.drawLine(postBases2[i].x, height-postBases2[i].y, postBases2[i].x, height-(postBases2[i].y + 15)); } foreG.drawLine(postBases1[0].x, height-(postBases1[0].y+7), postBases1[1].x, height-(postBases1[1].y + 15)); foreG.drawLine(postBases1[2].x, height-(postBases1[2].y+7), postBases1[1].x, height-(postBases1[1].y + 15)); foreG.drawLine(postBases2[0].x, height-(postBases2[0].y+7), postBases2[1].x, height-(postBases2[1].y + 15)); foreG.drawLine(postBases2[2].x, height-(postBases2[2].y+7), postBases2[1].x, height-(postBases2[1].y + 15)); //add the polygons and connections bridgePolygons.add(aPart); bridgePolygons.add(bPart); Vector aConns = new Vector(), bConns = new Vector(); aConns.add(a); aConns.add(bPart); bConns.add(b); bConns.add(aPart); bridgeConnections.add(aConns); bridgeConnections.add(bConns); ((Vector)connections.get(countryPolygons.indexOf(a))).add(aPart); ((Vector)connections.get(countryPolygons.indexOf(b))).add(bPart); } //output the xml of all countryside hexagon continents private void writeHexagons() { //for each castle, write the hexagons it owns //bonus = borders-1 boolean[] taken = new boolean[countryPolygons.size()]; for(int i = 0; i < taken.length; i += 1) taken[i] = false; for(int c = 0; c < numCastles; c += 1) { Point center = polygonCenter(castleCenters[c]); out.write("<continent>\n" + " <continentname>" + countrysideNames[c] + "</continentname>\n" + " <labellocation>" + center.x + "," + (center.y-40) + "</labellocation>\n"); int numBorders = 0; loop: for(int i = 0; i < countryPolygons.size(); i += 1) { //write out each country if(taken[i] || closestCastle((Polygon)countryPolygons.get(i)) != c) { continue loop; } taken[i] = true; out.write(" <country>\n" + " <id>" + i + "</id>\n" + " <name>" + makeHexagonName() + "</name>\n"); Vector integerConnections = new Vector(); boolean border = false; for(int j = 0; j < ((Vector)connections.get(i)).size(); j += 1) { if(allPolygons.contains(((Vector)connections.get(i)).get(j)) && (closestCastle((Polygon)((Vector)connections.get(i)).get(j)) != c || bridgePolygons.contains(((Vector)connections.get(i)).get(j)))) border = true; int index = allPolygons.indexOf(((Vector)connections.get(i)).get(j)); if(index != -1) { integerConnections.add(new Integer(index)); } } if(border) { numBorders += 1; } writeConnections(integerConnections); writePolygon((Polygon)countryPolygons.get(i)); out.write(" </country>\n"); } out.write("<bonus>" + Math.round(Math.min(numBorders-1, 6)) + "</bonus>\n"); out.write("</continent>\n"); } } //write the xml for the castles //bonus = 6 private void writeCastles() { for(int c = 0; c < numCastles; c += 1) { Point center = polygonCenter(castleCenters[c]); out.write("<continent>\n" + " <continentname>" + castleNames[c] + "</continentname>\n" + " <bonus>" + 6 + "</bonus>\n" + " <labellocation>" + center.x + "," + (center.y+20) + "</labellocation>\n"); for(int i = 0; i < 4; i += 1) { //put army location in a good spot int centerx = (int)(polygonCenter(castleCenters[c]).x + (cIR + cOR)/2*Math.sqrt(2)*Math.cos(Math.PI/4 + Math.PI/2*i)); int centery = (int)(polygonCenter(castleCenters[c]).y + (cIR + cOR)/2*Math.sqrt(2)*Math.sin(Math.PI/4 + Math.PI/2*i)); out.write(" <country>\n" + " <id>" + (countryPolygons.size() + c*4 + i) + "</id>\n" + " <name>" + makeWallName(i) + "</name>\n" + " <armylocation>" + centerx + "," + centery + "</armylocation>\n"); Vector integerConnections = new Vector(); for(int j = 0; j < castleConnections[c][i].size(); j += 1) { int index = allPolygons.indexOf(castleConnections[c][i].get(j)); if(index != -1) { integerConnections.add(new Integer(index)); } } writeConnections(integerConnections); writePolygon(castles[c][i]); out.write(" </country>\n"); } out.write("</continent>\n"); } } //write the xml for the bridges private void writeBridges() { for(int i = 0; i < bridgePolygons.size(); i += 2) { //write out each country out.write("<continent>\n" + " <continentname>Bridge</continentname>\n" + " <bonus>" + -2 + "</bonus>\n"); for(int j = 0; j < 2; j += 1) { //two halves per bridge out.write(" <country>\n" + " <id>" + (countryPolygons.size() + numCastles*4 + i+j) + "</id>\n" + " <name>Bridge</name>\n"); Vector integerConnections = new Vector(); for(int k = 0; k < ((Vector)bridgeConnections.get(i+j)).size(); k += 1) { int index = allPolygons.indexOf(((Vector)bridgeConnections.get(i+j)).get(k)); if(index != -1) { integerConnections.add(new Integer(index)); } } writeConnections(integerConnections); writePolygon((Polygon)bridgePolygons.get(i+j)); out.write(" </country>\n"); } out.write("</continent>\n"); } } //finish off the theme and write it to a folder private void doTheme() { //draw castle images inside castles for(int i = 0; i < numCastles; i += 1) { drawCastleAt(polygonCenter(castleCenters[i])); } //draw houses & churches dotting the countryside drawCountrysideDecorations(); backG.setColor(Color.black); backG.setStroke(new BasicStroke(1)); backG.drawLine(0, 0, 0, height-1); backG.drawLine(1, 0, 1, height-1); backG.drawLine(width-1, 0, width-1, height); backG.drawLine(width-2, 0, width-2, height); backG.drawLine(width-3, 0, width-3, height); //now handle the file stuff try { //first delete any old theme directories File support = new File(new File(m.getMapGeneratorPath()).getParent()); File[] supportChildren = support.listFiles(); File themes = null; for(int i = 0; i < supportChildren.length; i += 1) { if(supportChildren[i].getName().toLowerCase().equals("themes")) { themes = supportChildren[i]; } } File[] themesChildren = themes.listFiles(); for(int i = 0; i < themesChildren.length; i += 1) { if(themesChildren[i].getName().indexOf("CastleInfinity") != -1) { File[] oldThemeFiles = themesChildren[i].listFiles(); for(int j = 0; j < oldThemeFiles.length; j += 1) { oldThemeFiles[j].delete(); } themesChildren[i].delete(); } } //then write one for this map new File(themes.getPath() + File.separator + choice + seed).mkdir(); ImageIO.write(background, "png", new File(themes + File.separator + choice+seed + File.separator + "background.png")); ImageIO.write(foreground, "png", new File(themes + File.separator + choice+seed + File.separator + "overground.png")); } catch(Exception e) { debug(e.toString()); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -