Jos*_*shK 9 html javascript css
我正在制作名为Dots and Boxes的游戏.
网格上有一堆点:

<table>
<tr>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
</tr>
<tr>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
</tr>
</table>
Run Code Online (Sandbox Code Playgroud)
单击框的一侧时,它变为黑色:

function addLine(obj) {
console.log("Called")
if (obj.style.backgroundColor != "black") {
obj.style.backgroundColor = "black";
changeTurn()
}
Run Code Online (Sandbox Code Playgroud)
一旦你点击第四面,关闭框,该框将改变点击第四面的玩家的颜色:

目前,玩家必须手动点击该框以改变其颜色.但是,当盒子周围的四个边都是黑色的时候,我希望它能自动用颜色填充盒子.
如何在Javascript中使用函数来检查框的上方,下方,左侧和右侧的行是否填充为黑色?
var playerTurn = "Blue";
changeTurn();
var number = 0;
function addLine(obj) {
console.log("Called")
if (obj.style.backgroundColor != "black") {
obj.style.backgroundColor = "black";
changeTurn()
}
}
function fillBox(obj) {
if (playerTurn == "Blue") {
obj.style.backgroundColor = "red";
}
else if ( playerTurn == "Red") {
obj.style.backgroundColor = "blue";
}
}
function changeTurn() {
if (playerTurn == "Red") {
playerTurn = "Blue";
document.getElementById('turn').style.color = "blue";
}
else if (playerTurn == "Blue") {
playerTurn = "Red";
document.getElementById('turn').style.color = "red";
};
console.log(playerTurn);
document.getElementById('turn').innerHTML = playerTurn + "'s Turn";
}Run Code Online (Sandbox Code Playgroud)
h3 {
font-family: Arial;
}
table {
border-collapse: collapse;
}
.vLine {
width: 10px;
height: 60px;
}
.box {
width: 60px;
height: 60px;
}
.hLine {
width: 60px;
height: 10px;
}
.gap {
width: 10px;
height: 12px;
background-color: black;
}
.vLine:hover, .hLine:hover {
background-color: black;
}Run Code Online (Sandbox Code Playgroud)
<h3 id="turn"></h3>
<table>
<tr>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
</tr>
<tr>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
</tr>
<tr>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
</tr>
<tr>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
</tr>
<tr>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
</tr>
<tr>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
</tr>
<tr>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
</tr>
<tr>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
</tr>
<tr>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
</tr>
<tr>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
</tr>
<tr>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
</tr>
<tr>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
<td class="box" onclick="fillBox(this)"></td>
<td class="vLine" onclick="addLine(this)"></td>
</tr>
<tr>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
<td class="hLine" onclick="addLine(this)"></td>
<td class="gap"></td>
</tr>
</table>Run Code Online (Sandbox Code Playgroud)
这相当简单,但需要很好地使用 DOM 遍历。
当您单击一条线时,最多只能填写两个可能的框。对于水平线,这些框是上方和下方的框,这需要跳行。对于垂直线,左和右。
对于每个框,我们需要确认四行。同样,我们必须为上面和下面的行跳行。
实际上,我已经重新创建了这款游戏的大部分内容,因为它很有趣,而且这里有很多东西需要学习。那么让我们来看看重要的部分。我们将避免此代码中的不良形式,例如内联处理程序和直接在元素上设置样式,并且我们将让 CSS 类充当控件,尽管更完整的选项是data-attributes.
让我们从两个基本的辅助函数开始。
第一个用于将类似数组的对象转换为实际的数组,因此我们可以对Array.prototype它们使用方法。我们主要在物体上使用它nodeList。
function toArray (o) {
return Array.prototype.slice.call(o);
}
Run Code Online (Sandbox Code Playgroud)
第二个利用第一个,并为我们提供元素在其 中的位置parentNode。
function nodeIndex (node) {
return toArray(node.parentNode.children).indexOf(node);
}
Run Code Online (Sandbox Code Playgroud)
接下来是我们的事件处理程序。他们彼此非常相似。当我们单击一行时,我们用另一个辅助函数 填充该行,fill该函数将一个新类添加到名为 的行中.filled。然后我们检查可以填写的框。对于水平线,是上面和下面的垂直框;对于垂直线,这是水平框,左侧和右侧。我们删除了事件监听器,因此线条只能单击一次。
function addHLine (e) {
fill(this);
this.removeEventListener(e.type, addHLine);
checkVerticalBoxes(this);
updateGame();
}
function addVLine (e) {
fill(this);
this.removeEventListener(e.type, addVLine);
checkHorizontalBoxes(this);
updateGame();
}
Run Code Online (Sandbox Code Playgroud)
现在让我们看看checkHorizontalBoxes和checkVerticalBoxes。水平框位于同一行,+/-1从起始行开始索引。垂直框位于+/-1从起始行开始索引的行中,并与该行共享相同的索引。我们有一些if声明,因为有时可能的行或框会出界。
function checkHorizontalBoxes (line) {
var left = line.previousElementSibling,
right = line.nextElementSibling;
if (left) checkSurroundingLines(left);
if (right) checkSurroundingLines(right);
}
function checkVerticalBoxes (line) {
var index = nodeIndex(line),
up = line.parentNode.previousElementSibling,
down = line.parentNode.nextElementSibling;
if (up) checkSurroundingLines(up.children[index]);
if (down) checkSurroundingLines(down.children[index]);
}
Run Code Online (Sandbox Code Playgroud)
这两个函数都会调用checkSurroundingLines潜在的盒子。该函数调用另外两个函数 -checkVerticalLines和checkHorizontalLines。开始看到规律了吗?isFilled与 类似fill,它是我们定义的一个辅助函数,用于测试一行是否具有该类.filled。
function checkHorizontalLines (node, idx) {
var left = node.previousElementSibling,
right = node.nextElementSibling;
return isFilled(left) && isFilled(right);
}
function checkVerticalLines (node, idx) {
var row = node.parentNode,
up = row.previousElementSibling.children[idx],
down = row.nextElementSibling.children[idx];
return isFilled(up) && isFilled(down);
}
Run Code Online (Sandbox Code Playgroud)
如果这两个都返回,true我们将填写我们的框。
这是这种 DOM 遍历逻辑的基本概述。实际代码中有一些额外的内容,因此请阅读所有部分。
这是工作游戏:
function toArray (o) {
return Array.prototype.slice.call(o);
}
Run Code Online (Sandbox Code Playgroud)
function nodeIndex (node) {
return toArray(node.parentNode.children).indexOf(node);
}
Run Code Online (Sandbox Code Playgroud)
function addHLine (e) {
fill(this);
this.removeEventListener(e.type, addHLine);
checkVerticalBoxes(this);
updateGame();
}
function addVLine (e) {
fill(this);
this.removeEventListener(e.type, addVLine);
checkHorizontalBoxes(this);
updateGame();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
758 次 |
| 最近记录: |