我正在为2D迷宫游戏创建Web API。我有一个带有两个Get方法的服务 - 一个用于检索所有单元格,另一个用于检索特定单元格详细信息(带有下一个可能的移动链接)。
将按以下格式为请求http://localhost:51910/api/cells检索单元格列表。
<Cell>
<BottomIsWall>true</BottomIsWall>
<IsExtCell>false</IsExtCell>
<IsStartCell>false</IsStartCell>
<LeftIsWall>true</LeftIsWall>
<RelativeName>Self</RelativeName>
<RightIsWall>false</RightIsWall>
<TopIsWall>false</TopIsWall>
<XVal>0</XVal>
<YVal>0</YVal>
</Cell>
<Cell>
<BottomIsWall>false</BottomIsWall>
<IsExtCell>false</IsExtCell>
<IsStartCell>true</IsStartCell>
<LeftIsWall>false</LeftIsWall>
<RelativeName>Self</RelativeName>
<RightIsWall>false</RightIsWall>
<TopIsWall>true</TopIsWall>
<XVal>1</XVal>
<YVal>0</YVal>
</Cell>
特定小区请求的响应如下(对于请求http://localhost:51910/api/cells/21,当使用接受标头application/hal+xml
时)。如果允许在该方向上进行导航,则会添加链接(向上,向右,向下和向左)。
<?xml version="1.0" encoding="utf-8"?>
<resource rel="self" href="~/api/cells/21">
<link rel="down" href="~/api/cells/20" />
<link rel="left" href="~/api/cells/11" />
<link rel="up" href="~/api/cells/22" />
</resource>
用户可以单击可用链接以导航到下一个单元格。在每个响应中,我需要在2D
笛卡尔图中显示所有单元格,用户当前位置。我搜索了有助于显示单元格(带门/墙)的代码 - 但我找不到一个。
我发现很多教程都有代码和算法来生成迷宫。我不必生成迷宫。我已经定义并提供了迷宫。我需要绘制它以供用户查看。
实现此显示的最简单方法是什么?
注意:我需要根据服务返回的单元格使用javascript应用css样式。它可以是任何4X4迷宫。
答案 0 :(得分:1)
看起来有点蹩脚,但这与未优化的选择ad-hoc spritemap有很大关系。您应该能够根据数据为单元格分配类。当然,包含结构可以很容易地成为div。
<强>更新强> 我更新了这个答案,以驱逐所提供的数据。
有很多方法可以优化这一点,这只是快速而肮脏的事情,为您提供前进的方法。
例如,根据您的数据结构,使用xpath可能与将xml转换为JSON一样简单。此外,人们可能会在房间墙壁顶部对门图像进行z索引,而不是像我一样挑选出16个房间中的一个。
// --------------------------------
// Maze data from service.
// --------------------------------
var xmlString = "<root><Cell><BottomIsWall>true</BottomIsWall><IsExtCell>false</IsExtCell><IsStartCell>false</IsStartCell><LeftIsWall>true</LeftIsWall><RelativeName>Self</RelativeName><RightIsWall>false</RightIsWall><TopIsWall>false</TopIsWall><XVal>0</XVal><YVal>0</YVal></Cell><Cell><BottomIsWall>false</BottomIsWall><IsExtCell>false</IsExtCell><IsStartCell>true</IsStartCell><LeftIsWall>false</LeftIsWall><RelativeName>Self</RelativeName><RightIsWall>false</RightIsWall><TopIsWall>true</TopIsWall><XVal>1</XVal><YVal>0</YVal></Cell></root>";
// --------------------------------
// --------------------------------
// Convert the XML text to JSON
// --------------------------------
var data = (function(xmlString){
// --------------------------------
// Changes XML to JSON
// see: https://davidwalsh.name/convert-xml-json
// --------------------------------
function xmlToJson(xml) {
// Create the return object
var obj = {};
if (xml.nodeType == 1) { // element
// do attributes
if (xml.attributes.length > 0) {
obj["@attributes"] = {};
for (var j = 0; j < xml.attributes.length; j++) {
var attribute = xml.attributes.item(j);
obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
}
}
} else if (xml.nodeType == 3) { // text
obj = xml.nodeValue;
}
// do children
if (xml.hasChildNodes()) {
for(var i = 0; i < xml.childNodes.length; i++) {
var item = xml.childNodes.item(i);
var nodeName = item.nodeName;
if (typeof(obj[nodeName]) == "undefined") {
obj[nodeName] = xmlToJson(item);
} else {
if (typeof(obj[nodeName].push) == "undefined") {
var old = obj[nodeName];
obj[nodeName] = [];
obj[nodeName].push(old);
}
obj[nodeName].push(xmlToJson(item));
}
}
}
return obj;
};
// --------------------------------
var _parser = new window.DOMParser();
var xmlData = _parser.parseFromString(xmlString, "text/xml");
return xmlToJson(xmlData);
})(xmlString);
// --------------------------------
// --------------------------------
// For each TD in the maze, find the service data and
// set the room look.
// --------------------------------
Array.from(document.querySelectorAll("tr")).forEach(function(row, rowIndex){
Array.from(row.querySelectorAll("td")).forEach(function(col, colIndex){
// ---------------------
// Find the data element for this cell
// ---------------------
var cellData = data.root.Cell.filter(function(data){
var isRowMatch = data.YVal["#text"] == (3 - rowIndex);
var isColMatch = data.XVal["#text"] == colIndex;
return (isRowMatch && isColMatch);
});
// ---------------------
var cellType = "cell-00";
var cellRotation = "cell-south";
// ---------------------
// if there is some issue with the data set the cell to the void
// ---------------------
if(cellData.length !== 1) {
col.classList.add(cellType);
col.classList.add(cellRotation);
return;
}
// ---------------------
// ---------------------
// Where are the doors?
// ---------------------
var isDoor_North = cellData[0].TopIsWall["#text"] === "false";
var isDoor_East = cellData[0].RightIsWall["#text"] === "false";
var isDoor_South = cellData[0].BottomIsWall["#text"] === "false";
var isDoor_West = cellData[0].LeftIsWall["#text"] === "false";
// ---------------------
// ---------------------
// Determine the classes based on where the doors are
// ---------------------
switch(true) {
case (isDoor_North && isDoor_East && isDoor_South && isDoor_West):
break;
case (isDoor_North && isDoor_East && isDoor_South && !isDoor_West):
break;
case (isDoor_North && isDoor_East && !isDoor_South && isDoor_West):
break;
case (isDoor_North && isDoor_East && !isDoor_South && !isDoor_West):
cellType = "cell-03";
cellRotation = "cell-west";
break;
case (isDoor_North && !isDoor_East && isDoor_South && isDoor_West):
break;
case (isDoor_North && !isDoor_East && isDoor_South && !isDoor_West):
break;
case (isDoor_North && !isDoor_East && !isDoor_South && isDoor_West):
break;
case (isDoor_North && !isDoor_East && !isDoor_South && !isDoor_West):
break;
case (!isDoor_North && isDoor_East && isDoor_South && isDoor_West):
cellType = "cell-04";
cellRotation = "cell-east";
break;
case (!isDoor_North && isDoor_East && isDoor_South && !isDoor_West):
break;
case (!isDoor_North && isDoor_East && !isDoor_South && isDoor_West):
break;
case (!isDoor_North && isDoor_East && !isDoor_South && !isDoor_West):
break;
case (!isDoor_North && !isDoor_East && isDoor_South && isDoor_West):
break;
case (!isDoor_North && !isDoor_East && isDoor_South && !isDoor_West):
break;
case (!isDoor_North && !isDoor_East && !isDoor_South && isDoor_West):
break;
case (!isDoor_North && !isDoor_East && !isDoor_South && !isDoor_West):
break;
}
// ---------------------
// ---------------------
// Assign the proper classes based on our data.
// ---------------------
col.classList.add(cellType);
col.classList.add(cellRotation);
// ---------------------
});
});
// ---------------------
&#13;
.cell {
height: 36px;
width: 36px;
padding: 0;
margin: 0;
border: 0;
background-repeat: no-repeat;
background-image: url(http://img.photobucket.com/albums/v323/ShadowDragon8685/KestralDefiant_zps88896fb8.png);
}
.cell-00 { background-position: -0px -15px; }
.cell-01 { background-position: -115px -138px; }
.cell-02 { background-position: -44px -173px; }
.cell-03 { background-position: -254px -103px; }
.cell-04 { background-position: -254px -278px; }
.cell-north { transform: rotate(180deg); }
.cell-east { transform: rotate(90deg); }
.cell-south { transform: rotate(0deg); }
.cell-west { transform: rotate(270deg); }
&#13;
<table style="border-collapse: collapse">
<tr><td class="cell"></td><td class="cell"></td><td class="cell"></td><td class="cell"></td></tr>
<tr><td class="cell"></td><td class="cell"></td><td class="cell"></td><td class="cell"></td></tr>
<tr><td class="cell"></td><td class="cell"></td><td class="cell"></td><td class="cell"></td></tr>
<tr><td class="cell"></td><td class="cell"></td><td class="cell"></td><td class="cell"></td></tr>
</table>
&#13;