import Phaser from "phaser"; import pipeImg from "../../assets/flipbird/pipe.png"; import pipe1 from "../../assets/flipbird/pipe1.png"; import pipe2 from "../../assets/flipbird/pipe2.png"; import pipe3 from "../../assets/flipbird/pipe3.png"; import birdImg from "../../assets/flipbird/clumsy.png"; import bg from "../../assets/flipbird/bg.png"; /** * 素材再找 https://github.com/ellisonleao/clumsy-bird/blob/master/data/img/new.png * https://www.emanueleferonato.com/2019/05/02/flappy-bird-html5-prototype-updated-to-phaser-3-16-2/ * */ const getRandomPipe = () => ["pipe1", "pipe2", "pipe3"][Math.floor(Math.random() * 3)]; export default class PlayScene extends Phaser.Scene { constructor() { super({ key: "flipbird" }); this.bg = null; this.pipeGroup = null; this.gameOptions = { // bird gravity, will make bird fall if you dont flap birdGravity: 800, // horizontal bird speed birdSpeed: 120, //125 // flap thrust birdFlapPower: 250, // minimum pipe height, in pixels. Affects hole position minPipeHeight: 50, // distance range from next pipe, in pixels pipeDistance: [220, 280], // hole range between pipes, in pixels pipeHole: [300, 350], //[100, 130], }; } preload() { //this.load.image("bird", "bird.png"); this.load.image("bg", bg); this.load.image("pipe", pipeImg); this.load.image("pipe1", pipe1); this.load.image("pipe2", pipe2); this.load.image("pipe3", pipe3); this.load.spritesheet("bird", birdImg, { frameWidth: 386, frameHeight: 392, }); } create() { // this.game.physics.startSystem(Phaser.Physics.P2JS); this.bg = this.add.image( this.game.config.width / 2, this.game.config.height / 2, "bg" ); this.bg.displayWidth = this.game.config.width; this.bg.displayHeight = this.game.config.height; this.pipeGroup = this.physics.add.group(); this.pipePool = []; for (let i = 0; i < 4; i++) { const pipeA = getRandomPipe(); const p1 = this.pipeGroup.create(0, 0, pipeA); p1.body.setSize(100); p1.setScale(0.5); const pipeB = getRandomPipe(); const p2 = this.pipeGroup.create(0, 0, pipeB); p2.body.setSize(100); p2.setScale(0.5); this.pipePool.push(p1); this.pipePool.push(p2); this.placePipes(false); } this.pipeGroup.setVelocityX(-this.gameOptions.birdSpeed); this.bird = this.physics.add.sprite( 150, this.game.config.height / 2, "bird" ); this.bird.body.setCircle(342 / 2, 0, 25); this.bird.setScale(0.5); this.bird.body.gravity.y = this.gameOptions.birdGravity; this.anims.create({ key: "fly", frames: this.anims.generateFrameNumbers("bird", { start: 0, end: 3 }), frameRate: 10, repeat: -1, }); this.input.on("pointerdown", this.flap, this); this.score = 0; this.scoreText1 = this.add.text(20, 20, "", { fontSize: 20, }); this.updateScore(this.score); } updateScore(inc) { this.score += inc; this.scoreText1.text = "Game Score: " + this.score; } placePipes(addScore) { let rightmost = this.getRightmostPipe(); let pipeHoleHeight = Phaser.Math.Between( this.gameOptions.pipeHole[0], this.gameOptions.pipeHole[1] ); let pipeHolePosition = Phaser.Math.Between( this.gameOptions.minPipeHeight + pipeHoleHeight / 2, this.game.config.height - this.gameOptions.minPipeHeight - pipeHoleHeight / 2 ); this.pipePool[0].x = rightmost + this.pipePool[0].getBounds().width + Phaser.Math.Between( this.gameOptions.pipeDistance[0], this.gameOptions.pipeDistance[1] ); this.pipePool[0].y = pipeHolePosition - pipeHoleHeight / 2; this.pipePool[0].setOrigin(0, 1); this.pipePool[1].x = this.pipePool[0].x; this.pipePool[1].y = pipeHolePosition + pipeHoleHeight / 2; this.pipePool[1].setOrigin(0, 0); this.pipePool[1].flipY = true; this.pipePool = []; if (addScore) { this.updateScore(1); } } flap() { this.bird.body.velocity.y = -this.gameOptions.birdFlapPower; this.bird.anims.play("fly", true); } getRightmostPipe() { let rightmostPipe = 0; this.pipeGroup.getChildren().forEach(function (pipe) { rightmostPipe = Math.max(rightmostPipe, pipe.x); }); return rightmostPipe; } update() { this.physics.world.collide( this.bird, this.pipeGroup, () => { this.die(); }, null, this ); if (this.bird.y > this.game.config.height || this.bird.y < 0) { this.die(); } this.pipeGroup.getChildren().forEach(function (pipe) { if (pipe.getBounds().right < 0) { this.pipePool.push(pipe); if (this.pipePool.length == 2) { this.placePipes(true); } } }, this); // this.bg.tilePositionY += 0.5 } die() { if (this.game.onLose) { this.game.onLose(); this.scene.pause(); } } }