天天看点

基于Phaser框架完成FlappyBird

Phaser没什么好说的,不是很清楚的,网上自己去搜吧~

注:该博客大部分参考了网上的资源

各文件作用:

Index.html----不多说了,网页

Phaser.min.js----游戏所需框架

load.js----预加载游戏中用到的资源文件

Menu.js----游戏的主界面,提示游戏的操作方法,其实没什么功能,但又必不可少

Ready.js----是一个准备开始游戏的界面,按下空格键即开始游戏,防止还没准备好就开始游戏,并且以图示意因操作而使Bird产生的变化

Play.js----开始玩游戏所加载的State,用来展示游戏进行界面及分数改变

Gameover.js----》游戏结束,进行分数结算和展示

Game.js----初始化Phaser并且定义所需States

index.html游戏主界面

<html>   
<head>
  <meta charset="UTF-8" />
  <title>Flappy Bird</title>
  <style>
    #game_div {
      width: 400px;
      margin: auto;
      margin-top: 50px;
    }
    body{
        background-image:url(assets/birdbg.png);
    }
    .style1{
        text-align:center;
        color:#FFFFFF;
        font-size:24pt;
        font-weight:bold;
    }
  </style>
<!--导入游戏所需js文件-->
  <script type="text/javascript" src="phaser.min.js"></script>
  <script type="text/javascript" src="load.js"></script>
  <script type="text/javascript" src="menu.js"></script>
  <script type="text/javascript" src="ready.js"></script>
  <script type="text/javascript" src="play.js"></script>
  <script type="text/javascript" src="gameover.js"></script>
  <script type="text/javascript" src="game.js"></script> 
</head>
<body>
  <div align="center" class="style1">Flappy Bird</div>
<table width="100%"  align="center">
    <tr>
        <td width="40%">
        </td>
          <td width="400"><!--游戏域--><div id="game_div"></div></td>
        <td width="40%"></td>
    </tr>
</table>
</body>
</html>
           

加载游戏资源文件load.js

var load_state = {  
//预加载游戏资源
    preload: function() { 
        this.game.load.image('bg','assets/bg.png');
        this.game.load.image('bo','assets/back.png');
        this.game.load.image('menu','assets/menu.png');
        this.game.load.image('ready','assets/ready.png');
        this.game.load.image('bird', 'assets/bird.png');  
        this.game.load.image('pipe', 'assets/pipe.png');  
        this.game.load.audio('jump', 'assets/jump.wav');
        this.game.load.audio('dead','assets/dead.wav');
        this.game.load.image('gameover','assets/gameover.png');
    },
 
    create: function() {
         
        // 所有资源加载完成后,进入'menu'state
        this.game.state.start('menu');   
    }
};
           

载入menu界面

var menu_state={
    create: function(){
         
        var space_key = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);        //定义接受按键消息变量
        space_key.onDown.add(this.start,this);        //按键按下时调用start()函数
         
        var style = {font: "30px Arial",fill: "#FFFFFF"};        //定义游戏操作说明文字风格
        var x = game.world.width/2,y = game.world.height/2;        //定义坐标变量x,y,(x,y)为game.world中心
         
        this.bg = this.game.add.sprite(0,0,'bg');        //在game.world中坐标(0,0)处画出预加载游戏资源,背景图片
        this.bo = this.game.add.sprite(0,0,'bo');        //也是背景图片,我的背景由两个背景透明的图片组合而成,其实可以合二为一
        this.menu = this.game.add.sprite(0,0,'menu');        //加载menu图片
        this.bird = this.game.add.sprite(x-30,y-60,'bird');        //载入即将闯荡管子世界的Bird
         
        var text = this.game.add.text(x,y-118,"Press space to start!",style);        //定义显示文本变量,并在game.world显示,参数(坐标,显示文本,文本风格)
        text.anchor.setTo(0.5,0.5);        //
           
    },
    start:function(){
        this.game.state.start('ready');        //调用start()函数后进入'ready'state
    }
};
           

载入游戏准备界面ready.js

var ready_state = {
    create:function(){
        //载入游戏准备界面
        var space_key = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
        space_key.onDown.add(this.start,this);
         
        this.bg = this.game.add.sprite(0,0,'bg');
        this.bo = this.game.add.sprite(0,0,'bo');
        this.ready = this.game.add.sprite(0,0,'ready');
        this.bird = this.game.add.sprite(100,245,'bird');
    },
    start:function(){
        this.game.state.start('play');   
    },
};
           

play.js,游戏核心

var play_state = {
    create: function() { 
        //载入所需资源
        this.bg = this.game.add.sprite(0,0,'bg');
        this.bo = this.game.add.sprite(0,0,'bo');
         
         
        var space_key = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
        space_key.onDown.add(this.jump, this); 
 
        this.pipes = game.add.group();
        this.pipes.createMultiple(20, 'pipe');  
        this.timer = this.game.time.events.loop(1500, this.add_row_of_pipes, this);           
 
        this.bird = this.game.add.sprite(100, 245, 'bird');
        this.bird.body.gravity.y = 1000;         //设置Bird重力属性,gravity
        this.bird.anchor.setTo(-0.2, 0.5);        //设置Bird重心
         
        // Not 'this.score', but just 'score'
        score = 0; 
        var style = { font: "30px Arial", fill: "#ffffff" };
        this.label_score = this.game.add.text(20, 20, "0", style); 
 
        this.jump_sound = this.game.add.audio('jump');        //加载音效
        this.dead_sound = this.game.add.audio('dead');        //||
    },
 
    update: function() {
        if (this.bird.inWorld == false)
            this.restart_game(); 
 
        if (this.bird.angle < 20)
            this.bird.angle += 1;
 
        this.game.physics.overlap(this.bird, this.pipes, this.hit_pipe, null, this);      
    },
    //每次按下空格调用的函数
    jump: function() {
        if (this.bird.alive == false)
            return; 
 
        this.bird.body.velocity.y = -350;
        this.game.add.tween(this.bird).to({angle: -20}, 50).start();
        this.jump_sound.play();
    },
    //撞管子
    hit_pipe: function() {
        if (this.bird.alive == false)
            return;
 
        this.bird.alive = false;
        this.game.time.events.remove(this.timer);
 
        this.pipes.forEachAlive(function(p){
            p.body.velocity.x = 0;
        }, this);
        this.dead_sound.play();
    },
    //重新开始函数
    restart_game: function() {
        this.game.time.events.remove(this.timer);
         
        this.game.state.start('gameover');
    },
 
    add_one_pipe: function(x, y) {
        var pipe = this.pipes.getFirstDead();
        pipe.reset(x, y);
        pipe.body.velocity.x = -200; 
        pipe.outOfBoundsKill = true;
    },
 
    add_row_of_pipes: function() {
        var hole = Math.floor(Math.random()*5)+1;
         
        for (var i = 0; i < 8; i++)
            if (i != hole && i != hole +1) 
                this.add_one_pipe(400, i*60+10);   
        score += 1; 
        this.label_score.content = score;  
    },
};
           

gameover.js,游戏结束界面,并将分数显示在相应的位置

var gameover_state = {
    create:function(){
         
        var space_key = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
        space_key.onDown.add(this.start,this);   
         
        var style = {font: "20px Arial",fill: "#F00"};
        var style1 = {font: "30px Arial",fill: "F00"};
        var x = game.world.width/2,y = game.world.height/2;
         
        this.bg = this.game.add.sprite(0,0,'bg');
        this.bo = this.game.add.sprite(0,0,'bo');
        this.gameover = this.game.add.sprite(0,0,'gameover');
         
        if(score > 0){
            var score_label = this.game.add.text(x+90,y-40,score,style1);
            score_label.anchor.setTo(0.5,0.5);
            var score_label1 = this.game.add.text(x+90,y+20,"Unknown!",style);
            score_label1.anchor.setTo(0.5,0.5);
            }
        else if(score == 0){
            var score_label = this.game.add.text(x+90,y-40,"0",style1);
            score_label.anchor.setTo(0.5,0.5);
            var score_label1 = this.game.add.text(x+90,y+20,"Unknown!",style);
            score_label1.anchor.setTo(0.5,0.5);
            }
    },
    start:function(){
        this.game.state.start('menu');   
    }
};
           

最后,初始化Phaser并且定义所需States:(1)load_state,(2)menu_state,(3)ready_state,(4)play_state,(5)gameover_state

var game = new Phaser.Game(400,490,Phaser.AUTO,'game_div');
 
var score = 0;
 
game.state.add('load',load_state);
game.state.add('menu',menu_state);
game.state.add('ready',ready_state);
game.state.add('play',play_state);
game.state.add('gameover',gameover_state);
 
game.state.start('load');
           

源文件及资源文件: http://pan.baidu.com/s/1hqC97hy

演示地址:http://www.sunnylinner.com/Games/FlappyBird/

继续阅读