当前位置: 首页 > news >正文

Enduro 克隆游戏 — 基于 HTML、CSS 与 JavaScript 的完整教程模板

Enduro 克隆游戏 — 基于 HTML、CSS 与 JavaScript 的完整教程模板

目录

  • 项目概述
  • 主要特性
  • 技术栈与需求
  • 环境准备
  • 获取并运行项目
  • 项目结构示例
  • 示例代码片段
    • index.html 示例
    • style.css 示例
    • game.js 示例
  • 操作与控制
  • 常见问题与调试提示
  • 扩展与改进建议
  • 截图说明示例
  • 许可证与来源说明

项目概述

Enduro 克隆游戏 是对经典街机赛车 Enduro 的前端复刻。游戏以纯 HTML、CSS 与原生 JavaScript 实现,模拟车辆在无尽道路上的行驶、超车与躲避障碍的体验。该项目既可作为教学示例,也便于扩展加入更多功能。


主要特性

  • 纯前端实现:仅使用 HTML、CSS 和 JavaScript,无需后端或数据库。
  • 复古 UI:模仿经典 Enduro 外观,屏幕上实时显示分数和进度。
  • 响应式布局:可适应不同屏幕尺寸。
  • 核心游戏玩法
    • 玩家控制一辆赛车在无尽赛道上行驶。
    • 使用键盘进行平滑的左右移动,并可控制速度(加速/减速)。
    • 随着游戏进程,速度和难度不断增加。
    • 模拟原版 Enduro 的昼夜过渡效果。
  • 游戏机制
    • 超越一定数量赛车可晋级下一阶段。
    • 碰撞系统:与障碍物(其他车辆)碰撞会导致速度减慢。
    • 跟踪距离和时间。
    • 交通密度逐渐增加,提升挑战性。
  • 视觉和音频增强
    • 像素艺术风格图形,营造怀旧感。
    • 模拟道路运动的动画背景。
    • 流畅的汽车运动和碰撞动画。
    • 引人入胜的引擎、碰撞和过渡音效(若有实现)。
  • 教育用途:该项目是练习和巩固基本编程概念,提升 JavaScript 游戏开发技能的宝贵资源。

技术栈与需求

  • 核心语言:JavaScript
  • 前端技术:HTML (用于结构), CSS (用于样式)
  • 编码工具:Notepad++ 或任何可以运行 HTML 文件的文本编辑器(如 Visual Studio Code, Sublime Text 等)。
  • 运行环境:任何现代 Web 浏览器(如 Chrome, Firefox, Edge, Safari)。
  • 数据库:无。
  • 项目类型:Web 应用程序。

环境准备

本游戏作为纯前端 Web 应用,无需复杂的后端或数据库配置。

  1. 文本编辑器:请确保您已安装并熟悉使用一款文本编辑器,例如 Visual Studio Code、Sublime Text 或 Notepad++。
  2. 现代浏览器:准备一个您常用的现代浏览器,用于打开和运行游戏。

获取并运行项目

  1. 下载源代码:通常,项目源代码会以 .zip 压缩包的形式提供。请从可靠来源(如 SourceCodester 网站)下载本游戏的源代码。
  2. 解压文件:将下载的 .zip 文件解压到您选择的任意目录中。解压后,您会得到一个包含游戏所有文件和文件夹的项目目录。
  3. 运行游戏
    • 在解压后的项目文件夹中,找到主 HTML 文件(通常命名为 index.html)。
    • 双击 index.html 文件,它将自动在您的默认浏览器中打开,游戏即可启动。
    • 或者,您也可以在浏览器中选择“文件” -> “打开文件”,然后导航到 index.html 并打开。
    • (可选)为了避免本地文件系统限制,您可以使用轻量级本地服务器(如 VS Code 的 Live Server 扩展或 Node.js 的 http-server)来运行项目。

项目结构示例

enduro-clone/
├─ index.html          # 游戏主页面
├─ css/                # 存放 CSS 样式文件
│  └─ style.css       # 游戏样式表
├─ js/                 # 存放 JavaScript 文件
│  └─ game.js         # 游戏核心逻辑
├─ assets/             # 存放游戏资源,如图片和音效(可选)
│  ├─ images/
│  │  ├─ car.png
│  │  └─ obstacle.png
│  └─ audio/
│     ├─ engine.mp3
│     └─ crash.mp3
└─ README.md           # 项目说明文件 (当前正在阅读的)

示例代码片段

以下代码为可直接复制到项目中的基础实现示例。这些片段旨在展示核心结构,实际项目可能包含更多细节和优化。

index.html 示例

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>Enduro 克隆游戏</title><link rel="stylesheet" href="css/style.css" />
</head>
<body><div id="game-root"><header id="hud"><div id="score">分数: <span id="score-value">0</span></div><div id="stage">关卡: <span id="stage-value">1</span></div></header><main id="game-area"><!-- 游戏元素(由 JS 动态插入) --><div id="player" class="car"></div></main><div id="overlay" class="hidden"><div id="game-over"><h1>游戏结束</h1><p>最终得分:<span id="final-score">0</span></p><button id="btn-restart">重新开始</button></div></div></div><script src="js/game.js"></script>
</body>
</html>

style.css 示例

/* css/style.css */
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {background: #222; /* 主背景色 */color: #fff;font-family: "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;display: flex;justify-content: center;align-items: center;overflow: hidden; /* 防止滚动条 */
}#game-root {width: 800px;max-width: 95vw; /* 适应小屏幕 */border: 2px solid #fff;box-shadow: 0 0 15px rgba(0,0,0,0.5);background-color: #333;
}#hud {display: flex;justify-content: space-between;padding: 10px;font-size: 1.2em;background-color: #444;border-bottom: 1px solid #666;
}
#score, #stage {padding: 5px 10px;background-color: #555;border-radius: 4px;
}#game-area {position: relative;width: 100%; /* 继承父元素宽度 */height: 600px; /* 游戏区域固定高度 */background: linear-gradient(#444, #222); /* 简单道路背景 */overflow: hidden; /* 隐藏超出边界的元素 */
}/* 玩家车辆 */
.car {position: absolute;width: 50px; /* 车辆宽度 */height: 90px; /* 车辆高度 */background: red; /* 车辆颜色 */bottom: 30px; /* 距离底部 */left: calc(50% - 25px); /* 水平居中 */border-radius: 6px;transition: left 0.1s linear; /* 平滑左右移动 */box-shadow: 0 0 10px rgba(255,255,255,0.3);
}/* 障碍物(其他车辆) */
.obstacle {position: absolute;width: 48px;height: 48px;background: gray; /* 障碍物颜色 */border-radius: 4px;box-shadow: 0 0 8px rgba(0,0,0,0.5);
}/* 覆盖层(游戏结束) */
#overlay {position: absolute;inset: 0; /* 覆盖整个游戏区域 */display: flex;justify-content: center;align-items: center;background: rgba(0,0,0,0.7); /* 半透明黑色背景 */z-index: 100; /* 确保在最上层 */
}
#overlay.hidden { display: none; } /* 默认隐藏 */#game-over {background: #2a2a2a;padding: 30px 40px;border-radius: 10px;text-align: center;box-shadow: 0 0 20px rgba(0,255,255,0.5);transform: scale(0.9);animation: popIn 0.3s ease-out forwards;
}@keyframes popIn {from { transform: scale(0.7); opacity: 0; }to { transform: scale(1); opacity: 1; }
}#game-over h1 {margin-bottom: 15px;color: #ffcc00;font-size: 2.5em;text-shadow: 2px 2px 4px rgba(0,0,0,0.7);
}
#game-over p {margin-bottom: 25px;font-size: 1.5em;
}
#game-over #final-score {font-weight: bold;color: #00ff00;
}
#btn-restart {padding: 12px 25px;font-size: 1.2em;cursor: pointer;border: none;border-radius: 5px;background: #007bff;color: #fff;transition: background 0.3s ease, transform 0.1s ease;box-shadow: 0 4px 6px rgba(0,0,0,0.3);
}
#btn-restart:hover {background: #0056b3;transform: translateY(-2px);
}
#btn-restart:active {transform: translateY(0);box-shadow: 0 2px 3px rgba(0,0,0,0.3);
}

game.js 示例

// js/game.js
document.addEventListener('DOMContentLoaded', () => {// --- DOM 元素获取 ---const player = document.getElementById('player');const gameArea = document.getElementById('game-area');const scoreValue = document.getElementById('score-value');const stageValue = document.getElementById('stage-value'); // 关卡显示const overlay = document.getElementById('overlay');const finalScore = document.getElementById('final-score');const restartBtn = document.getElementById('btn-restart');// --- 游戏状态变量 ---let score = 0;let currentStage = 1;let gameRunning = false; // 游戏是否正在进行let animationFrameId; // 用于 requestAnimationFramelet playerX = gameArea.clientWidth / 2 - player.clientWidth / 2; // 玩家X坐标const playerSpeed = 8; // 玩家左右移动速度let gameSpeed = 5; // 游戏整体下落速度 (像素/帧)const obstacleGenerationInterval = 60; // 障碍物生成间隔帧数let frameCount = 0; // 帧计数器// --- 初始化游戏 ---function initGame() {// 重置状态score = 0;currentStage = 1;gameSpeed = 5;gameRunning = true;scoreValue.textContent = score;stageValue.textContent = currentStage;overlay.classList.add('hidden'); // 隐藏游戏结束界面// 重置玩家位置playerX = gameArea.clientWidth / 2 - player.clientWidth / 2;player.style.left = `${playerX}px`;player.style.bottom = '30px'; // 确保在底部// 清除所有现有障碍物document.querySelectorAll('.obstacle').forEach(obs => obs.remove());// 启动游戏循环if (animationFrameId) cancelAnimationFrame(animationFrameId); // 取消之前的循环gameLoop();}// --- 游戏主循环 ---function gameLoop() {if (!gameRunning) return;frameCount++;// 障碍物生成逻辑if (frameCount % obstacleGenerationInterval === 0) {createObstacle();}// 移动障碍物并进行碰撞检测document.querySelectorAll('.obstacle').forEach(obstacle => {let currentTop = parseFloat(obstacle.style.top);obstacle.style.top = `${currentTop + gameSpeed}px`;// 障碍物超出底部,移除并加分if (currentTop > gameArea.clientHeight) {obstacle.remove();score++;scoreValue.textContent = score;// 简单关卡晋升逻辑 (例如每得20分升一级)if (score % 20 === 0 && score !== 0) {currentStage++;stageValue.textContent = currentStage;gameSpeed += 0.5; // 增加游戏速度,提升难度}} else {// 碰撞检测if (isColliding(player, obstacle)) {gameOver();}}});animationFrameId = requestAnimationFrame(gameLoop);}// --- 创建障碍物 ---function createObstacle() {const obstacle = document.createElement('div');obstacle.className = 'obstacle';obstacle.style.top = '-50px'; // 从顶部之外开始生成// 随机左右位置,确保不会超出边界const randomX = Math.random() * (gameArea.clientWidth - 48); // 48为障碍物宽度obstacle.style.left = `${randomX}px`;gameArea.appendChild(obstacle);}// --- 碰撞检测函数 ---function isColliding(element1, element2) {const rect1 = element1.getBoundingClientRect();const rect2 = element2.getBoundingClientRect();// 检查是否有任何重叠return !(rect1.bottom < rect2.top ||rect1.top > rect2.bottom ||rect1.right < rect2.left ||rect1.left > rect2.right);}// --- 游戏结束逻辑 ---function gameOver() {gameRunning = false;cancelAnimationFrame(animationFrameId); // 停止动画循环finalScore.textContent = score;overlay.classList.remove('hidden'); // 显示游戏结束界面}// --- 事件监听器 ---document.addEventListener('keydown', (e) => {if (!gameRunning) return; // 游戏未进行时,不响应按键// 玩家左右移动if (e.key === 'ArrowLeft') {playerX -= playerSpeed;} else if (e.key === 'ArrowRight') {playerX += playerSpeed;}// 限制玩家在游戏区域内playerX = Math.max(0, Math.min(playerX, gameArea.clientWidth - player.clientWidth));player.style.left = `${playerX}px`;});restartBtn.addEventListener('click', initGame);// --- 首次加载时启动游戏 ---initGame();
});

操作与控制

  • 向左移动:按下键盘上的 左箭头 (←) 键。
  • 向右移动:按下键盘上的 右箭头 (→) 键。
  • 加速(若实现):原始描述中提到“上箭头键加速”,但在提供的示例代码中未直接实现加速功能,而是通过得分增加 gameSpeed 来提升难度。您可以在 game.js 中添加对 ArrowUp 键的监听来控制玩家车辆的垂直移动速度或游戏全局速度。
  • 减速(若实现):原始描述中提到“下箭头键减速”,同样未在示例代码中直接实现。您可以在 game.js 中添加对 ArrowDown 键的监听。
  • 重新开始:游戏结束后,点击屏幕中央的“重新开始”按钮。

常见问题与调试提示

  • 游戏无法运行
    • 文件路径:请确保 index.htmllinkscript 标签的 hrefsrc 属性指向的 CSS 和 JavaScript 文件路径正确(例如 css/style.css, js/game.js)。
    • 浏览器控制台:打开浏览器开发者工具(通常按 F12),切换到“控制台 (Console)”选项卡。如果代码有错误,这里会显示详细的错误信息,帮助您定位问题。
  • 图片或资源未加载
    • 如果您的项目使用了图片或音频文件,请检查其在 CSS 或 JavaScript 中引用的路径是否正确,并确认文件确实存在于相应位置。
    • 本地服务器:直接从文件系统(file:/// 协议)打开 HTML 文件时,浏览器可能会实施 CORS(跨域资源共享)安全策略,导致某些资源(尤其是从外部加载的)无法加载。强烈建议使用本地静态服务器来运行项目(如 VS Code 的 Live Server 扩展,或通过 Node.js 安装 http-servernpm install -g http-server,然后在项目根目录运行 http-server)。
  • 移动卡顿或不流畅
    • 游戏循环:确保游戏的主循环使用 requestAnimationFrame 而不是 setIntervalrequestAnimationFrame 会与浏览器刷新率同步,提供更流畅的动画。
    • DOM 操作:频繁的 DOM 操作会影响性能。尽量减少在游戏循环中直接操作 DOM 的次数。例如,可以通过改变元素的 transform 属性来移动,而不是直接改变 topleft
    • 性能分析:在浏览器开发者工具中,使用“性能 (Performance)”选项卡录制一段游戏运行过程,可以帮助您找出性能瓶颈。

扩展与改进建议

这个 Enduro 克隆项目是一个优秀的起点,您可以尝试以下方式来进一步探索和提升:

  • 视觉增强
    • 滚动道路背景:实现背景图片或 CSS 渐变的平滑垂直滚动,模拟道路在移动。
    • 白天/夜晚循环:更精细地控制背景颜色和亮度的变化,模拟时间流逝。
    • 车辆贴图:替换单色车辆为真实的像素艺术贴图。
    • 粒子效果:在车辆加速时添加尘土或尾气效果。
  • 游戏性增强
    • 不同障碍物:引入不同大小、形状或行为模式的障碍物(例如,卡车、摩托车)。
    • 道具系统:添加拾取道具(如加速、护盾、分数加成)的功能。
    • 生命值/碰撞惩罚:除了减速,可以引入生命值系统,碰撞时扣除生命值,生命值为零时游戏结束。
    • 更复杂的关卡设计:不仅仅是速度提升,还可以改变障碍物的生成模式或密度。
    • 音效与背景音乐:为碰撞、得分、加速、游戏开始/结束等事件添加音效,并播放循环背景音乐。
  • 用户体验
    • 开始菜单:添加一个更完善的开始界面,包含游戏说明、音量控制等。
    • 高分榜:使用 localStorage 在本地存储玩家的高分记录。
    • 键盘配置:允许玩家自定义控制按键。
  • 代码优化
    • 模块化:将游戏的不同部分(如游戏逻辑、渲染、输入处理)拆分为独立的函数或模块,提高可维护性。
    • 面向对象:可以尝试使用面向对象编程的思想,为玩家、障碍物等创建类。

截图说明示例

描述截图示例
游戏主界面:玩家在赛道起点准备开始。游戏主界面
游戏进行中:玩家在躲避障碍物。游戏过程截图
游戏结束画面:显示最终得分与重玩选项。游戏结束界面截图

许可证与来源说明

  • 源代码来源:本教程模板改编自 SourceCodester 网站上名为“使用 HTML、CSS 和 JavaScript 的 Enduro 克隆游戏”的项目。
  • 教育用途:根据原始项目说明,此应用程序仅供教育用途
  • 许可证:请根据原始项目提供方的具体说明,遵守其源代码的使用和分发条款。

http://www.dtcms.com/a/353174.html

相关文章:

  • 23种设计模式——单例模式(Singleton)​详解
  • 金仓数据库文档系统全面升级:用户体验焕然一新
  • CPU、IO、网络与内核参数调优
  • Linux 性能调优实战:CPU、磁盘 I/O、网络与内核参数
  • 系统架构设计师备考第8天——嵌入式系统
  • 工业网络安全:保护制造系统和数据
  • Linux 系统CPU-IO-网络-内核参数的调优
  • 【学习笔记】GB 42250-2022标准解析
  • 手写MyBatis第36弹:MyBatis执行流程中SQL命令类型解析
  • Effective c++ 35条款详解
  • docker run 后报错/bin/bash: /bin/bash: cannot execute binary file总结
  • Python计算点云的欧式、马氏、最近邻、平均、倒角距离(Chamfer Distance)
  • iOS技术之通过Charles抓包http、https数据
  • 【开题答辩全过程】以Trlig(服装网站)为例,包含答辩的问题和答案
  • ETH PPS 配置链路
  • 车载诊断架构 --- 基于整车功能的正向诊断需求开发
  • Ruoyi-cloud 微服务部署双方案:本地与 K8S 实践手册
  • FastAPI + SQLModel 从 0 搭到完整 CRUD
  • 腾讯云人脸库技术架构深度解析
  • Github 3k+ star,中后台管理系统框架,支持多款 UI 组件库,兼容PC、移动端!比商业系统还专业!!
  • IntelliJ IDEA Debug 模式功能指南
  • 微算法科技(NASDAQ:MLGO)突破性FPGA仿真算法技术助力Grover搜索,显著提升量子计算仿真效率
  • 【数据结构】树和二叉树——树和森林
  • Python音频分析与线性回归:探索声音中的数学之美
  • 基于 Qt 实现的动态流程图画板框架设计与实现
  • 储能变流器学习之MPPT
  • 教程:按年份导出中国县级 NDVI(月均值 CSV)
  • 【87页PPT】新能源汽车解决方案(附下载方式)
  • 把 AI 塞进「盲文点显器」——基于触觉反馈的离线双向翻译笔
  • 【RAG】使用llamaindex进行RAG开发