使用Phaser.js开发简易跑酷游戏:从创建到源码解析
本文详细介绍如何使用Phaser.js框架结合Arcade物理引擎开发一款简单的横版跑酷游戏。内容涵盖游戏舞台创建、资源加载、场景构建、键盘监听、碰撞检测及更新逻辑的实现。文章附带完整JavaScript源码及GitHub链接,适合前端开发者入门游戏开发。
Phaser.js跑酷游戏开发概述
本项目基于Phaser.js引擎进行开发。
Phaser.js官方网址为:http://phaser.io/。
关于该引擎的详细介绍此处省略,因作者自身也是初学者。
游戏运行效果展示如下:

完整源代码(包含详细的图片与资源文件)可通过点击文章下方或屏幕右上方的GitHub链接进行克隆获取。
第一步:创建游戏舞台。
游戏舞台与配置初始化
var config = {
type: Phaser.AUTO,
width: 800,
height: 400,
physics: {
default: 'arcade',
arcade: {
gravity: {
y: 300
},
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
var game = new Phaser.Game(config); // 创建游戏
第二步:加载所需的游戏资源。
游戏资源加载流程
function preload() {
this.load.image('sky', 'assets/sky.png');
this.load.image('ground', 'assets/platform.png');
5 6 this.load.spritesheet('dude', 'assets/dude.png', {
frameWidth: 32,
frameHeight: 48
});
}
第三步:将加载的资源渲染至游戏舞台。
场景构建与对象创建
var distanceText; // 路程文本
var distance = 0; // 路程
var platforms; // 地面
var player; // 玩家
var enemy; // 敌人
var enemys; // 敌人们
var enemyTimer; // 敌人计时器
var distanceTimer; // 路程计时器
function create() {
// 添加画布背景
this.add.image(400, 200, 'sky');
// 添加分数文本
distanceText = this.add.text(16, 16, 'Distance: 0m', {
fontSize: '20px',
fill: '#000'
});
// 添加地面
platforms = this.physics.add.staticGroup();
platforms.create(400, 400, 'ground').setScale(3).refreshBody();
// 添加玩家(精灵)
player = this.physics.add.sprite(100, 300, 'dude');
player.setBounce(0); // 设置阻力
player.setCollideWorldBounds(true); // 禁止玩家走出世界
// 敌人
enemys = this.physics.add.group();
enemys.children.iterate(function (child) {
child.setCollideWorldBounds(false);
});
// 动态创建敌人
enemyTimer = setInterval(function () {
enemy = enemys.create(1000, 300, 'dude');
enemy.setTint(getColor());
enemy.anims.play('left', true);
enemy.setVelocityX(Phaser.Math.Between(-300, -100));
}, Phaser.Math.Between(4000, 8000))
distanceTimer = setInterval(function () {
distance += 1;
distanceText.setText('Distance: ' + distance + 'm');
}, 1000)
this.physics.add.collider(player, platforms); //玩家在地面上
this.physics.add.collider(enemys, platforms); //敌人在地面上
this.physics.add.collider(player, enemys, hitBomb, null, this);
}
第四步:在场景构建过程中编写键盘监听事件。
键盘输入与动画控制
var cursors; // 按键
// 事件
this.anims.create({
key: 'left',
frames: this.anims.generateFrameNumbers('dude', {
start: 0,
end: 3
}),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'right',
frames: this.anims.generateFrameNumbers('dude', {
start: 5,
end: 8
}),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'turn',
frames: [{
key: 'dude',
frame: 4
}],
frameRate: 20
});
cursors = this.input.keyboard.createCursorKeys();
第五步:编写碰撞检测函数,处理玩家与敌人碰撞后的逻辑结果。
碰撞检测与游戏结束逻辑
var gameOver = false; // 游戏结束
function hitBomb(player, enemys) {
this.physics.pause();
clearInterval(enemyTimer);
clearInterval(distanceTimer);
player.setTint(0xff0000);
gameOver = true;
alert('游戏结束,您跑了' + distance + 'm');
}
第六步:在update函数中编写每帧执行的逻辑(需注意,此函数每帧执行,1帧并不等于1秒)。
游戏主循环与更新逻辑
function update() {
if (cursors.up.isDown && player.body.touching.down) {
player.setVelocityY(-220);
} else {
player.anims.play('right', true);
}
if (gameOver) {
player.setVelocityX(0);
player.anims.play('turn');
return;
}
}
此处为敌人设置了随机生成的16进制颜色。
敌人颜色生成机制
function getColor() {
var color = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"].sort(function(){
return Math.random() - 0.5
}).join("").substr(0,6);
return "0x" + color;
}
以下是完整的源代码(建议前往GitHub自行克隆):
完整源码结构说明
var config = {
type: Phaser.AUTO,
width: 800,
height: 400,
physics: {
default: 'arcade',
arcade: {
gravity: {
y: 300
},
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
var game = new Phaser.Game(config); // 创建游戏
var distanceText; // 路程文本
var distance = 0; // 路程
var platforms; // 地面
var player; // 玩家
var enemy; // 敌人
var enemys; // 敌人们
var gameOver = false; // 游戏结束
var enemyTimer; // 敌人计时器
var distanceTimer; // 路程计时器
var cursors; // 按键
// 载入资源
function preload() {
this.load.image('sky', 'assets/sky.png');
this.load.image('ground', 'assets/platform.png');
39 40 this.load.spritesheet('dude', 'assets/dude.png', {
frameWidth: 32,
frameHeight: 48
});
}
// 将资源展示到画布创建资源
function create() {
// 添加画布背景
this.add.image(400, 200, 'sky');
// 添加分数文本
distanceText = this.add.text(16, 16, 'Distance: 0m', {
fontSize: '20px',
fill: '#000'
});
// 添加地面
platforms = this.physics.add.staticGroup();
platforms.create(400, 400, 'ground').setScale(3).refreshBody();
// 添加玩家(精灵)
player = this.physics.add.sprite(100, 300, 'dude');
player.setBounce(0); // 设置阻力
player.setCollideWorldBounds(true); // 禁止玩家走出世界
// 敌人
enemys = this.physics.add.group();
enemys.children.iterate(function (child) {
child.setCollideWorldBounds(false);
});
// 事件
this.anims.create({
key: 'left',
frames: this.anims.generateFrameNumbers('dude', {
start: 0,
end: 3
}),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'right',
frames: this.anims.generateFrameNumbers('dude', {
start: 5,
end: 8
}),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'turn',
frames: [{
key: 'dude',
frame: 4
}],
frameRate: 20
});
cursors = this.input.keyboard.createCursorKeys();
// 动态创建敌人
enemyTimer = setInterval(function () {
enemy = enemys.create(1000, 300, 'dude');
enemy.setTint(getColor());
enemy.anims.play('left', true);
enemy.setVelocityX(Phaser.Math.Between(-300, -100));
}, Phaser.Math.Between(4000, 8000))
distanceTimer = setInterval(function () {
distance += 1;
distanceText.setText('Distance: ' + distance + 'm');
}, 1000)
this.physics.add.collider(player, platforms); //玩家在地面上
this.physics.add.collider(enemys, platforms);
this.physics.add.collider(player, enemys, hitBomb, null, this);
}
// 一直执行
function update() {
if (cursors.up.isDown && player.body.touching.down) {
player.setVelocityY(-220);
} else {
player.anims.play('right', true);
}
if (gameOver) {
player.setVelocityX(0);
player.anims.play('turn');
return;
}
}
function hitBomb(player, enemys) {
this.physics.pause();
clearInterval(enemyTimer);
clearInterval(distanceTimer);
player.setTint(0xff0000);
gameOver = true;
alert('游戏结束,您跑了' + distance + 'm');
}
function getColor() {
var color = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"].sort(function(){
return Math.random() - 0.5
}).join("").substr(0,6);
return "0x" + color;
}
GitHub仓库地址:Fuck me on GitHub Fuck me on GitHub。
总结。
以上即为Phaser.js实现简单跑酷游戏的完整教程及源码下载内容,希望对你有帮助。如有任何疑问,欢迎留言,小编会及时回复。非常感谢大家对本站的支持!
JS动态构建复杂嵌套JSON对象的方法
2026-11-05 15:41:52
JS负数取余为什么是负数?详解余数与模运算区别
2026-11-05 13:34:41
JS 解压出现乱码或报错怎么解决?
2026-11-05 12:32:38
JS 中 startsWith、indexOf 与正则判断字符串前缀的对比
2026-11-04 22:19:43
JS解析Excel后怎么将数据转换为JSON格式
2026-11-04 20:58:28
