如何制作我的第一个Phaser.js游戏

Phaser.js是一款JavaScript语言的网页游戏框架。它简洁易用、跨平台、功能强大、性能良好,是不可多得的游戏制作工具。

一、工具与代码模板

首先,我们需要一个在线编辑器。这里推荐使用菜鸟的前端工具:HTML/CSS/JS 在线工具 | 菜鸟工具

在打开的工具里,HTML一栏,输入下面的代码:

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/phaser@3.15.1/dist/phaser-arcade-physics.min.js"></script>
</head>
<body>

    <script>

    </script>

</body>
</html>

这段代码可以用作模板,引用了一个CDN上的phaser库。我们后来要写的代码需要添加到<script></script>之间。

二、基本代码结构

Phaser代码的基本结果如下:

var config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

var game = new Phaser.Game(config);

function preload ()
{
}

function create ()
{
}

function update ()
{
}

将上述代码放到模板中的<script></script>之间后,在线工具的效果预览处,将出现游戏的黑屏效果,上面暂时没有其他东西,是因为我们什么都没有往里面加。

三、加载图片

首先,我们把本课程要用到的图片上传到了这里,它们的路径如下:

1. 炸弹bomb: https://img-blog.csdnimg.cn/d21caf1056a14bc19e8476649a26539f.png

2. 星星star: https://img-blog.csdnimg.cn/61cad081ae31499e96a6e07327758328.png

3. 天空sky: https://img-blog.csdnimg.cn/019871af78a94614a90011defa9de90a.png

4. 地面/平台 ground: https://img-blog.csdnimg.cn/e21ef7cc9a4e4665892fed352efdbe33.png

5. 游戏角色 dude: https://img-blog.csdnimg.cn/421cc50b0bf04982b387e344c1a0c9d5.png

有了上面的图片后,我们可以在preload函数中,添加下面的代码了:

function preload ()
{
    this.load.image('sky', 'https://img-blog.csdnimg.cn/019871af78a94614a90011defa9de90a.png');
    this.load.image('ground', 'https://img-blog.csdnimg.cn/e21ef7cc9a4e4665892fed352efdbe33.png');
    this.load.image('star', 'https://img-blog.csdnimg.cn/61cad081ae31499e96a6e07327758328.png');
    this.load.image('bomb', 'https://img-blog.csdnimg.cn/d21caf1056a14bc19e8476649a26539f.png');
    this.load.spritesheet('dude', 
        'https://img-blog.csdnimg.cn/421cc50b0bf04982b387e344c1a0c9d5.png',
        { frameWidth: 32, frameHeight: 48 }
    );
}

在create函数中添加下面的代码,就能出来基本的天空和星星图片了:

function create ()
{
    this.add.image(400, 300, 'sky');
    this.add.image(400, 300, 'star');
}

四、添加地面平台

我们给游戏中所有地面、平台编到一个组里,它们都是静止的东西,位置不相同而已。

如下面的代码,创建全局变量platforms,再替换一下create函数里的内容:

var platforms;

function create ()
{
    this.add.image(400, 300, 'sky');

    platforms = this.physics.add.staticGroup();

    platforms.create(400, 568, 'ground').setScale(2).refreshBody();

    platforms.create(600, 400, 'ground');
    platforms.create(50, 250, 'ground');
    platforms.create(750, 220, 'ground');
}

为了能够正常运行,还需要修改一下前面已经添加过的游戏config变量。需要配置一下physics属性:

var config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 300 },
            debug: false
        }
    },
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

这时,便有了几个平台一样的东西出现在游戏里了。

五、添加游戏角色

继续在create函数里添加创建player的代码,如下:

player = this.physics.add.sprite(100, 450, 'dude');

player.setBounce(0.2);
player.setCollideWorldBounds(true);

this.anims.create({
    key: 'left',
    frames: this.anims.generateFrameNumbers('dude', { start: 0, end: 3 }),
    frameRate: 10,
    repeat: -1
});

this.anims.create({
    key: 'turn',
    frames: [ { key: 'dude', frame: 4 } ],
    frameRate: 20
});

this.anims.create({
    key: 'right',
    frames: this.anims.generateFrameNumbers('dude', { start: 5, end: 8 }),
    frameRate: 10,
    repeat: -1
});

player.body.setGravityY(300);

this.physics.add.collider(player, platforms);

其中player.setBounce(0.2);设置角色的弹跳系数,接近0时弹跳次数越少,设为1时永远不停地弹。player.setCollideWorldBounds(true);设置角色碰到世界的边界时是否检测碰到,是否将角色活动范围局限于可视的世界中。后面的三段代码分别创建一个动画:按下左键、转身、按下右键时的帧,分别为dude图片中的编号为0-3、4、5-8帧。

接下来的两行,player.body.setGravityY(300)可以为角色单独设置一个向下的重力,this.physics.add.collider(player, platforms);为物理世界添加了一个角色和平台之间的碰撞检测,有了这行代码,角色才能站立在平台和地面上,否则会往下面掉。

六、用键盘控制角色移动

这时需要让角色动起来了!我们用下面的代码:

cursors = this.input.keyboard.createCursorKeys();

if (cursors.left.isDown)
{
    player.setVelocityX(-160);

    player.anims.play('left', true);
}
else if (cursors.right.isDown)
{
    player.setVelocityX(160);

    player.anims.play('right', true);
}
else
{
    player.setVelocityX(0);

    player.anims.play('turn');
}

if (cursors.up.isDown && player.body.touching.down)
{
    player.setVelocityY(-330);
}

有了这段代码,角色可以左右走动,也可以跳跃上平台了。如果跳不上去,可以酌情修改一下前面设置的角色的重力。

七、添加星星

首先,生成一批星星从上方掉下来,为每一颗设置随机的弹跳系数,这样看起来会更有意思一些。

stars = this.physics.add.group({
    key: 'star',
    repeat: 11,
    setXY: { x: 12, y: 0, stepX: 70 }
});

stars.children.iterate(function (child) {

    child.setBounceY(Phaser.Math.FloatBetween(0.4, 0.8));

});

this.physics.add.collider(stars, platforms);

function collectStar (player, star)
{
    star.disableBody(true, true);
}

this.physics.add.overlap(player, stars, collectStar, null, this);

一番操作后,移动角色,就可以摘到星星了。this.physics.add.collider(stars, platforms);指明了星星会掉落到平台上,而不会一直往下掉;this.physics.add.overlap(player, stars, collectStar, null, this); 可以让角色碰到星星时,执行一个叫collectStar的函数,这个函数里仅仅将触碰到的星星禁用隐藏了。

八、显示分数

如果能够显示即时分数,那就更好了!那就干活吧!

首先,定义两个全局变量,一个定义分数,一个定义显示的文本。

var score = 0;
var scoreText;

在create函数里,添加上这么一行:

scoreText = this.add.text(16, 16, 'score: 0', { fontSize: '32px', fill: '#000' });

这表示在游戏中加上一个文本显示。

在collectStar函数中,添加分数增加的代码,最后如下:

function collectStar (player, star)
{
    star.disableBody(true, true);

    score += 10;
    scoreText.setText('Score: ' + score);
}

这时应该能够显示分数了。

九、增加炸弹

为了增强游戏的趣味性与挑战性,我们决定加上一个炸弹的元素。

继续在create函数代码上,增加这么几行:

bombs = this.physics.add.group();

this.physics.add.collider(bombs, platforms);

function hitBomb (player, bomb)
{
    this.physics.pause();

    player.setTint(0xff0000);

    player.anims.play('turn');

    gameOver = true;
}

this.physics.add.collider(player, bombs, hitBomb, null, this);

这段代码表示炸弹这个“组”加进来,也会与平台进行碰撞检测,弹跳。当角色碰到炸弹时,执行hitBomb函数,这时物理世界会暂停,角色变为红色,动画为正面像,gameOver变量为true。

 刚才的代码只添加了bombs这个“组”,里面还没有炸弹呢。单个的炸弹什么时候出现呢?

我们决定在每一轮的星星接完之后出现一个新的炸弹。因此,把collectStar函数修改成下面这样,让每一次活跃的星星数为0时,重新将所有星星激活,移到屏幕上方再掉下来。与此同时,让炸弹“组”中随机产生一个炸弹,炸弹出现的位置为远离角色的一侧。

function collectStar (player, star)
{
    star.disableBody(true, true);

    score += 10;
    scoreText.setText('Score: ' + score);

    if (stars.countActive(true) === 0)
    {
        stars.children.iterate(function (child) {

            child.enableBody(true, child.x, 0, true, true);

        });

        var x = (player.x < 400) ? Phaser.Math.Between(400, 800) : Phaser.Math.Between(0, 400);

        var bomb = bombs.create(x, 16, 'bomb');
        bomb.setBounce(1);
        bomb.setCollideWorldBounds(true);
        bomb.setVelocity(Phaser.Math.Between(-200, 200), 20);

    }
}

到这里,游戏基本就能正常运行了!让我们一起来玩一玩吧! 

最後,讓我們爲遊戲添加更多的角色,制造出更多的豐富劇情的玩法吧!

圖片库:

1. 苹果:https://img-blog.csdnimg.cn/cf225c2c58d04418801a94731396a538.png

2. 小球:https://img-blog.csdnimg.cn/3d9310cc81ae4b54a493bd9cfcbfb762.png

 

3. 箱子:https://img-blog.csdnimg.cn/d6c36861fae04c06975921cb1deec321.png

 

4. 硬币:https://img-blog.csdnimg.cn/b1be2aef067c432c923e40d6a7edea29.png

 

5. 爆炸:https://img-blog.csdnimg.cn/2b34bf82a0644f58befafa49df2c309d.png

 

6. 神:https://img-blog.csdnimg.cn/f8a370b3056c44d3b3504bb1b76885f7.png

 

7. 西瓜:https://img-blog.csdnimg.cn/a9ddb4bf552546c580831488c1da0dc8.png

 

8. 钻石:https://img-blog.csdnimg.cn/a3cd5c703f744fd4a607d8f25e2384e4.png

 

9. 箭头:https://img-blog.csdnimg.cn/a9af71a0d7c543a1b25d2ba9dede2d46.png

 

10. 水果:https://img-blog.csdnimg.cn/fdd3034494aa40e89be3d3ad36a75534.png

 

 

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值