phaser3⼊门教程-从零开始开发⼀个打砖块游戏
项⽬代码
体验⼀下
空格开始,左右箭头控制移动
Phaser简介
是⼀个HTML5游戏框架。它使⽤了许多HTML5 API,例如Canvas,WebGL,Audio,Gamepad等,并添加了⼀些有⽤的逻辑,例如管理游戏循环并为我们提供了物理引擎。
使⽤Phaser,我们可以只⽤HTML,CSS和JavaScript来构建2D游戏。
项⽬需求
在使⽤Phaser构建Breakout克隆之前,让我们⾸先定义游戏的范围:
这款单⼈游戏具有30个积⽊,⼀个球拍和⼀个球的⼀个关卡
⽬标是让球摧毁所有积⽊,同时确保其不离开游戏画⾯的底部。
玩家将控制⼀个可左右移动的桨
该游戏是为桌⾯版⽹络⽤户打造的,因此将使⽤键盘进⾏输⼊
设置Phaser
Phaser是⼀个JavaScript库,要开发和玩我们的游戏,我们需要⼀些基本的HTML来加载JS。在⼀个⼯作区中创建⼀个名为breakout的⽬录。
python可以做什么游戏
在⽬录中创建以下⽂件和⽂件夹:
⼀个index.html⽂件
⼀个breakout.js⽂件
名为的⽂件夹 assets
在您的assets⽂件夹中,创建⼀个images⽂件夹
游戏资产是游戏使⽤的艺术品,声⾳,视频和其他数据。对于这个简单的Breakout克隆,没有多少资产需要使⽤⽂件夹进⾏组织。但是,优良作法是将资产与代码分开,并按类型将资产分开。
将以下代码添加到您的index.html⽂件中:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>Breakout</title>
<style>
html,
body {
margin: 0 auto;
padding: 0;
width: 100%;
height: 100%;
}
#game {
margin: 10px auto;
padding: 0;
width: 800px;
height: 640px;
}
</style>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="game"></div>
<script src="//cdn.jsdelivr/npm/phaser@3.17.0/dist/phaser.min.js"></script>
<script src="breakout.js"></script>
</body>
</html>
此基本HTML代码执⾏以下操作:
删除HTML和body标签中的浏览器边距和填充
添加⼀个game div元素,其中将包含我们的Breakout克隆
通过其CDN加载Phaser v3.17
加载breakout.js当前不执⾏任何操作但包含游戏逻辑的⽂件
为了使⽤Phaser有效开发游戏,我们需要将这些⽂件放到web服务器中运⾏。如果web服务器,出于安全原因,我们的浏览器将不允许我们的游戏脚本加载资产。
幸运的是,⽆需设置或即可获得运⾏中的Web服务器。如果使⽤ Code,则可以安装扩展。⼤多数IDE和⽂本编辑器都具有功能类似的插件。
如果您安装了Python版本3,则可以通过终端进⼊⼯作区并输⼊python3 -m http.server。还有其他CLI⼯具可提供简单的Web服务器,请选择⼀种可以为您提供最快时间开发游戏的⼯具。
最后,下载我们为此游戏创建的图像资产。将PNG⽂件复制并粘贴到images⽂件夹中。
创造我们的游戏世界
通过设置HTML和CSS,让我们编辑breakout.js⽂件以设置游戏世界。
开始Phaser
⾸先,我们需要配置Phaser并创建我们的Game实例。该的实例是Phaser游戏的中央控制器,它进⾏所有的设置和开始游戏循环。
让我们配置和创建Game实例:
// This object contains all the Phaser configurations to load our game
const config = {
type: Phaser.AUTO,
parent: 'game',
width: 800,
heigth: 640,
scale: {
mode: Phaser.Scale.RESIZE,
autoCenter: Phaser.Scale.CENTER_BOTH
},
scene: {
preload,
create,
update,
},
physics: {
default: 'arcade',
arcade: {
gravity: false
},
}
};
// Create the game instance
const game = new Phaser.Game(config);
该type属性告诉Phaser使⽤什么渲染器。Phaser可以使⽤HTML5的或元素来渲染我们的游戏。通过将类型设置为Phaser.AUTO,我们告诉Phaser⾸先尝试使⽤WebGL进⾏渲染,如果失败,则使⽤Canvas进⾏渲染。
该parent属性表⽰将要玩我们的游戏的HTML元素的ID。我们使⽤width和定义游戏尺⼨(以像素为单位)height。该scale对象为我们做两件事:mode告诉Phaser如何使⽤⽗元素的空间,在这种情况下,我们确保游戏适合⽗元素的⼤⼩div
autoCenter告诉Phaser div如果需要的话,如何在我们的⽗级中居中游戏。在这种情况下,我们将游戏在⽗div内垂直和⽔平居中。当游戏不占据⽗对象的整个空间时,此属性会更有⽤。
在Phaser中,我们的游戏逻辑在中定义Scenes。将场景视为游戏中的各种状态:标题屏幕是⼀个场景,
游戏的每个级别将是它们⾃⼰的场景,剪切场景将是它⾃⼰的场景,等等。Phaser提供了对象,但它也可以与含有常规的JavaScript对象preload(),create()和update()定义的函数。
最后⼀个配置告诉Phaser要使⽤哪个物理引擎。Phaser可以使⽤3种不同的物理引擎:,和。Arcade是最简单的⼊门游戏,⾜以满⾜我们的游戏需求。
Breakout 不需要重⼒即可⼯作,因此我们在物理引擎中禁⽤了该属性。如果我们要构建Platform游戏,则可能会启⽤重⼒,这样当我们的玩家跳跃时,他们会⾃然地掉回地⾯。为了确保我们的游戏设置⼯作,我们需要添加preload(),create()和update()功能。创建游戏实例后,向其中添加以下空⽩函数:
function preload() { }
function create() { }
function update() { }
在Web服务器运⾏的情况下,导航到运⾏游戏的页⾯。您应该看到⼀个空⽩屏幕,如下所⽰:
加载资产
该游戏中的资产包括5张图⽚。在您可能创建的其他游戏中,您的资产可能⾮常庞⼤。⾼清晰图像,⾳频和视频⽂件可能会占⽤兆字节的空间。资产越⼤,负担越长。因此,Phaser具有⼀项preload()功能,我们可以在开始运⾏游戏之前加载所有资产。
将preload()函数更改为以下内容,以便我们可以在游戏循环开始之前加载图像:
function preload() {
this.load.image('ball', 'assets/images/ball_32_32.png');
this.load.image('paddle', 'assets/images/paddle_128_32.png');
this.load.image('brick1', 'assets/images/brick1_64_32.png');
this.load.image('brick2', 'assets/images/brick2_64_32.png');
this.load.image('brick3', 'assets/images/brick3_64_32.png');
}
第⼀个参数是稍后将⽤来引⽤图像的键,第⼆个参数是图像的位置。
注: -当我们⽤this我们的preload(),create()和update()功能,我们指的是由之前创建的游戏实例game。
加载图像后,我们想在屏幕上放置精灵。在的顶部breakout.js,添加以下将包含我们的精灵数据的变量:
let player, ball, violetBricks, yellowBricks, redBricks, cursors;
⼀旦全局定义它们,我们所有的函数都可以使⽤它们。
添加精灵
sprite 是游戏场景中任何2D图像。在Phaser中,sprite 会封装图像以及其位置,速度,物理属性和其他属性。⾸先,通过create()函数创建player精灵:
player = this.physics.add.sprite(
400, // x position
600, // y position
'paddle', // key of image for the sprite
);
您现在应该可以在屏幕上看到⼀个桨:
该sprite()⽅法的第⼀个参数是X放置精灵的坐标。第⼆个参数是Y坐标,最后⼀个参数是preload()函数中添加的图像资产的键。
了解phaser和⼤多数2D游戏框架如何使⽤坐标很重要。我们在学校学到的图形通常将原点即点(0,0)置于中⼼。在Phaser中,原点位于屏幕的左上⽅。随着x增长,我们实际上正在向右移动。随着y增加,我们正在向下移动。
我们的游戏的宽度为800像素,⾼度为640像素,因此我们的游戏坐标如下所⽰:
让我们将球添加到Player上⽅。将以下代码添加到该create()函数:
ball = this.physics.add.sprite(
400, // x position
565, // y position
'ball' // key of image for the sprite
);
由于球上⾯我们的Player,在坐标y的值是低⽐玩家的Y坐标。
添加精灵组
虽然Phaser可以轻松添加sprite,但如果必须分别定义每个sprite,将很快变得乏味。Breakout中的砖块⼏乎相同。位置不同,但是它们的属性(例如颜⾊以及它们与球的交互⽅式)是相同的。我们可以创建精灵组来更好地管理它们,⽽不是创建30个砖精灵对象。
让我们通过create()函数添加第⼀排紫⾊砖:
// Add violet bricks
violetBricks = this.up({
key: 'brick1',
repeat: 9,
setXY: {
x: 80,
y: 140,
stepX: 70
}
});
代替this.physics.add.sprite()我们使⽤this.up()并传递⼀个JavaScript对象。key属性引⽤sprite组中所有sprite将使⽤的图像键。该repeat属性告诉Phaser再创建多少个精灵。每个精灵组都创建⼀个精灵。随着repeat设置为9,Phaser将创建⼀个精灵组10个精灵。该setXY对象具有三个有趣的属性:
x是第⼀个精灵的X坐标
y是第⼆个精灵的Y坐标
stepX是x轴上重复的精灵之间的像素长度。
也有⼀个stepY属性,但是我们不需要在游戏中使⽤它。让我们为砖添加另外两个剩余的精灵组:
// Add yellow bricks
yellowBricks = this.up({
key: 'brick2',
repeat: 9,
setXY: {
x: 80,
y: 90,
stepX: 70
}
});
// Add red bricks
redBricks = this.up({
key: 'brick3',
repeat: 9,
setXY: {
x: 80,
y: 40,
stepX: 70
}
});
我们的游戏已经整合在⼀起,您的屏幕应如下所⽰: