模板特点
- 响应式设计: 适配桌面和移动设备。
- 模块化结构: 代码清晰,易于理解和扩展。
- Canvas 核心: 使用 HTML5 Canvas 作为游戏渲染的主要区域。
- 完整的游戏流程: 包含开始界面、游戏主界面、游戏结束界面和分数系统。
- 键盘与触摸控制: 同时支持键盘(方向键/ WASD)和触摸(移动端)操作。
- 动画循环: 使用
requestAnimationFrame实现流畅的动画。 - 面向对象: 使用 ES6 类来组织游戏逻辑,便于管理。
最终效果预览
文件结构
为了保持项目整洁,我们建议创建以下文件结构:

(图片来源网络,侵删)
my-game/
├── index.html # 主 HTML 文件
├── style.css # 样式文件
└── script.js # 游戏逻辑文件
index.html (主页面结构)
这个文件定义了页面的基本骨架,包括游戏标题、画布元素和用于显示分数的元素。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">我的 HTML5 游戏</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="game-container">
<h1>太空躲避者</h1>
<div class="game-info">
<span>分数: <span id="score">0</span></span>
<span>最高分: <span id="high-score">0</span></span>
</div>
<!-- 游戏画布 -->
<canvas id="gameCanvas"></canvas>
<!-- 游戏开始界面 -->
<div id="start-screen" class="screen">
<h2>准备开始</h2>
<p>使用方向键或 WASD 移动飞船</p>
<button id="start-button">开始游戏</button>
</div>
<!-- 游戏结束界面 -->
<div id="game-over-screen" class="screen hidden">
<h2>游戏结束</h2>
<p>你的分数: <span id="final-score">0</span></p>
<button id="restart-button">重新开始</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
style.css (样式设计)
这个文件负责美化游戏界面,使其看起来更专业,它使用了 Flexbox 布局来居中内容,并定义了不同屏幕的样式。
/* 全局样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background-color: #111;
color: #eee;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow: hidden; /* 防止页面滚动 */
}
/* 游戏主容器 */
.game-container {
text-align: center;
position: relative;
}
h1 {
margin-bottom: 10px;
color: #4CAF50;
}
/* 游戏信息 */
.game-info {
margin-bottom: 10px;
font-size: 1.2em;
}
#score, #high-score {
font-weight: bold;
color: #FFD700;
}
/* 画布样式 */
#gameCanvas {
background-color: #000;
border: 2px solid #333;
display: block; /* 移除画布下方的间隙 */
max-width: 100%; /* 响应式 */
height: auto;
}
/* 游戏屏幕(开始/结束) */
.screen {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.8);
padding: 30px;
border-radius: 10px;
border: 2px solid #4CAF50;
text-align: center;
}
.screen.hidden {
display: none;
}
.screen h2 {
margin-bottom: 20px;
color: #4CAF50;
}
.screen p {
margin-bottom: 20px;
font-size: 1.1em;
}
/* 按钮样式 */
button {
padding: 10px 20px;
font-size: 1.1em;
font-weight: bold;
color: #fff;
background-color: #4CAF50;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #45a049;
}
/* 移动端触摸控制区域 */
.touch-controls {
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
display: none; /* 默认隐藏,通过 JS 在移动端显示 */
}
.touch-button {
width: 60px;
height: 60px;
background-color: rgba(255, 255, 255, 0.1);
border: 2px solid #4CAF50;
border-radius: 50%;
color: #fff;
font-size: 24px;
margin: 0 5px;
display: inline-block;
text-align: center;
line-height: 56px;
user-select: none; /* 防止长选中文本 */
-webkit-user-select: none; /* Safari */
}
/* 响应式设计:移动端 */
@media (max-width: 768px) {
.touch-controls {
display: block;
}
#gameCanvas {
touch-action: none; /* 防止触摸时页面滚动 */
}
}
script.js (游戏逻辑)
这是游戏的核心,包含了所有游戏对象的定义、渲染、更新和交互逻辑。
// --- 全局变量 ---
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const startScreen = document.getElementById('start-screen');
const gameOverScreen = document.getElementById('game-over-screen');
const startButton = document.getElementById('start-button');
const restartButton = document.getElementById('restart-button');
const scoreElement = document.getElementById('score');
const highScoreElement = document.getElementById('high-score');
const finalScoreElement = document.getElementById('final-score');
// 设置画布尺寸
function resizeCanvas() {
canvas.width = 800;
canvas.height = 600;
// 在移动端,可以动态调整画布大小以适应屏幕
if (window.innerWidth < 768) {
canvas.width = window.innerWidth - 40;
canvas.height = window.innerHeight - 200;
}
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
// 游戏状态
let gameRunning = false;
let score = 0;
let highScore = localStorage.getItem('highScore') || 0;
highScoreElement.textContent = highScore;
// --- 游戏对象类 ---
// 玩家飞船类
class Player {
constructor() {
this.width = 50;
this.height = 50;
this.x = canvas.width / 2 - this.width / 2;
this.y = canvas.height - this.height - 20;
this.speed = 5;
this.color = '#4CAF50';
}
draw() {
ctx.fillStyle = this.color;
// 绘制一个简单的三角形作为飞船
ctx.beginPath();
ctx.moveTo(this.x + this.width / 2, this.y);
ctx.lineTo(this.x, this.y + this.height);
ctx.lineTo(this.x + this.width, this.y + this.height);
ctx.closePath();
ctx.fill();
}
update() {
// 移动逻辑在事件监听器中处理
}
}
// 障碍物类
class Obstacle {
constructor() {
this.width = Math.random() * 50 + 20;
this.height = Math.random() * 50 + 20;
this.x = Math.random() * (canvas.width - this.width);
this.y = -this.height;
this.speed = Math.random() * 3 + 2;
this.color = '#f44336';
}
draw() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
update() {
this.y += this.speed;
}
}
// --- 游戏逻辑函数 ---
let player;
let obstacles = [];
let animationId;
// 初始化游戏
function init() {
player = new Player();
obstacles = [];
score = 0;
scoreElement.textContent = score;
gameRunning = true;
}
// 游戏主循环
function gameLoop() {
if (!gameRunning) return;
// 1. 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 2. 更新和绘制玩家
player.update();
player.draw();
// 3. 更新和绘制障碍物
for (let i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].update();
obstacles[i].draw();
// 移除超出屏幕的障碍物
if (obstacles[i].y > canvas.height) {
obstacles.splice(i, 1);
score += 10; // 成功躲避加分
scoreElement.textContent = score;
}
// 4. 碰撞检测
if (checkCollision(player, obstacles[i])) {
endGame();
return; // 结束当前循环
}
}
// 5. 生成新障碍物
if (Math.random() < 0.02) { // 2% 的概率每帧生成一个
obstacles.push(new Obstacle());
}
// 6. 继续下一帧
animationId = requestAnimationFrame(gameLoop);
}
// 碰撞检测函数 (AABB - Axis-Aligned Bounding Box)
function checkCollision(rect1, rect2) {
return rect1.x < rect2.x + rect2.width &&
rect1.x + rect1.width > rect2.x &&
rect1.y < rect2.y + rect2.height &&
rect1.y + rect1.height > rect2.y;
}
// 结束游戏
function endGame() {
gameRunning = false;
cancelAnimationFrame(animationId);
finalScoreElement.textContent = score;
gameOverScreen.classList.remove('hidden');
// 更新最高分
if (score > highScore) {
highScore = score;
highScoreElement.textContent = highScore;
localStorage.setItem('highScore', highScore);
}
}
// --- 事件监听 ---
// 键盘控制
const keys = {};
window.addEventListener('keydown', (e) => {
keys[e.key] = true;
});
window.addEventListener('keyup', (e) => {
keys[e.key] = false;
});
// 在游戏循环中处理玩家移动
function handlePlayerMovement() {
if (!gameRunning) return;
if (keys['ArrowLeft'] || keys['a'] || keys['A']) {
player.x = Math.max(0, player.x - player.speed);
}
if (keys['ArrowRight'] || keys['d'] || keys['D']) {
player.x = Math.min(canvas.width - player.width, player.x + player.speed);
}
if (keys['ArrowUp'] || keys['w'] || keys['W']) {
player.y = Math.max(0, player.y - player.speed);
}
if (keys['ArrowDown'] || keys['s'] || keys['S']) {
player.y = Math.min(canvas.height - player.height, player.y + player.speed);
}
}
// 将移动处理集成到游戏循环中
const originalGameLoop = gameLoop;
gameLoop = function() {
handlePlayerMovement();
originalGameLoop();
};
// 触摸控制 (移动端)
let touchStartX = 0;
let touchStartY = 0;
canvas.addEventListener('touchstart', (e) => {
touchStartX = e.touches[0].clientX;
touchStartY = e.touches[0].clientY;
});
canvas.addEventListener('touchmove', (e) => {
e.preventDefault(); // 阻止页面滚动
if (!gameRunning) return;
const touchX = e.touches[0].clientX;
const touchY = e.touches[0].clientY;
const deltaX = touchX - touchStartX;
const deltaY = touchY - touchStartY;
player.x = Math.max(0, Math.min(canvas.width - player.width, player.x + deltaX));
player.y = Math.max(0, Math.min(canvas.height - player.height, player.y + deltaY));
touchStartX = touchX;
touchStartY = touchY;
});
// 按钮事件
startButton.addEventListener('click', () => {
startScreen.classList.add('hidden');
init();
gameLoop();
});
restartButton.addEventListener('click', () => {
gameOverScreen.classList.add('hidden');
init();
gameLoop();
});
如何使用这个模板
- 创建文件: 按照上面的文件结构创建
index.html,style.css, 和script.js三个文件。 - 复制代码: 将对应的代码块分别粘贴到三个文件中。
- 打开浏览器: 用浏览器打开
index.html文件。 - 开始游戏: 点击“开始游戏”按钮,你就可以用键盘方向键或 WASD 控制绿色飞船,躲避从上方掉落的红色障碍物了。
- 自定义修改:
- 修改游戏玩法: 在
script.js中,你可以改变Player和Obstacle类的属性(如大小、速度、颜色),或者修改gameLoop函数中的逻辑(增加子弹、敌人、道具等)。 - 修改美术风格: 在
style.css中修改颜色、字体;在script.js的draw方法中绘制更复杂的图形,或者加载图片来替代简单的形状。 - 调整难度: 修改
Obstacle类中的speed和生成概率 (Math.random() < 0.02) 来调整游戏难度。
- 修改游戏玩法: 在
这个模板为你提供了一个坚实的基础,你可以在此基础上尽情发挥,创造出属于你自己的精彩 HTML5 游戏!

(图片来源网络,侵删)

(图片来源网络,侵删)
