HTML5 游戏框架-Phaser 教程

4,023 阅读15分钟
入门教程,我可不会讲什么概念,我只会讲一个入门例子,通过这个例子,你就知道phaser有多么强大,而照着这个例子做,你就能知道怎么使用phaser了。需要说明的是,这个就是phaser官方的一个入门的案例!做这个游戏需要多长时间,我可以告诉你,用phaser,只需要十分钟,下面就来一步一步进行游戏的实现。首先第一步,搭建环境:
<!DOCTYPE html>
<head>
         <meta charset="UTF-8" />
         <title>exam1</title>
    <script src="../phaser.min.js"></script>
</head>
<body>
 
<script>
 
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
 
function preload() {
    console.log('preload');
}
 
function create() {
    console.log('create');
}
 
function update() {
    console.log('update');
}
 
</script>
 
</body>
我不知道你有没有用过unity3d或者cocos2d,那时候要搭建一个环境是多么地复杂,而phaser,是需要引入一个js文件,是的,就这样环境就搭建好了。就是上面这个html页面,在浏览器中打开,你会看到控制台的输出,preload用来加载一些资源,create用来进行一些对象的创建及初始化,update就是游戏的主循环。接下来,我们来点东西:
<!DOCTYPE html>
<head>
         <meta charset="UTF-8" />
         <title>exam2</title>
    <script src="../phaser.min.js"></script>
</head>
<body>
 
<script>
 
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
 
function preload() {
    game.load.image('sky', 'assets/sky.png');
    game.load.image('ground', 'assets/platform.png');
    game.load.image('star', 'assets/star.png');
    game.load.spritesheet('dude', 'assets/dude.png', 32, 48);
}
 
function create() {
    game.add.sprite(0, 0, 'star');
}
 
function update() {
    console.log('update');
}
 
</script>
 
</body>
这时候,你可以看到左上角上有一颗星星,我们在preload中,将phaser需要使用到的资源加载进来,这里包括一些图片可一些序列帧。然后,我们通过game.add.sprite(0, 0, 'star');就可以把一个精灵显示在游戏区域的(0,0)点了。
但是一个星星似乎没什么意思,接下来我们来绘制一下游戏场景,让游戏看起来有点雏形:
<!DOCTYPE html>
<head>
         <meta charset="UTF-8" />
         <title>exam3</title>
    <script src="../phaser.min.js"></script>
</head>
<body>
 
<script>
 
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
 
function preload() {
    game.load.image('sky', 'assets/sky.png');
    game.load.image('ground', 'assets/platform.png');
    game.load.image('star', 'assets/star.png');
    game.load.spritesheet('dude', 'assets/dude.png', 32, 48);
}
 
var platforms;
function create() {
 
    game.physics.startSystem(Phaser.Physics.ARCADE);
    game.add.sprite(0, 0, 'sky');
    platforms = game.add.group();
    platforms.enableBody = true;
    var ground = platforms.create(0, game.world.height - 64, 'ground');
    ground.scale.setTo(2, 2);
    ground.body.immovable = true;
    var ledge = platforms.create(400, 400, 'ground');
    ledge.body.immovable = true;
    ledge = platforms.create(-150, 250, 'ground');
    ledge.body.immovable = true;
}
 
function update() {
    console.log('update');
}
 
</script>
 
</body>
这里,我们开启了物理引擎,当然,这只是为了后面做准备。然后,我们创建了天空,大地和两个平板。大地和平板的位置定位,我们是通过坐标来进行的,大家可以仔细看一下图片大小及坐标位置的关系。其中,大地和两个平板都被加到了platforms这个组中,这个组我们为它启动了物理属性,然后我们设置了大地和两个平板是不能动的,这样他们就不会由于撞击被改变位置。这样,我们的游戏场景就加进来了,接下来,我们来加入一个小人,这个小人也是我们游戏的主角:
<!DOCTYPE html>
<head>
         <meta charset="UTF-8" />
         <title>exam4</title>
    <script src="../phaser.min.js"></script>
</head>
<body>
 
<script>
 
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
 
function preload() {
    game.load.image('sky', 'assets/sky.png');
    game.load.image('ground', 'assets/platform.png');
    game.load.image('star', 'assets/star.png');
    game.load.spritesheet('dude', 'assets/dude.png', 32, 48);
}
 
var platforms;
var player;
function create() {
 
    game.physics.startSystem(Phaser.Physics.ARCADE);
    game.add.sprite(0, 0, 'sky');
    platforms = game.add.group();
    platforms.enableBody = true;
    var ground = platforms.create(0, game.world.height - 64, 'ground');
    ground.scale.setTo(2, 2);
    ground.body.immovable = true;
    var ledge = platforms.create(400, 400, 'ground');
    ledge.body.immovable = true;
    ledge = platforms.create(-150, 250, 'ground');
    ledge.body.immovable = true;
   
    player = game.add.sprite(32, game.world.height - 150, 'dude');
    game.physics.arcade.enable(player);
    player.body.bounce.y = 0.2;
    player.body.gravity.y = 300;
    player.body.collideWorldBounds = true;
    player.animations.add('left', [0, 1, 2, 3], 10, true);
    player.animations.add('right', [5, 6, 7, 8], 10, true);
}
 
function update() {
    console.log('update');
}
 
</script>
 
</body>

同样是通过game.add.sprite将精灵加入进来,但是大家仔细看看dude.png这张资源图片,这是一个帧动画序列,里面包含了小人左移和右移的动画帧。我们同样给它开启了物理属性,然后设置了它的弹性和重力。player.body.collideWorldBounds = true;这句话设置了它会与边界进行碰撞,这就是为什么小人落下的时候,到游戏区域边界就不会掉下去,大家可以把这句话注释掉再运行,看看会是什么情况。在这里,我们还为小人添加了两个动画,一个是向左移动,一个是向右移动,分别指定了响应的动画帧,这也是为后续的动画做准备。


但是小人还没有站在地上,接下来,我们来让小人站在地上:

<!DOCTYPE html>
<head>
         <meta charset="UTF-8" />
         <title>exam5</title>
    <script src="../phaser.min.js"></script>
</head>
<body>
 
<script>
 
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
 
function preload() {
    game.load.image('sky', 'assets/sky.png');
    game.load.image('ground', 'assets/platform.png');
    game.load.image('star', 'assets/star.png');
    game.load.spritesheet('dude', 'assets/dude.png', 32, 48);
}
 
var platforms;
var player;
function create() {
 
    game.physics.startSystem(Phaser.Physics.ARCADE);
    game.add.sprite(0, 0, 'sky');
    platforms = game.add.group();
    platforms.enableBody = true;
    var ground = platforms.create(0, game.world.height - 64, 'ground');
    ground.scale.setTo(2, 2);
    ground.body.immovable = true;
    var ledge = platforms.create(400, 400, 'ground');
    ledge.body.immovable = true;
    ledge = platforms.create(-150, 250, 'ground');
    ledge.body.immovable = true;
   
    player = game.add.sprite(32, game.world.height - 150, 'dude');
    game.physics.arcade.enable(player);
    player.body.bounce.y = 0.2;
    player.body.gravity.y = 300;
    player.body.collideWorldBounds = true;
    player.animations.add('left', [0, 1, 2, 3], 10, true);
    player.animations.add('right', [5, 6, 7, 8], 10, true);
}
 
function update() {
    game.physics.arcade.collide(player, platforms);
}
 
</script>
 
</body>


是不是很惊讶?要让小人站在地上,只要在update中加上一句,game.physics.arcade.collide(player, platforms);就可以了,这句话表示,检测小人与platforms组的碰撞,而大地正是在platforms组中,这样,小人就不会穿过大地了。同样地,当小人与两个平板碰撞时,也不会穿过了。


但是这小人还傻傻地不能动,接下来,就让小人动起来:

<!DOCTYPE html>
<head>
         <meta charset="UTF-8" />
         <title>exam6</title>
    <script src="../phaser.min.js"></script>
</head>
<body>
 
<script>
 
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
 
function preload() {
    game.load.image('sky', 'assets/sky.png');
    game.load.image('ground', 'assets/platform.png');
    game.load.image('star', 'assets/star.png');
    game.load.spritesheet('dude', 'assets/dude.png', 32, 48);
}
 
var platforms;
var player;
var cursors;
function create() {
 
    game.physics.startSystem(Phaser.Physics.ARCADE);
    game.add.sprite(0, 0, 'sky');
    platforms = game.add.group();
    platforms.enableBody = true;
    var ground = platforms.create(0, game.world.height - 64, 'ground');
    ground.scale.setTo(2, 2);
    ground.body.immovable = true;
    var ledge = platforms.create(400, 400, 'ground');
    ledge.body.immovable = true;
    ledge = platforms.create(-150, 250, 'ground');
    ledge.body.immovable = true;
   
    player = game.add.sprite(32, game.world.height - 150, 'dude');
    game.physics.arcade.enable(player);
    player.body.bounce.y = 0.2;
    player.body.gravity.y = 300;
    player.body.collideWorldBounds = true;
    player.animations.add('left', [0, 1, 2, 3], 10, true);
    player.animations.add('right', [5, 6, 7, 8], 10, true);
   
    cursors = game.input.keyboard.createCursorKeys();
}
 
function update() {
    game.physics.arcade.collide(player, platforms);
   
    player.body.velocity.x = 0;
    if (cursors.left.isDown)
    {
        player.body.velocity.x = -150;
        player.animations.play('left');
    }
    else if (cursors.right.isDown)
    {
        player.body.velocity.x = 150;
        player.animations.play('right');
    }
    else
    {
        player.animations.stop();
        player.frame = 4;
    }
    if (cursors.up.isDown && player.body.touching.down)
    {
        player.body.velocity.y = -350;
    }
}
 
</script>
 
</body>


我们希望让小人在按下方向左键的时候,向左移动,按下方向右键的时候,向右移动,为了实现这一功能,我们又定义了一个cursors,我们通过cursors = game.input.keyboard.createCursorKeys();来获取系统的键盘输入对象。然后,我们在update中,通过cursors.left.isDown来判断用户是否按下了键盘左键,如果按下了,我们给小人设置一个速度,然后播放左移的动画,方向右键的逻辑是一样的。如果方向左键和右键都没有按下,那么我们就通过player.frame来设置小人停在第4帧。小人的跳跃是通过方向上键来实现的,但是这里有一个条件,就是小人在空中的时候,不允许跳跃,所以,加上了一个player.body.touching.down的判断条件。

一个小人在这个场景中动,也没啥意思,不如加点东西:

<!DOCTYPE html>
<head>
         <meta charset="UTF-8" />
         <title>exam7</title>
    <script src="../phaser.min.js"></script>
</head>
<body>
 
<script>
 
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
 
function preload() {
    game.load.image('sky', 'assets/sky.png');
    game.load.image('ground', 'assets/platform.png');
    game.load.image('star', 'assets/star.png');
    game.load.spritesheet('dude', 'assets/dude.png', 32, 48);
}
 
var platforms;
var player;
var cursors;
var stars;
function create() {
 
    game.physics.startSystem(Phaser.Physics.ARCADE);
    game.add.sprite(0, 0, 'sky');
    platforms = game.add.group();
    platforms.enableBody = true;
    var ground = platforms.create(0, game.world.height - 64, 'ground');
    ground.scale.setTo(2, 2);
    ground.body.immovable = true;
    var ledge = platforms.create(400, 400, 'ground');
    ledge.body.immovable = true;
    ledge = platforms.create(-150, 250, 'ground');
    ledge.body.immovable = true;
   
    player = game.add.sprite(32, game.world.height - 150, 'dude');
    game.physics.arcade.enable(player);
    player.body.bounce.y = 0.2;
    player.body.gravity.y = 300;
    player.body.collideWorldBounds = true;
    player.animations.add('left', [0, 1, 2, 3], 10, true);
    player.animations.add('right', [5, 6, 7, 8], 10, true);
   
    cursors = game.input.keyboard.createCursorKeys();
   
    stars = game.add.group();
    stars.enableBody = true;
    for (var i = 0; i < 12; i++)
    {
        var star = stars.create(i * 70, 0, 'star');
        star.body.gravity.y = 300;
        star.body.bounce.y = 0.7 + Math.random() * 0.2;
    }
}
 
function update() {
    game.physics.arcade.collide(player, platforms);
   
    game.physics.arcade.collide(stars, platforms);
    game.physics.arcade.overlap(player, stars, collectStar, null, this);
   
    player.body.velocity.x = 0;
    if (cursors.left.isDown)
    {
        player.body.velocity.x = -150;
        player.animations.play('left');
    }
    else if (cursors.right.isDown)
    {
        player.body.velocity.x = 150;
        player.animations.play('right');
    }
    else
    {
        player.animations.stop();
        player.frame = 4;
    }
    if (cursors.up.isDown && player.body.touching.down)
    {
        player.body.velocity.y = -350;
    }
}
 
function collectStar (player, star) {
    star.kill();
}
 
</script>
 
</body>

在create中,我们又创建了一个stars的组,在这个组中,添加了12个星星,然后设置了它们的重力,随机设置了弹性,所以它们掉落的时候,碰到平板或者地面,会弹起不同的高度。同样,星星也不能穿过地面,所以在update中,添加了碰撞检测。

还有一层碰撞检测就是小人和星星的碰撞,当小人和星星发生碰撞的时候,需要让星星消失,这时候,再添加碰撞检测的时候,我们还添加了一个回调函数collectStar,在这里面,我们的player和star都会作为参数传递进来,通过调用star.kill();将星星销毁。

星星全部收集完毕了,接下来我们需要进行得分的计算,不能光收集星星不得分对不对?

<!DOCTYPE html>
<head>
         <meta charset="UTF-8" />
         <title>exam8</title>
    <script src="../phaser.min.js"></script>
</head>
<body>
 
<script>
 
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
 
function preload() {
    game.load.image('sky', 'assets/sky.png');
    game.load.image('ground', 'assets/platform.png');
    game.load.image('star', 'assets/star.png');
    game.load.spritesheet('dude', 'assets/dude.png', 32, 48);
}
 
var platforms;
var player;
var cursors;
var stars;
var score = 0;
var scoreText;
function create() {
 
    game.physics.startSystem(Phaser.Physics.ARCADE);
    game.add.sprite(0, 0, 'sky');
    platforms = game.add.group();
    platforms.enableBody = true;
    var ground = platforms.create(0, game.world.height - 64, 'ground');
    ground.scale.setTo(2, 2);
    ground.body.immovable = true;
    var ledge = platforms.create(400, 400, 'ground');
    ledge.body.immovable = true;
    ledge = platforms.create(-150, 250, 'ground');
    ledge.body.immovable = true;
   
    player = game.add.sprite(32, game.world.height - 150, 'dude');
    game.physics.arcade.enable(player);
    player.body.bounce.y = 0.2;
    player.body.gravity.y = 300;
    player.body.collideWorldBounds = true;
    player.animations.add('left', [0, 1, 2, 3], 10, true);
    player.animations.add('right', [5, 6, 7, 8], 10, true);
   
    cursors = game.input.keyboard.createCursorKeys();
   
    stars = game.add.group();
    stars.enableBody = true;
    for (var i = 0; i < 12; i++)
    {
        var star = stars.create(i * 70, 0, 'star');
        star.body.gravity.y = 300;
        star.body.bounce.y = 0.7 + Math.random() * 0.2;
    }
   
    scoreText = game.add.text(16, 16, 'score: 0', { fontSize: '32px', fill: '#000' });
}
 
function update() {
    game.physics.arcade.collide(player, platforms);
   
    game.physics.arcade.collide(stars, platforms);
    game.physics.arcade.overlap(player, stars, collectStar, null, this);
   
    player.body.velocity.x = 0;
    if (cursors.left.isDown)
    {
        player.body.velocity.x = -150;
        player.animations.play('left');
    }
    else if (cursors.right.isDown)
    {
        player.body.velocity.x = 150;
        player.animations.play('right');
    }
    else
    {
        player.animations.stop();
        player.frame = 4;
    }
    if (cursors.up.isDown && player.body.touching.down)
    {
        player.body.velocity.y = -350;
    }
}
 
function collectStar (player, star) {
    star.kill();
   
    score += 10;
    scoreText.text = 'Score: ' + score;
}
 
</script>
 
</body>

我们通过game.add.text为场景加上一个文本,显示在左上角,在collectStar的时候,将分数进行累加,然后更新显示,这样就结束啦。


到这里,一个简单的小游戏就实现了,是不是比想象中的简单呢?

其实Phaser官方还为这个小游戏提供了一些其他的素材资源,但是在这里没有用到,可能是希望我们自己进行扩展吧!

用phaser做游戏,就是这么简单,只要会一点点js,人人都能做游戏啦!

转载请注明出处:www.phaser-china.com/tutorial-de…