天天看點

Phaser架構下的flappyBird

前端的小練習:flappyBird

體驗位址: https://xiaoxinnolabi.gitee.io/flappybird

碼雲位址: https://gitee.com/Xiaoxinnolabi/flappyBird.git

(很粗糙,bug略多)

index.html

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FlappyBird</title>
    <script src="js/phaser.min.js"></script>
</head>
<body>
    <center>
    <!--放置遊戲畫面-->
    <div id="game"></div>
    <p style="text-align: center;font-family:Arial, Helvetica, sans-serif;">隻要你飛得夠高,你就能夠穿越山河大海</p>

    </center>
</body>
<script src="js/game.js"></script>
</html>
           

game.js

// 放置遊戲邏輯代碼 
const game = new Phaser.Game(320,505,Phaser.AUTO,"game")//(遊戲寬度、高度、渲染方式、盒子ID)

//在game對象裡面添加一個gameStates屬性 ,放置遊戲場景
game.gameStates = {}

//放入menu場景 
game.gameStates.menu=function(){
    //一個合法場景必須有以下三個功能中一個

    //1 加載資源
    this.preload=function(){
        game.load.image('background','assets/background.png')
        game.load.image('ground','assets/ground.png')
        game.load.image('game_over','assets/gameover.png')

        game.load.spritesheet('bird','assets/bird.png',34,24,3)//(命名、圖檔位置、寬度、高度、幀數)

        game.load.image('title','assets/title.png')//加載題目圖檔
        game.load.image('btnImg','assets/start-button.png')

        //加載管道圖檔
        game.load.spritesheet('pipe','assets/pipes.png',54,320,2)

        game.load.audio('fly_sound','assets/flap.wav')
        game.load.audio('score_sound','assets/score.wav')

        //字型
        game.load.bitmapFont('fly_font','assets/fonts/flappyfont/flappyfont.png','assets/fonts/flappyfont/flappyfont.fnt')

    }

    //2 加載資源後,進入create()方法
    this.create=function(){
        //const 定義常量 局部常量
        const mybg=game.add.tileSprite(0,0,game.width,game.height,"background")//瓷磚精靈:(x軸,y軸,寬度,高度,對象)
        const ground=game.add.tileSprite(0,game.height-112,game.width,112,"ground")//地闆
        const titleGroup = game.add.group()//在遊戲對象添加一個組 titleGroup
        titleGroup.create(0,0,'title')//(x軸位置,y軸位置,加入什麼元素)
        const bird = titleGroup.create(190,0,'bird')//小鳥加入組

        bird.animations.add('fly')//('動畫名字')
        bird.animations.play('fly',16,true)//(動畫名字,每秒多少張圖檔,是否重複播放)

        titleGroup.x=50
        titleGroup.y=140

        //tween(控制對象).to(位置,時間,緩動類型,是否自動開始,延遲幾秒開始,重複幾次,來回循環)緩動
        game.add.tween(titleGroup).to({y:120},1000,null,true,0,Number.MAX_VALUE,true)

        const btn = game.add.button(game.width/2,game.height/2,'btnImg',function(){
            //點選後效果:跳轉到第二個
            game.state.start("mysence2")
        })//(x,y,填加進去的是什麼,執行的效果)

        btn.anchor.setTo(0.5,0.5)//anchor修改按鈕中心點

        mybg.autoScroll(-15,0)//重複自動滾動 (x,y)
        ground.autoScroll(-100,0)
        
    }

    //3 時時刻刻監測的内容
    this.update=function(){}
}

game.gameStates.play=function(){
    //加載資源
    this.preload=function(){
    }

    //資源加載後的場景
    this.create=function(){
        this.mybg=game.add.tileSprite(0,0,game.width,game.height,"background")//瓷磚精靈:(x軸,y軸,寬度,高度,對象)
        //添加管道組
        this.pipeGroup= game.add.group()

        //添加聲音
        this.flySound=game.add.audio('fly_sound')
        this.scoreSound=game.add.audio('score_sound')
        //開啟實體引擎
        this.pipeGroup.enableBody=true  
        this.startGameFlag=false
        
        this.ground=game.add.tileSprite(0,game.height-112,game.width,112,"ground")//地闆

        //加載字型
        this.scoreGroup=game.add.group()
        this.scoreText=game.add.bitmapText(game.width/2,100,'fly_font','0',40,this.scoreGroup)
        // this.scoreText.anchor.setTo(0.5,0.5)

        this.bird = game.add.sprite(50,100,'bird')//小鳥加入組

        this.bird.animations.add('fly')//('動畫名字')
        this.bird.animations.play('fly',16,true)//(動畫名字,每秒多少張圖檔,是否重複播放)
        this.bird.anchor.setTo(0.5,0.5)

        //開啟實體引擎(physics.enable(引擎作用的對象,使用的實體引擎))
        game.physics.enable(this.bird,Phaser.Physics.ARCADE)
        game.physics.enable(this.ground,Phaser.Physics.ARCADE)
        this.ground.body.immovable=true
        


        //1.點選螢幕(事件,綁定到對象)
        game.input.onDown.addOnce(this.startGame,this)//this.startGame隻要監聽一次用addOnce
        
    }

    //實時更新需要的場景
    this.update=function(){
        if(this.startGameFlag==false){
            return 
        }

        //collide碰撞(對象A,對象B,碰撞後執行的方法,回調,對象)
        game.physics.arcade.collide(this.bird,this.ground,this.hit,null,this)

        //碰撞檢測 一旦碰撞,停止
        game.physics.arcade.overlap(this.bird,this.pipeGroup,this.hitPipe,null,this)
        if(this.bird.angle<90 ){
            this.bird.angle+=3
        }

        //得分檢測:檢測存在于螢幕中的物體,第二個隻能用于組
        this.pipeGroup.forEachExists(this.checkScore,this)
        
    }

    //2.開始遊戲
    //使用者定義startGame
    this.startGame=function(){
        this.score=0

        this.mybg.autoScroll(-15,0)//重複自動滾動 (x,y)
        this.ground.autoScroll(-100,0)
        //一旦開啟實體引擎,就有body屬性
        this.bird.body.gravity.y=1000
        this.startGameFlag=true

        game.input.onDown.add(this.fly,this)

        //定時器 制作管道
        this.Timer =game.time.events.loop(1000,this.makePipe,this)
       
    }

    //撞擊管道後
    this.hitPipe=function(){
        this.gameOver()
    }

    //分數檢測
    this.checkScore=function(pipe){
        //pipe是形參,是this.pipeGroup
        if(!pipe.hasScore && pipe.y<=0 && pipe.x < this.bird.x-54){
            this.scoreSound.play()
            pipe.hasScore=true
            this.score++
            this.scoreText.text = this.score
            console.log(this.score)
        }

        return
    }
    //結束遊戲
    this.gameOver=function(){
        //停止地闆和背景動畫
        this.ground.stopScroll()
        this.mybg.stopScroll()
        //停止飛翔動作
        this.bird.animations.stop('fly',0)
        //移除滑鼠單擊事件的監聽
        game.input.onDown.remove(this.fly,this)
        //停止管道生成
        this.pipeGroup.setAll('body.velocity.x',0)
        game.time.events.remove(this.Timer)

        //加載重新開始界面
        this.restartGame()

    }

    //重新開始
    this.restartGame=function(){
        this.gameOverGroup = game.add.group()
        const gameOverText = this.gameOverGroup.create(game.width/2,60,'game_over')
        gameOverText.anchor.setTo(0.5,0.5)

        const replayBtn=game.add.button(game.width/2,180,'btnImg',function(){
                game.state.start('mysence1')
        })

        replayBtn.anchor.setTo(0.5,0.5)
    }

    //制作管道
    this.makePipe=function(){
        gam=100//空隙  空隙在85-320之間都是合理的
        //math.random() 0-1 :Math.random(235)+85 管道的随機位置
        const position = Math.floor(Math.random()*235)+85
        const topPipeY = position -320//上管道
        const bottomPipeY = position + 100//下管道
        const topPipe = game.add.sprite(game.width,topPipeY,'pipe',0,this.pipeGroup)
        const bottomPipe = game.add.sprite(game.width,bottomPipeY,'pipe',1,this.pipeGroup)
        this.pipeGroup.setAll('body.velocity.x',-200)
    }

    //小鳥向上飛
    this.fly=function(){
        this.flySound.play()
        //1 頭部向上揚起
        game.add.tween(this.bird).to({angle:-30},100,null,true,0,0,false)
        //2 小鳥向上運動
        this.bird.body.velocity.y=-300//一次性
        
        // 重力恒定this.bird.body.gravity.y=-300
    }

    //使用者定義this.hit
    this.hit=function(){
         //停止地闆和背景動畫
         this.ground.stopScroll()
         this.mybg.stopScroll()
         //停止飛翔動作
         this.bird.animations.stop('fly',0)
         //移除滑鼠單擊事件的監聽
         game.input.onDown.remove(this.fly,this)
         //停止管道生成
         this.pipeGroup.setAll('body.velocity.x',0)
         game.time.events.remove(this.Timer)
 
         //加載重新開始界面
         this.restartGame()
    }
}

game.state.add("mysence1",game.gameStates.menu)
game.state.add("mysence2",game.gameStates.play)
game.state.start("mysence1")
           

繼續閱讀