这个问题与我上一个关于MMO服务器的问题有关。
在这里,我使用这个程序所做的是连接到另一个与MMO服务器位于同一服务器上的Java服务器程序。一旦连接,它将接收包含MMO服务器的所有播放器数据以及所有区域数据的有效负载。这是大约15兆字节的数据,每小时左右传输一次。
使用这些数据,我创建了一个简单的网页。我将在这个问题上发布的是用来生成页面的代码。我知道我做错了很多事情,所以希望我能有很多的批评和提高。
分析区域数据,然后基于该数据创建网页上地图的图像。
下面是一个链接,链接到实时网页:
世界地图
public class RegionWebsiteGenerator {
private Map<MapPoint, String> regionMap = new HashMap<MapPoint, String>();
private Map<String, Integer> regionOwners = new HashMap<String, Integer>();
private Map<String, Integer> topOwnersAndRanks = new HashMap<String, Integer>();
private int regionWidth = 12;
private int numRegions = 60; //need to know this number ahead of time
public RegionWebsiteGenerator() {
this.loadRegions();
this.countOwnersForRegions(this.regionMap);
this.populateTopOwners(this.regionOwners);
this.createMapImageForRegions(this.regionMap);
}
//load and parse data
private void loadRegions() {
File dir = new File("regions");
File[] directoryListing = dir.listFiles();
if (directoryListing != null) {
for (File child : directoryListing) {
//validation
String fileName = child.getName();
String delims = ","; //separator for map point
String[] points = fileName.split(delims);
if (points.length > 0) {
try {
MapPoint point = new MapPoint(Integer.parseInt(points[0]), Integer.parseInt(points[1]));
//read the valid file
if (point != null) {
BufferedReader br = new BufferedReader(new FileReader(child));
@SuppressWarnings("unused")
String firstLine = br.readLine();
String secondLine = br.readLine(); //second line is the region data
this.regionMap.put(point, secondLine);
br.close();
}
} catch (Exception e) {
System.out.println("file is not a region");
}
}
}
}
}
private void countOwnersForRegions(Map<MapPoint, String>regions) {
for (String regionString : regions.values()) {
String ownerName = this.getOwnerNameForRegion(regionString);
if (this.regionOwners.containsKey(ownerName)) {
int currentCount = this.regionOwners.get(ownerName);
this.regionOwners.put(ownerName, currentCount++);
} else {
this.regionOwners.put(ownerName, 1);
}
}
}
private void populateTopOwners(Map<String, Integer>regionOwners) {
Set<Entry<String, Integer>> entries = PlayerWebsiteGenerator.entriesSortedByValues(regionOwners);
Object[] entriesArray = entries.toArray();
int maxCount = Math.min(entriesArray.length, 10);
for (int i = 0; i < maxCount; i++) {
@SuppressWarnings("rawtypes")
Entry entry = (Entry)entriesArray[i];
String name = (String)entry.getKey();
if (!name.equals("^")) {
this.topOwnersAndRanks.put((String)entry.getKey(), i);
}
}
}
//output the html
public void generatePage() {
String filePath = "../www/site1/stats/regions.html";
File regionHTMLFile = new File(filePath);
try {
regionHTMLFile.createNewFile();
BufferedWriter output;
try {
output = new BufferedWriter(new FileWriter(regionHTMLFile));
output.write("<!doctype html>");
output.newLine();
output.write("<html>");
output.newLine();
output.write("<link rel=\"stylesheet\" type=\"text/css\" href=\"regions.css\" media=\"screen\" />");
output.newLine();
output.write("<head>");
output.newLine();
output.write("</head>");
output.newLine();
output.write("<body onload=\"javascript:scrollWin()\">");
output.newLine();
output.write("<div id=\"title\">");
output.newLine();
output.write("<p>Live Region Map</p>");
output.newLine();
output.write("</div>");
output.newLine();
output.write("<div id=\"map\">");
output.newLine();
output.write("<img src=\"regions.png\" alt=\"Map\">"); //style=\"width:1800px;height:1800px\"
output.newLine();
output.write("</div>");
output.newLine();
output.write("<div id=\"legend\">");
output.newLine();
output.write("<p>Region Owners</p>");
output.newLine();
output.write("<p>Legend</p>");
output.newLine();
this.writeLegendToHTML(output);
output.write("</div>");
output.newLine();
output.write("<script>");
output.newLine();
output.write("function scrollWin() {");
output.newLine();
output.write("window.scrollTo(window.outerHeight/2, window.outerWidth/2);");
output.newLine();
output.write("}");
output.newLine();
output.write("</script>");
output.newLine();
output.write("</body>");
output.newLine();
output.write("</html>");
output.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void writeLegendToHTML(BufferedWriter output) throws IOException {
int currentRank = 0;
for (String string : this.topOwnersAndRanks.keySet()) {
output.write("<div id=\"rank" + String.valueOf(currentRank) + "\">");
output.newLine();
output.write("<p>" + string + "</p>");
output.newLine();
output.write("</div>");
output.newLine();
currentRank++;
}
}
//generate the map image
private void createMapImageForRegions(Map<MapPoint, String>regions) {
BufferedImage img = new BufferedImage(numRegions*regionWidth, numRegions*regionWidth, BufferedImage.TYPE_INT_RGB);
for (MapPoint point : regions.keySet()) {
int i = point.x * regionWidth;
int j = (59 - point.y) * regionWidth; //flip the image because it draws starting top left
String ownerName = this.getOwnerNameForRegion(regions.get(point));
Color color = new Color(this.getColorForBiomeType(this.getBiomeTypeForRegion(regions.get(point))));
if (this.topOwnersAndRanks.containsKey(ownerName)) {
color = new Color(this.getColorForRank(this.topOwnersAndRanks.get(ownerName)));
}
Graphics graphics = img.getGraphics();
graphics.setColor(color);
graphics.drawRect(i, j, regionWidth, regionWidth);
graphics.fillRect(i, j, regionWidth, regionWidth);
}
File imageFile = new File("../www/site1/stats/regions.png");
try {
ImageIO.write(img, "PNG", imageFile);
} catch (IOException e) {
System.out.println("failed to write image");
}
}
private int getColorForRank(int rank) {
int r = 0;
int g = 0;
int b = 0;
int a = 255;
switch (rank) {
case 0:
//gold
r = 204;
g = 204;
b = 0;
break;
case 1:
//Dark magenta
r = 153;
g = 0;
b = 76;
break;
case 2:
//dark red
r = 153;
g = 0;
b = 0;
break;
case 3:
//light blue
r = 153;
g = 255;
b = 255;
break;
case 4:
//pink
r = 255;
g = 204;
b = 204;
break;
case 5:
//light gray
r = 224;
g = 224;
b = 224;
break;
case 6:
//dark gray
r = 64;
g = 64;
b = 64;
break;
case 7:
//dark blue
r = 0;
g = 0;
b = 102;
break;
case 8:
//dark purple
r = 51;
g = 0;
b = 102;
break;
case 9:
//light purple
r = 153;
g = 153;
b = 255;
break;
default:
//will be black
break;
}
//color is created by this bit shifting trick
return (a << 24) | (r << 16) | (g << 8) | b;
}
private int getColorForBiomeType(int biomeType) {
int r = 0;
int g = 0;
int b = 0;
int a = 255;
if (biomeType == 0) {
//woodlands
r = 52;
g = 108;
b = 0;
} else if (biomeType == 1) {
//mountains
r = 102;
g = 51;
b = 0;
} else if (biomeType == 2) {
//plains
r = 0;
g = 255;
b = 0;
} else if (biomeType == 3) {
//wasteland
r = 255;
g = 153;
b = 51;
} else if (biomeType == 4) {
//swampy
r = 0;
g = 153;
b = 76;
} else if (biomeType == 5) {
//aquatic
r = 0;
g = 128;
b = 255;
}
//color is created by this bit shifting trick
return (a << 24) | (r << 16) | (g << 8) | b;
}
//get the necessary information using the pattern found in deserialization method below
private int getBiomeTypeForRegion(String region) {
String delims = DelimiterType.TOP_LEVEL.string;
String[] messageFragments = region.split(delims);
return Integer.parseInt(messageFragments[0]);
}
private String getOwnerNameForRegion(String region) {
String delims = DelimiterType.TOP_LEVEL.string;
String[] messageFragments = region.split(delims);
return messageFragments[4];
}
/*
public static Region decodeRegionFromString(String string) {
String delims = DelimiterType.TOP_LEVEL.string;
String[] messageFragments = string.split(delims);
int biomeType = Integer.parseInt(messageFragments[0]);
Region region = new Region(BiomeType.values()[biomeType], new MapPoint(Integer.parseInt(messageFragments[1]), Integer.parseInt(messageFragments[2])));
region.name = messageFragments[3];
region.setOwnerName(messageFragments[4]);
int numTiles = Integer.parseInt(messageFragments[5]);
int messageIndex = 6;
for (int i = 0; i < numTiles; i++) {
int tileType = Integer.parseInt(messageFragments[messageIndex]);
messageIndex++;
if (tileType == TileType.CAPITAL.ordinal()) {
TileCapital tile = TileCapital.decodeTileFromString(messageFragments[messageIndex]);
messageIndex++;
region.setTileForPosition(tile.position(), tile);
} else {
Tile tile = Tile.decodeTileFromString(TileType.values()[tileType], messageFragments[messageIndex]);
messageIndex++;
region.setTileForPosition(tile.position(), tile);
}
}
return region;
}
*/
//DO NOT DELETE COMMENTED METHOD
}下面是生成的HTML文件:
<!doctype html>
<html>
<link rel="stylesheet" type="text/css" href="regions.css" media="screen" />
<head>
</head>
<body onload="javascript:scrollWin()">
<div id="title">
<p>Live Region Map</p>
</div>
<div id="map">
<img src="regions.png" alt="Map">
</div>
<div id="legend">
<p>Region Owners</p>
<p>Legend</p>
<div id="rank0">
<p>Name14</p>
</div>
</div>
<script>
function scrollWin() {
window.scrollTo(window.outerHeight/2, window.outerWidth/2);
}
</script>
</body>
</html>下面是CSS文件,该文件目前从未更改过:
body {
background-color:black;
}
#title {
font-size: 40pt;
color: white;
text-align: center;
border:5px solid white;
}
#map {
text-align: center;
}
#legend {
border: 5px solid white;
text-align: center;
font-size: 30pt;
color: white;
}
#rank0 {
text-align: center;
background-color: rgb(204, 204, 0);
}
#rank1 {
text-align: center;
background-color: rgb(153, 0, 76);
}
#rank2 {
text-align: center;
background-color: rgb(153, 0, 0);
}
#rank3 {
text-align: center;
background-color: rgb(153, 255, 255);
}
#rank4 {
text-align: center;
background-color: rgb(255, 204, 204);
}
#rank5 {
text-align: center;
background-color: rgb(224, 224, 224);
}
#rank6 {
text-align: center;
background-color: rgb(64, 64, 64);
}
#rank7 {
text-align: center;
background-color: rgb(0, 0, 102);
}
#rank8 {
text-align: center;
background-color: rgb(51, 0, 102);
}
#rank9 {
text-align: center;
background-color: rgb(153, 153, 255);
}我对HTML和CSS知之甚少,所以对它们的任何评论也将不胜感激。
发布于 2015-05-08 21:40:06
专用int getColorForRank(int秩){ int r= 0;int g= 0;int b= 0;int a= 255;开关(秩){ case 0: /gold= 204;g= 204;b= 0;例1: //暗品红r= 153;g= 0;b= 76;断裂;例2: //暗红r= 153;g= 0;b= 0;例3: //淡蓝色r= 153;g= 255;b= 255;断裂;例4: //粉红色r= 255;g= 204;B= 204;断裂;例5: //浅灰r= 224;g= 224;b= 224;断裂;例6: //深灰色r= 64;G= 64;b= 64;断裂;例7: //深蓝色r= 0;g= 0;b= 102;断裂;例8: //暗紫色r= 51;g= 0;b= 102;断裂;例9: //浅紫色r= 153;g= 153;b= 255;分隔符;默认值://将是黑色断线;}//颜色是通过此位移位技巧返回(a << 24) \x (r << 16) \ (g << 8) \ b;}创建的。
我会像这样定义Enum Color:
public enum Color {
GOLD(204,204,0);
private int r = 0;
private int g = 0;
private int b = 0;
private int a = 255;
private Color(int r, int g, int b) {
this.r = r;
this.g = g;
this.b = b;
}
public int color() {
return (a << 24) | (r << 16) | (g << 8) | b;
}
}现在,你唯一需要做的就是构造一个颜色的Map,你只需要做一些像mapOfColors.get(1).color()和瞧!你可以对你拥有的每一种颜色(生物群落等等)进行反复练习和重复。
大多数情况下,@Suprresswarnigns是一种代码气味。通常,你可以做一些事情来避免手头的问题,或者它警告你,你在做坏事!让我们来看看你的问题:
@SuppressWarnings("unused") String firstLine = br.readLine();
这是警告您不要使用firstLine。如果您不需要它,为什么要创建一个变量并分配它。您知道可以忽略返回的值。
br.readLine();//skip the first line你用手做的事情可以很容易地通过使用像速度这样的模板引擎来完成,或者在一个webapp中转换。它将简化generatePage(),因为您将使用所需的所有信息构造模型变量,并只发布页面。
为一个页面编写一个小型的Java web应用程序看起来有点过分了,但我相信你将来会添加一些页面,我希望到那时你不会通过做你目前正在做的事情来生成所有的页面。
private int regionWidth = 12;这是一个常数,所以应该是:
private final static int REGION_WIDTH = 12;//不删除注释方法
注释的方法只是你的课堂上的噪音。我希望您使用的是源代码管理,如果您确实删除了该代码,并做了一个标记来记住在哪里可以找到它,但就目前的情况而言,它根本没有用。
发布于 2015-05-08 17:52:41
Java中的
我对Java一无所知,但是像print语句这样硬编码的静态标记的数量给我带来了危险。没有读取您可以使用的文件内容的函数吗?这似乎会使您以后修改模板时更容易进行修改。
在页面标题中使用以下标记:
<div id="title">
<p>Live Region Map</p>
</div>您应该使用的是h1 (标题):
<h1>Live Region Map</h1>你的传奇真的需要两行文字吗?简化(并使用适当的标记):
<h2>Region Owners</h2>业主本身应列明:
<ul class="legend">
<li>baz</li>
<li>Krepi</li>
</ul>我认为这里根本没有必要使用I。您不能将它们用作JavaScript的钩子。如果您不确定是否应该使用类或id,请与类一起使用。
对于您的传奇,您是指定文本-对齐10次!只要一次就可以了(使用上面的标记):
.legend li {
text-align: center;
}通常,我会建议任何使用行样式的人将这些信息放在外部样式表中。但是,对于像这样动态生成的内容,特别是当您重用相同的信息来生成映像时,最好将其定位(在Java中)并使用内联样式。
<ul class="legend">
<li style="background-color: rgb(204, 204, 0)">baz</li>
<li style="background-color: rgb(153, 0, 0)">Krepi</li>
</ul>如果您没有在两个地方重用这些信息,我建议您使用:nth-child而不是一个类(或id):
.legend li:nth-child(1) {
background-color: rgb(204, 204, 0);
}
.legend li:nth-child(2) {
background-color: rgb(153, 0, 76);
}
.legend li:nth-child(3) {
background-color: rgb(153, 0, 0);
}
.legend li:nth-child(4) {
background-color: rgb(153, 255, 255);
}
.legend li:nth-child(5) {
background-color: rgb(255, 204, 204);
}
.legend li:nth-child(6) {
background-color: rgb(224, 224, 224);
}
.legend li:nth-child(7) {
background-color: rgb(64, 64, 64);
}
.legend li:nth-child(8) {
background-color: rgb(0, 0, 102);
}
.legend li:nth-child(9) {
background-color: rgb(51, 0, 102);
}
.legend li:nth-child(10) {
background-color: rgb(153, 153, 255);
}https://codereview.stackexchange.com/questions/90186
复制相似问题