使用Javascript创建水果狂热游戏
在这个教学练习中,你将学习如何制作一个以水果为主题的经典街机游戏(水果忍者)的版本。主要目的是看看你对javaScript的专业程度能有多大的创造性。
前提条件
在我们开始制作游戏本身之前,我们应该了解一些将用于实现我们项目目标的方法。
这些方法包括。
addEventListener()setAttribute()setTimeout()setInterval()createElement()appendChild()every()includes()
水果狂热游戏
首先,创建三个文件,即。
index.htmlstyle.cssapp.js
index.html
我们的目标是用这个文件创建一个scoreboard ,它将记录我们的进度,同时也是一个网格,我们所有的糖果将被放置在这里。
在你的html 文件中,粘贴如下所示的代码。
<div class="score-board">
<h3>score</h3>
<h1 id="score"></h1>
</div>
<div class="grid"></div>
style.css
由于主要目的是了解游戏的逻辑,我们不会花太多时间在样式设计上。
我们将只有一些基本的样式,你可以根据你的愿望添加更多的样式。
移除令人厌恶的默认边距和填充,如下面的例子所示。
* {
margin: 0;
padding: 0;
}
对于正文,我们要确保内容公平地分散在可用的区域内,因此我们将对正文进行如下样式设计。
body {
display: flex;
justify-content: space-evenly;
align-items: center;
font-family: "Trebuchet MS", "Lucida Sans Unicode", "Lucida Grande",
"Lucida Sans", Arial, sans-serif;
}
我们将能够在这个grid 盒子里储存我们的糖果。我们将有以下的样式来使它更吸引人。
.grid {
margin-top: 34px;
height: 560px;
width: 560px;
display: flex;
flex-wrap: wrap;
}
.grid div {
height: 70px;
width: 70px;
}
app.js
首先,我们有一个名为DOMContentLoaded 的事件监听器作为我们模板设置的一部分,这只是在屏幕上显示HTML元素时检查我们的脚本文件是否被加载。
document.addEventListener("DOMContentLoaded", () => {});
这个事件监听器将是我们所有的javascript代码的容器。
下一步是设计一个宽为8 英寸的板子,为我们提供70 小格子,这将是储存糖果的理想选择。
为此,建立一个名为'createBoard()'的函数,它看起来就像下面所示。
// create Board
let createBoard = () => {
for (let i = 0; i < width * width; i++) {
const square = document.createElement("div");
square.setAttribute("draggable", true);
square.setAttribute("id", i);
let randomColor = Math.floor(Math.random() * candyColors.length);
square.style.backgroundImage = candyColors[randomColor];
grid.appendChild(square);
squares.push(square);
}
};
createBoard();
它还将使小格子可以拖动,并为它们分配随机的颜色,以及这个函数的其他功能。
我们定义了四个变量来拖动糖果以及替换它们。
let colorBeingDragged.let colorBeingReplaced.let squareIdBeingDragged.let squareIdBeindReplaced.
我们采用了事件监听器来协助我们完成这项任务,每个事件都与一个函数相关联,例如,一个方法dragOver()与事件dragover, ,以此类推。
检查一下下面的代码。
//drag the candies
let colorBeingDragged;
let colorBeingReplaced;
let squareIdBeingDragged;
let squareIdBeindReplaced;
squares.forEach(square => square.addEventListener('dragstart', dragstart))
squares.forEach(square => square.addEventListener('dragEnd', dragEnd))
squares.forEach(square => square.addEventListener('dragOver', dragOver))
squares.forEach(square => square.addEventListener('dragEnter', dragEnter))
squares.forEach(square => square.addEventListener('dragLeave', dragLeave))
squares.forEach(square => square.addEventListener('dragDrop', dragDrop))
function dragstart() {
colorBeingDragged = this.style.backgroundImage;
squareIdBeingDragged = parseInt(this.id);
console.log(colorBeingDragged);
console.log(this.id, 'dragstart');
}
function dragOver(e) {
e.preventDefault();
console.log(this.id, 'dragover');
}
function dragEnter(e) {
e.preventDefault();
console.log(this.id, 'dragenter');
}
function dragLeave() {
console.log(this.id, 'dragleave');
}
function dragDrop() {
console.log(this.id, 'dragdrop');
colorBeingReplaced = this.style.backgroundImage;
squareIdBeindReplaced = parseInt(this.id);
this.style.backgroundImage = colorBeingDragged;
squares[squareIdBeingDragged].style.backgroundImage = colorBeingReplaced;
}
function dragEnd()
由于我们现在能够拖动糖果,现在是时候进入游戏中更耐人寻味的方面了:确定一个动作是否有效。
结果将是一个额外的函数来验证糖果在某一列或某一行是否匹配,这取决于它们是如何分组的。在匹配的情况下有可能获得分数。
function dragEnd() {
console.log(this.id, "dragend");
//what is a valid move
let validMoves = [
squareIdBeingDragged - 1,
squareIdBeingDragged - width,
squareIdBeingDragged + 1,
squareIdBeingDragged + width,
];
let validMove = validMoves.includes(squareIdBeindReplaced);
if (squareIdBeindReplaced && validMove) {
squareIdBeindReplaced = null;
} else if (squareIdBeindReplaced && !validMove) {
squares[squareIdBeindReplaced].style.backgroundImage = colorBeingReplaced;
squares[squareIdBeingDragged].style.backgroundImage = colorBeingDragged;
} else {
squares[squareIdBeingDragged].style.backgroundImage = colorBeingDragged;
}
}
现在我们已经确定了一个有效的动作,我们可以亲切地搜索一个匹配,在这种情况下,我们将找到一个匹配的数字3 糖果。
如果你愿意,你可以搜索任何你想要的数字的匹配。当找到匹配的时候,分数就会被更新,并且会产生一批新的糖果。
const checkRowForThree = () => {
for (i = 0; 1 < 61; i++) {
let rowOfThree = [i, i + 1, i + 2];
let decidedColor = squares[i].style.backgroundImage;
const isBlank = squares[i].style.backgroundImage === '';
const notValid = [6, 7, 14, 15, 22, 23, 30, 31, 38, 39, 46, 47, 54, 55];
if (notValid.includes(i)) continue;
if (rowOfThree.every(index => squares[index].style.backgroundImage === decidedColor && !isBlank)) {
score += 3;
scoreDisplay.innerHTML = score;
rowOfThree.forEach(index => {
squares[index].style.backgroundImage = '';
})
}
}
}
checkRowForThree();
const checkColumnForThree = () => {
for (i = 0; 1 < 47; i++) {
let columnOfThree = [i, i + width, i + width * 2];
let decidedColor = squares[i].style.backgroundImage;
const isBlank = squares[i].style.backgroundImage === '';
if (columnOfThree.every(index => squares[index].style.backgroundImage === decidedColor && !isBlank)) {
score += 3;
scoreDisplay.innerHTML = score;
columnOfThree.forEach(index => {
squares[index].style.backgroundImage = '';
})
}
}
}
checkColumnForThree();
function moveDown() {
for (i = 0; i < 55; i++) {
if (squares[i + width].style.backgroundImage === '') {
squares[i + width].style.backgroundImage = squares[i].style.backgroundImage;
squares[i].style.backgroundImage = '';
const firstRow = [0, 1, 2, 3, 4, 5, 6, 7];
let isFirstRow = firstRow.includes(i);
if (isFirstRow && squares[1].style.backgroundImage === '') {
let randomColor = Math.floor(Math.random() * candyColors.length);
squares[1].style.backgroundImage = candyColors[randomColor];
}
}
}
以下是源代码的完整参考。
HTML文件。
<div class="score-board">
<h3>score</h3>
<h1 id="score"></h1>
</div>
<div class="grid"></div>
样式表。
* {
margin: 0;
padding: 0;
}
body {
display: flex;
justify-content: space-evenly;
align-items: center;
font-family: "Trebuchet MS", "Lucida Sans Unicode", "Lucida Grande",
"Lucida Sans", Arial, sans-serif;
}
.grid {
margin-top: 34px;
height: 560px;
width: 560px;
display: flex;
flex-wrap: wrap;
}
.grid div {
height: 70px;
width: 70px;
}
JavaScript文件。
document.addEventListener("DOMContentLoaded", () => {
const grid = document.querySelector(".grid");
const width = 8;
const squares = [];
let scoreDisplay = document.getElementById("score");
let score = 0;
const candyColors = ["red", "yellow", "orange", "purple", "green", "blue"];
// create Board
let createBoard = () => {
for (let i = 0; i < width * width; i++) {
const square = document.createElement("div");
square.setAttribute("draggable", true);
square.setAttribute("id", i);
let randomColor = Math.floor(Math.random() * candyColors.length);
square.style.backgroundImage = candyColors[randomColor];
grid.appendChild(square);
squares.push(square);
}
};
createBoard();
//drag the candies
let colorBeingDragged;
let colorBeingReplaced;
let squareIdBeingDragged;
let squareIdBeindReplaced;
squares.forEach((square) => square.addEventListener("dragstart", dragstart));
squares.forEach((square) => square.addEventListener("dragEnd", dragEnd));
squares.forEach((square) => square.addEventListener("dragOver", dragOver));
squares.forEach((square) => square.addEventListener("dragEnter", dragEnter));
squares.forEach((square) => square.addEventListener("dragLeave", dragLeave));
squares.forEach((square) => square.addEventListener("dragDrop", dragDrop));
function dragstart() {
colorBeingDragged = this.style.backgroundImage;
squareIdBeingDragged = parseInt(this.id);
console.log(colorBeingDragged);
console.log(this.id, "dragstart");
}
function dragOver(e) {
e.preventDefault();
console.log(this.id, "dragover");
}
function dragEnter(e) {
e.preventDefault();
console.log(this.id, "dragenter");
}
function dragLeave() {
console.log(this.id, "dragleave");
}
function dragDrop() {
console.log(this.id, "dragdrop");
colorBeingReplaced = this.style.backgroundImage;
squareIdBeindReplaced = parseInt(this.id);
this.style.backgroundImage = colorBeingDragged;
squares[squareIdBeingDragged].style.backgroundImage = colorBeingReplaced;
}
function dragEnd() {
console.log(this.id, "dragend");
//what is a valid move
let validMoves = [
squareIdBeingDragged - 1,
squareIdBeingDragged - width,
squareIdBeingDragged + 1,
squareIdBeingDragged + width,
];
let validMove = validMoves.includes(squareIdBeindReplaced);
if (squareIdBeindReplaced && validMove) {
squareIdBeindReplaced = null;
} else if (squareIdBeindReplaced && !validMove) {
squares[squareIdBeindReplaced].style.backgroundImage = colorBeingReplaced;
squares[squareIdBeingDragged].style.backgroundImage = colorBeingDragged;
} else {
squares[squareIdBeingDragged].style.backgroundImage = colorBeingDragged;
}
}
const checkRowForThree = () => {
for (i = 0; 1 < 61; i++) {
let rowOfThree = [i, i + 1, i + 2];
let decidedColor = squares[i].style.backgroundImage;
const isBlank = squares[i].style.backgroundImage === "";
const notValid = [6, 7, 14, 15, 22, 23, 30, 31, 38, 39, 46, 47, 54, 55];
if (notValid.includes(i)) continue;
if (
rowOfThree.every(
(index) =>
squares[index].style.backgroundImage === decidedColor && !isBlank
)
) {
score += 3;
scoreDisplay.innerHTML = score;
rowOfThree.forEach((index) => {
squares[index].style.backgroundImage = "";
});
}
}
};
checkRowForThree();
const checkColumnForThree = () => {
for (i = 0; 1 < 47; i++) {
let columnOfThree = [i, i + width, i + width * 2];
let decidedColor = squares[i].style.backgroundImage;
const isBlank = squares[i].style.backgroundImage === "";
if (
columnOfThree.every(
(index) =>
squares[index].style.backgroundImage === decidedColor && !isBlank
)
) {
score += 3;
scoreDisplay.innerHTML = score;
columnOfThree.forEach((index) => {
squares[index].style.backgroundImage = "";
});
}
}
};
checkColumnForThree();
function moveDown() {
for (i = 0; i < 55; i++) {
if (squares[i + width].style.backgroundImage === "") {
squares[i + width].style.backgroundImage =
squares[i].style.backgroundImage;
squares[i].style.backgroundImage = "";
const firstRow = [0, 1, 2, 3, 4, 5, 6, 7];
let isFirstRow = firstRow.includes(i);
if (isFirstRow && squares[1].style.backgroundImage === "") {
let randomColor = Math.floor(Math.random() * candyColors.length);
squares[1].style.backgroundImage = candyColors[randomColor];
}
}
}
}
window.setInterval(() => {
moveDown();
checkRowForThree();
checkColumnForThree();
}, 100);
});
输出。

结论
通过所提供的知识,你现在明白了如何设置HTML元素的属性,如何创建HTML元素,如何使用计时器,以及最重要的是,如何使用javascript进行游戏开发。
还有其他的方法来创建本帖所讨论的游戏,这只是一种直接的方法。你可以尝试不同的方法,使其更加吸引人。为了更多的练习,你可以用javascript开发一个俄罗斯方块游戏。