别踩白块

JavaScriptJavaScriptBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

本项目将指导你创建一款名为《别踩白块儿》的简单但引人入胜的网页游戏。通过遵循这些步骤,你将学习如何结合 HTML、CSS 和 JavaScript 来构建一个交互式游戏,玩家必须避免踩到白块儿才能得分。本项目非常适合希望练习网页开发技能的初学者。

👀 预览

🎯 任务

在本项目中,你将学习:

  • 如何设置基本的 HTML 结构来布局游戏界面。
  • 如何利用 CSS 对游戏进行样式设计,使其在视觉上更具吸引力且用户友好。
  • 如何实现 JavaScript 以添加动态功能,如移动方块、计分系统和游戏逻辑。
  • 如何通过点击等事件处理用户交互,增强游戏的交互性。
  • 如何操作 DOM 以动态更新游戏状态,如分数和游戏结束条件。
  • 如何应用基本的游戏开发概念,如游戏循环、碰撞检测和速度调整。

🏆 成果

完成本项目后,你将能够:

  • 扎实理解如何结合 HTML、CSS 和 JavaScript 来创建交互式网页应用程序。
  • 应用游戏开发概念的实践经验,如动画、用户输入处理和实时更新。
  • 操作 DOM 并处理事件以创建响应式网页应用程序。
  • 通过实现游戏逻辑和处理游戏结束等边缘情况来提高解决问题的能力。
  • 在网页设计和游戏美学方面展示你的创造力,并探索进一步的定制和增强功能。
  • 朝着更复杂的网页开发和游戏设计项目迈出基础的一步,为在网页技术领域的进一步学习和探索奠定基础。

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL javascript(("JavaScript")) -.-> javascript/BasicConceptsGroup(["Basic Concepts"]) javascript(("JavaScript")) -.-> javascript/DOMManipulationGroup(["DOM Manipulation"]) javascript/BasicConceptsGroup -.-> javascript/arith_ops("Arithmetic Operators") javascript/BasicConceptsGroup -.-> javascript/cond_stmts("Conditional Statements") javascript/BasicConceptsGroup -.-> javascript/loops("Loops") javascript/BasicConceptsGroup -.-> javascript/functions("Functions") javascript/DOMManipulationGroup -.-> javascript/dom_select("DOM Selection") javascript/DOMManipulationGroup -.-> javascript/dom_manip("DOM Manipulation") javascript/DOMManipulationGroup -.-> javascript/event_handle("Event Handling") javascript/DOMManipulationGroup -.-> javascript/dom_traverse("DOM Traversal") subgraph Lab Skills javascript/arith_ops -.-> lab-445719{{"别踩白块"}} javascript/cond_stmts -.-> lab-445719{{"别踩白块"}} javascript/loops -.-> lab-445719{{"别踩白块"}} javascript/functions -.-> lab-445719{{"别踩白块"}} javascript/dom_select -.-> lab-445719{{"别踩白块"}} javascript/dom_manip -.-> lab-445719{{"别踩白块"}} javascript/event_handle -.-> lab-445719{{"别踩白块"}} javascript/dom_traverse -.-> lab-445719{{"别踩白块"}} end

设置 HTML 结构

首先在 index.html 中为游戏创建基本的 HTML 结构。这包括游戏的标题、分数显示、主要游戏区域(#main)以及开始按钮。主要游戏区域将包含移动的方块行。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Don't Step on the White Tile</title>
    <link rel="stylesheet" href="index.css" />
  </head>
  <body>
    <h2>Score</h2>
    <h2 id="score">0</h2>
    <div id="main">
      <div id="con"></div>
    </div>
    <div class="btn">
      <button class="start" onclick="start()">Start Game</button>
    </div>
    <script src="index.js"></script>
  </body>
</html>

在这一步中,你已经为游戏建立了基本的 HTML 结构。该结构包括游戏的标题、分数显示、用于移动方块的以 #main 标识的主要游戏区域,以及用于开始游戏的开始按钮。#main 区域稍后将填充玩家在游戏过程中与之交互的方块行。此设置至关重要,因为它奠定了游戏的框架,CSS 和 JavaScript 将在此基础上添加样式和功能。

✨ 查看解决方案并练习

设计 CSS 样式

index.css 中定义 CSS 样式,以便从视觉上构建游戏结构。此步骤涉及对主要游戏容器、各个方块(单元格)和开始按钮进行样式设计,使游戏在视觉上更具吸引力。

#main {
  width: 408px;
  height: 408px;
  background: white;
  border: 2px solid gray;
  margin: 0 auto;
  overflow: hidden;
}

h2 {
  text-align: center;
}

#con {
  width: 100%;
  height: 400px;
  position: relative;
  top: -408px;
  border-collapse: collapse;
}

.row {
  height: 100px;
  width: 100%;
}

.cell {
  height: 100px;
  width: 100px;
  float: left;
  border: rgb(54, 74, 129) 1px solid;
}

.black {
  background: black;
}

.btn {
  width: 100%;
  text-align: center;
}

.start {
  margin: 20px auto;
  width: 150px;
  height: 50px;
  border-radius: 10px;
  background: yellowgreen;
  line-height: 50px;
  color: #fff;
}

你已经定义了决定游戏视觉效果的 CSS 样式。这些样式包括主要游戏区域的布局、方块(或单元格)的外观以及开始按钮的样式。通过设置这些样式,你使游戏在视觉上更具吸引力,并定义了玩家将与之交互的用户界面元素,如游戏棋盘和开始按钮。这些样式对于使游戏引人入胜并让玩家易于使用至关重要。

✨ 查看解决方案并练习

游戏初始化

在这一步中,你将开始在 index.js 中编写让游戏运行起来所需的 JavaScript 代码。首先创建 startinit 函数,用于初始化游戏并动态创建游戏区域的初始方块行。

// 用于通过 ID 获取元素的辅助函数
function $(id) {
  return document.getElementById(id);
}

// 创建具有给定类名的 div 的函数
function createDiv(className) {
  var div = document.createElement("div");
  div.className = className;
  return div;
}

var gameStarted = false;

// 开始游戏的函数
function start() {
  if (!gameStarted) {
    init();
  } else {
    alert("The game has already started, no need to click again!");
  }
}

// 初始化游戏
function init() {
  gameStarted = true;
  for (var i = 0; i < 4; i++) {
    createRow();
  }
}

在这个阶段,你已经开始用 JavaScript 让游戏动起来了。你编写的代码初始化了游戏,并设置了创建初始方块行的机制。这包括定义用于操作 DOM 的辅助函数、设置一个标志以防止多次启动游戏,以及为向游戏区域动态添加行奠定基础。这一步至关重要,因为它设置了游戏的动态元素,为方块移动以及玩家开始与游戏互动的交互部分做好准备。

✨ 查看解决方案并练习

处理行移动和游戏结束检查

扩展 JavaScript 功能,使其包括向下移动行以及检查游戏是否结束。这涉及创建一个游戏循环,该循环更新行的位置,并检查是否有任何一行在未被“踩到”的情况下越过了允许的边界。

// 继续在 index.js 中

var speed = 6; // 移动行的初始速度
var clock = null;

// 向下移动行
function move() {
  var con = $("con");
  var top = parseInt(window.getComputedStyle(con, null)["top"]);
  if (speed + top > 0) {
    top = 0;
  } else {
    top += speed;
  }
  con.style.top = top + "px";
  checkGameOver();
  if (top == 0) {
    createRow();
    con.style.top = "-102px";
    deleteRow();
  }
}

// 检查游戏是否结束
function checkGameOver() {
  var con = $("con");
  var rows = con.childNodes;
  var conTop = parseInt(window.getComputedStyle(con, null)["top"]);
  var conHeight = con.offsetHeight;
  for (var i = 0; i < rows.length; i++) {
    var row = rows[i];
    var rowTop = conTop + i * row.offsetHeight;
    if (rowTop >= conHeight && row.passed !== 1) {
      fail();
      break;
    }
  }
}

在这里,你通过添加向下移动行和检查游戏结束条件的逻辑,扩展了游戏的功能。move 函数更新行的位置,模拟玩家需要避免踩到的方块的移动。checkGameOver 函数监控是否有任何一行在未被“踩到”的情况下越过了游戏区域的底部,如果是,则游戏结束。这一步引入了主要的游戏机制和挑战,使游戏具有交互性和吸引力。

✨ 查看解决方案并练习

实现计分与速度提升

在这一步中,重点是实现游戏的计分机制,并随着玩家分数的增加提高方块行的移动速度。这为游戏增添了一定的挑战性,使其更具吸引力。

// 继续在 index.js 中

// 更新分数
function score() {
  var newScore = parseInt($("score").innerHTML) + 1;
  $("score").innerHTML = newScore;
  if (newScore % 10 == 0) {
    speedUp();
  }
}

// 提高移动方块行的速度
function speedUp() {
  speed += 2;
  if (speed == 20) {
    alert("Incredible speed!");
  }
}

在这一步中,你实现了游戏的计分系统,并添加了一项功能,即随着玩家分数的增加提高移动方块行的速度。这不仅向玩家反馈了他们的表现,还逐步增加了游戏的难度。计分机制奖励玩家成功避开白色方块,而速度的增加则考验玩家的反应速度,使游戏更具吸引力和竞争性。

✨ 查看解决方案并练习

处理用户交互

实现处理用户点击方块的逻辑。玩家点击黑色方块时得分,点击白色方块时失分。

// 继续在 index.js 中

// 判断玩家的操作
function judge(ev) {
  ev = ev || event;
  if (ev.target.className.indexOf("black") !== -1) {
    ev.target.className = "cell";
    ev.target.parentNode.passed = 1;
    score();
  } else if (ev.target.className.indexOf("cell") !== -1) {
    fail();
  }
}

在这一步中,你实现了 judge 函数来处理游戏中的用户点击操作。当玩家点击一个方块时,该函数会判断方块是否为黑色。如果方块是黑色(正确操作),它会变成一个普通方块,并且分数会更新。如果方块不是黑色(错误操作),则会触发游戏结束流程。这个函数对于游戏的交互性至关重要,它允许玩家通过点击方块与游戏进行交互,并立即获得关于他们操作的反馈。

✨ 查看解决方案并练习

创建和删除行

开发函数以动态创建新的方块行,并在最旧的行不再可见时将其删除,以保持游戏平稳运行。

// 继续在 index.js 中

// 在一行中随机分配黑色方块
function createCell() {
  var temp = ["cell", "cell", "cell", "cell"];
  var i = Math.floor(Math.random() * 4);
  temp[i] = "cell black";
  return temp;
}

// 创建新的方块行
function createRow() {
  var con = $("con");
  var row = createDiv("row");
  var arr = createCell();
  for (var i = 0; i < 4; i++) {
    row.appendChild(createDiv(arr[i]));
  }
  if (con.firstChild == null) {
    con.appendChild(row);
  } else {
    con.insertBefore(row, con.firstChild);
  }
}

// 如果有超过 5 行,则删除最后一行
function deleteRow() {
  var con = $("con");
  if (con.childNodes.length == 6) {
    con.removeChild(con.lastChild);
  }
}

你添加了 createRow 函数来动态生成方块行,其中一个黑色方块位于随机位置,增强了游戏的不可预测性和挑战性。deleteRow 函数删除不再可见的最旧行,优化了游戏性能,并确保游戏区域不会因未使用的元素而溢出。这些函数共同作用,为玩家保持方块的连续流动以供交互。

✨ 查看解决方案并练习

实现游戏结束逻辑

定义游戏结束的条件,例如点击白色方块或错过黑色方块。显示玩家的最终得分,并提供重新开始游戏的选项。

// 继续在 index.js 中

// 结束游戏
function fail() {
  clearInterval(clock);
  gameStarted = false;
  confirm("Your final score is " + parseInt($("score").innerHTML));
  window.location.reload();
}

通过定义 fail 函数,你确定了游戏结束的条件。当玩家做出错误操作或错过黑色方块时,会调用此函数。它会停止游戏循环,显示玩家的最终得分,并重新加载页面以重新开始。这一步对于提供完整的游戏体验至关重要,包括避免错误的挑战和游戏结束的确定性。

✨ 查看解决方案并练习

启动游戏循环

设置主游戏循环,使方块在屏幕上向下移动。根据玩家得分调整移动速度以增加难度。

// 继续在 index.js 中

// 启动游戏循环
function start() {
  if (!gameStarted) {
    init();
    clock = setInterval("move()", 30);
  }
}

你使用 move 函数设置了主游戏循环,该函数持续使方块行在屏幕上向下移动,模拟游戏进程。随着玩家得分增加,移动速度加快,增加了游戏难度。这个循环是游戏的核心,推动游戏玩法并挑战玩家跟上不断加快的节奏。

✨ 查看解决方案并练习

添加事件监听器

将事件监听器附加到游戏区域,以检测并响应玩家操作,例如点击方块。

// 继续在 index.js 中

// 为主要游戏容器添加事件监听器
$("main").onclick = function (ev) {
  judge(ev);
};

在这一步中,你已将事件监听器附加到主要游戏区域,使其能够响应玩家点击。此功能对于捕获用户交互至关重要,它允许游戏处理玩家的移动并相应地更新游戏状态。这就是使游戏具有交互性并能对玩家操作做出响应的原因。

要查看以下效果,请点击 WebIDE 右下角的“上线”按钮,然后切换到“Web 8080”标签页。

✨ 查看解决方案并练习

总结

通过完成这个项目,你创建了一个名为“别踩白块”的实用网页游戏。这个项目不仅加深了你对HTML、CSS和JavaScript如何协同工作以创建交互式网页内容的理解,还为未来创建更复杂的网页游戏奠定了基础。尝试不同的样式、特性和功能,让这个游戏独具你自己的特色。编码愉快!