diff --git a/Game.vue b/Game.vue index a612ac3..d9fc0f9 100644 --- a/Game.vue +++ b/Game.vue @@ -6,10 +6,11 @@ import ballMove from "./games/game-ballmove/game"; import flappyBird from "./games/game-flipbird/game"; import game2048 from "./games/game2048/game"; import rect from "./games/game-rect/game"; -const games = { ballMove, flappyBird, game2048, rect }; +import floodFill from "./games/game-flood-fill/game"; +const games = { ballMove, flappyBird, game2048, rect, floodFill }; const STATE_RUNNING = 0; const STATE_LOSE = 1; -const STATE_WIN = 2; +const STATE_WON = 2; const STATE_PAUSED = 3; export default { props: ["name", "containerStyle"], @@ -68,11 +69,14 @@ export default { if (this.state !== STATE_LOSE) this.$emit("lost"); this.state = STATE_LOSE; }, + onWon: () => { + if (this.state !== STATE_WON) this.$emit("won"); + this.state = STATE_WON; + }, }); }, }, async mounted() { - console.log("a"); this.reload(this.name); }, diff --git a/games/game-flood-fill/game.js b/games/game-flood-fill/game.js index 0516e78..f6df0b3 100644 --- a/games/game-flood-fill/game.js +++ b/games/game-flood-fill/game.js @@ -1,13 +1,12 @@ import Phaser from "phaser"; -import BootScene from "./scenes/BootScene"; import PlayScene from "./scenes/PlayScene"; //import { * } from "./constant"; -function launch(containerId) { +function launch({ containerId, onLose, onWon }) { const container = document.getElementById(containerId); const width = container.clientWidth; const height = container.clientHeight; - return new Phaser.Game({ + const game = new Phaser.Game({ type: Phaser.WEBGL, width, height, @@ -21,8 +20,23 @@ function launch(containerId) { debug: true, }, }, - scene: [BootScene, PlayScene], + scene: PlayScene, + scale: { + mode: Phaser.Scale.FIT, + autoCenter: Phaser.Scale.CENTER_BOTH, + parent: containerId, + width: 1080, + height: 1080, + }, + }); + Object.assign(game, { + onLose, + onWon, + restart() { + this.scene.scenes[0].scene.start("PlayScene"); + }, }); + return game; } export default launch; diff --git a/games/game-flood-fill/scenes/BootScene.js b/games/game-flood-fill/scenes/BootScene.js deleted file mode 100644 index 7ebc468..0000000 --- a/games/game-flood-fill/scenes/BootScene.js +++ /dev/null @@ -1,12 +0,0 @@ -import { Scene } from "phaser"; - -export default class BootScene extends Scene { - constructor() { - super({ key: "BootScene" }); - } - preload() {} - - create() { - this.scene.start("PlayScene"); - } -} diff --git a/games/game-flood-fill/scenes/PlayScene.js b/games/game-flood-fill/scenes/PlayScene.js index 96e2b26..63d8bec 100644 --- a/games/game-flood-fill/scenes/PlayScene.js +++ b/games/game-flood-fill/scenes/PlayScene.js @@ -1,9 +1,10 @@ import Phaser from "phaser"; -import bg from "@/game/game-breakout/assets/parallax-mountain800600.png"; -import atari from "@/game/game-flood-fill/assets/flood/atari-smooth.png"; -//import atarixml from "@/game/game-flood-fill/assets/flood/atari-smooth.xml"; -import blobs from "@/game/game-flood-fill/assets/flood/blobs.png"; -//import blobsjson from "@/game/game-flood-fill/assets/flood/blobs.json"; + +import bg from "./bg.jpg"; +import tiles from "./tiles.png"; +import sprites from "./tiles.json"; +import title from "./title.png"; +import instruction from "./instruction.png"; class PlayScene extends Phaser.Scene { constructor() { @@ -12,18 +13,6 @@ class PlayScene extends Phaser.Scene { }); this.allowClick = true; - this.arrow; - this.cursor; - this.cursorTween; - this.monsterTween; - - this.icon1 = { shadow: null, monster: null }; - this.icon2 = { shadow: null, monster: null }; - this.icon3 = { shadow: null, monster: null }; - this.icon4 = { shadow: null, monster: null }; - this.icon5 = { shadow: null, monster: null }; - this.icon6 = { shadow: null, monster: null }; - this.gridBG; this.instructions; @@ -40,33 +29,34 @@ class PlayScene extends Phaser.Scene { this.moves = 25; - this.frames = ["blue", "green", "grey", "purple", "red", "yellow"]; + this.frames = [ + "red.png", + "bu.png", + "grey.png", + "ye.png", + "pr.png", + "gr.png", + ]; } preload() { - this.load.bitmapFont( - "atari", - atari, - "static/assets/flood-fill/atari-smooth.xml" - ); - this.load.atlas("flood", blobs, "static/assets/flood-fill/blobs.json"); + this.load.image("bg", bg); + this.load.image("title", title); + this.load.atlas("tiles", tiles, sprites); + this.load.image("instruction", instruction); } create() { - this.add.image(400, 300, "flood", "background"); - this.gridBG = this.add.image(400, 600 + 300, "flood", "grid"); - - this.createIcon(this.icon1, "grey", 16, 156); - this.createIcon(this.icon2, "red", 16, 312); - this.createIcon(this.icon3, "green", 16, 458); - this.createIcon(this.icon4, "yellow", 688, 156); - this.createIcon(this.icon5, "blue", 688, 312); - this.createIcon(this.icon6, "purple", 688, 458); - - this.cursor = this.add - .image(16, 156, "flood", "cursor-over") - .setOrigin(0) - .setVisible(false); + const bg = this.add.image(0, 0, "bg"); + bg.setOrigin(0); + bg.displayWidth = 1080; + bg.displayHeight = 1080; + this.createIcon(0, 0, 272); + this.createIcon(1, 0, 272 + 252); + this.createIcon(2, 0, 272 + 252 * 2); + this.createIcon(3, 1080 - 184, 272); + this.createIcon(4, 1080 - 184, 272 + 252); + this.createIcon(5, 1080 - 184, 272 + 252 * 2); // The game is played in a 14x14 grid with 6 different colors @@ -76,12 +66,14 @@ class PlayScene extends Phaser.Scene { this.grid[x] = []; for (var y = 0; y < 14; y++) { - var sx = 166 + x * 36; - var sy = 66 + y * 36; + var sx = 204 + x * 48; + var sy = 309 + y * 48; var color = Phaser.Math.Between(0, 5); - var block = this.add.image(sx, -600 + sy, "flood", this.frames[color]); - + var block = this.add.image(sx, -1032 + sy, "tiles", this.frames[color]); + block.setOrigin(0); + block.displayWidth = 48; + block.displayHeight = 48; block.setData("oldColor", color); block.setData("color", color); block.setData("x", sx); @@ -102,23 +94,28 @@ class PlayScene extends Phaser.Scene { this.currentColor = this.grid[0][0].getData("color"); - this.particles = this.add.particles("flood"); + this.particles = this.add.particles("tiles"); for (var i = 0; i < this.frames.length; i++) { this.createEmitter(this.frames[i]); } - - this.createArrow(); - - this.text1 = this.add.bitmapText(684, 30, "atari", "Moves", 20).setAlpha(0); - this.text2 = this.add.bitmapText(694, 60, "atari", "00", 40).setAlpha(0); + const title = this.add.image(1080 / 2, 228, "title"); + title.displayWidth = 222; + title.displayHeight = 50; + this.text1 = this.add + .text(440, 160, "MOVES:", { + fontSize: 40, + color: "#fff", + }) + .setAlpha(0); + this.text2 = this.add + .text(590, 160, "00", { fontSize: 40, color: "#fff" }) + .setAlpha(0); this.text3 = this.add - .bitmapText(180, 200, "atari", "So close!\n\nClick to\ntry again", 48) + .text(180, 200, "差一点!\n\n点击\n再试一次", 48) .setAlpha(0); - this.instructions = this.add - .image(400, 300, "flood", "instructions") - .setAlpha(0); + this.instructions = this.add.image(500, 600, "instruction").setAlpha(0); //初始化位置 this.revealGrid(); } @@ -141,40 +138,11 @@ class PlayScene extends Phaser.Scene { } } - createArrow() { - this.arrow = this.add - .image(109 - 24, 48, "flood", "arrow-white") - .setOrigin(0) - .setAlpha(0); - - this.tweens.add({ - targets: this.arrow, - x: "+=24", - ease: "Sine.easeInOut", - duration: 900, - yoyo: true, - repeat: -1, - }); - } - - createIcon(icon, color, x, y) { - var sx = x < 400 ? -200 : 1000; - - icon.monster = this.add.image(sx, y, "flood", "icon-" + color).setOrigin(0); - - var shadow = this.add.image(sx, y, "flood", "shadow"); - - shadow.setData("color", this.frames.indexOf(color)); - - shadow.setData("x", x); - - shadow.setData("monster", icon.monster); - - shadow.setOrigin(0); - - shadow.setInteractive(); - - icon.shadow = shadow; + createIcon(color, x, y) { + const area = this.add.rectangle(x, y, 184, 758 / 3); + area.setOrigin(0); + area.setData("color", color); + area.setInteractive(); } revealGrid() { @@ -206,53 +174,6 @@ class PlayScene extends Phaser.Scene { i -= 1000; - // Icons - this.tweens.add({ - targets: [this.icon1.shadow, this.icon1.monster], - x: this.icon1.shadow.getData("x"), - ease: "Power3", - delay: i, - }); - - this.tweens.add({ - targets: [this.icon4.shadow, this.icon4.monster], - x: this.icon4.shadow.getData("x"), - ease: "Power3", - delay: i, - }); - - i += 200; - - this.tweens.add({ - targets: [this.icon2.shadow, this.icon2.monster], - x: this.icon2.shadow.getData("x"), - ease: "Power3", - delay: i, - }); - - this.tweens.add({ - targets: [this.icon5.shadow, this.icon5.monster], - x: this.icon5.shadow.getData("x"), - ease: "Power3", - delay: i, - }); - - i += 200; - - this.tweens.add({ - targets: [this.icon3.shadow, this.icon3.monster], - x: this.icon3.shadow.getData("x"), - ease: "Power3", - delay: i, - }); - - this.tweens.add({ - targets: [this.icon6.shadow, this.icon6.monster], - x: this.icon6.shadow.getData("x"), - ease: "Power3", - delay: i, - }); - // Text this.tweens.add({ @@ -268,7 +189,7 @@ class PlayScene extends Phaser.Scene { from: 0, to: 25, ease: "Power1", - onUpdate: function(tween, targets, text) { + onUpdate: function (tween, targets, text) { text.setText( Phaser.Utils.String.Pad(tween.getValue().toFixed(), 2, "0", 1) ); @@ -280,7 +201,7 @@ class PlayScene extends Phaser.Scene { i += 500; this.tweens.add({ - targets: [this.instructions, this.arrow], + targets: [this.instructions], alpha: 1, ease: "Power3", delay: i, @@ -290,15 +211,13 @@ class PlayScene extends Phaser.Scene { } startInputEvents() { - this.input.on("gameobjectover", this.onIconOver, this); - this.input.on("gameobjectout", this.onIconOut, this); this.input.on("gameobjectdown", this.onIconDown, this); // Cheat mode :) this.input.keyboard.on( "keydown_M", - function() { + function () { this.moves++; this.text2.setText(Phaser.Utils.String.Pad(this.moves, 2, "0", 1)); }, @@ -307,7 +226,7 @@ class PlayScene extends Phaser.Scene { this.input.keyboard.on( "keydown_X", - function() { + function () { this.moves--; this.text2.setText(Phaser.Utils.String.Pad(this.moves, 2, "0", 1)); }, @@ -316,72 +235,13 @@ class PlayScene extends Phaser.Scene { } stopInputEvents() { - this.input.off("gameobjectover", this.onIconOver); - this.input.off("gameobjectout", this.onIconOut); this.input.off("gameobjectdown", this.onIconDown); } - onIconOver(pointer, gameObject) { - var icon = gameObject; - - var newColor = icon.getData("color"); - - // Valid color? - if (newColor !== this.currentColor) { - this.cursor.setFrame("cursor-over"); - } else { - this.cursor.setFrame("cursor-invalid"); - } - - this.cursor.setPosition(icon.x + icon.width / 2, icon.y + icon.height / 2); - if (this.cursorTween) { - this.cursorTween.stop(); - } - - this.cursor.setAlpha(1); - this.cursor.setVisible(true); - - // Change arrow color - this.arrow.setFrame("arrow-" + this.frames[newColor]); - - // Jiggle the monster :) - var monster = icon.getData("monster"); - - this.children.bringToTop(monster); - - this.monsterTween = this.tweens.add({ - targets: monster, - y: "-=24", - yoyo: true, - repeat: -1, - duration: 300, - ease: "Power2", - }); - } - - onIconOut(pointer, gameObject) { - // console.log(this.monsterTween.targets[0].y); - - this.monsterTween.stop(0); - - gameObject.getData("monster").setY(gameObject.y); - - // console.log(this.monsterTween.targets[0].y); - - this.cursorTween = this.tweens.add({ - targets: this.cursor, - alpha: 0, - duration: 300, - }); - - this.arrow.setFrame("arrow-white"); - } - onIconDown(pointer, gameObject) { if (!this.allowClick) { return; } - var icon = gameObject; var newColor = icon.getData("color"); @@ -392,7 +252,6 @@ class PlayScene extends Phaser.Scene { } var oldColor = this.grid[0][0].getData("color"); - // console.log('starting flood from', oldColor, this.frames[oldColor], 'to', newColor, this.frames[newColor]); if (oldColor !== newColor) { @@ -400,11 +259,6 @@ class PlayScene extends Phaser.Scene { this.matched = []; - if (this.monsterTween) { - this.monsterTween.stop(0); - } - - this.cursor.setVisible(false); this.instructions.setVisible(false); this.moves--; @@ -433,7 +287,7 @@ class PlayScene extends Phaser.Scene { } startFlow() { - this.matched.sort(function(a, b) { + this.matched.sort(function (a, b) { var aDistance = Phaser.Math.Distance.Between(a.x, a.y, 166, 66); var bDistance = Phaser.Math.Distance.Between(b.x, b.y, 166, 66); @@ -457,9 +311,8 @@ class PlayScene extends Phaser.Scene { this.time.delayedCall( t, - function(block, blockColor) { + function (block, blockColor) { block.setFrame(blockColor); - emitter.explode(6, block.x, block.y); }, [block, blockColor, emitter] @@ -470,7 +323,7 @@ class PlayScene extends Phaser.Scene { this.time.delayedCall( t, - function() { + function () { this.allowClick = true; if (this.checkWon()) { @@ -501,28 +354,6 @@ class PlayScene extends Phaser.Scene { clearGrid() { // Hide everything :) - this.tweens.add({ - targets: [ - this.icon1.monster, - this.icon1.shadow, - this.icon2.monster, - this.icon2.shadow, - this.icon3.monster, - this.icon3.shadow, - this.icon4.monster, - this.icon4.shadow, - this.icon5.monster, - this.icon5.shadow, - this.icon6.monster, - this.icon6.shadow, - this.arrow, - this.cursor, - ], - alpha: 0, - duration: 500, - delay: 500, - }); - var i = 500; for (var y = 13; y >= 0; y--) { @@ -564,7 +395,7 @@ class PlayScene extends Phaser.Scene { duration: 1000, delay: i, }); - + this.game.onLose && this.game.onLose(); this.input.once("pointerdown", this.resetGame, this); } @@ -575,30 +406,6 @@ class PlayScene extends Phaser.Scene { // Show everything :) - this.arrow.setFrame("arrow-white"); - - this.tweens.add({ - targets: [ - this.icon1.monster, - this.icon1.shadow, - this.icon2.monster, - this.icon2.shadow, - this.icon3.monster, - this.icon3.shadow, - this.icon4.monster, - this.icon4.shadow, - this.icon5.monster, - this.icon5.shadow, - this.icon6.monster, - this.icon6.shadow, - this.arrow, - this.cursor, - ], - alpha: 1, - duration: 500, - delay: 500, - }); - var i = 500; for (var y = 13; y >= 0; y--) { @@ -639,11 +446,11 @@ class PlayScene extends Phaser.Scene { this.currentColor = this.grid[0][0].getData("color"); - var movesTween = this.tweens.addCounter({ + this.tweens.addCounter({ from: 0, to: 25, ease: "Power1", - onUpdate: function(tween, targets, text) { + onUpdate: function (tween, targets, text) { text.setText( Phaser.Utils.String.Pad(tween.getValue().toFixed(), 2, "0", 1) ); @@ -658,6 +465,7 @@ class PlayScene extends Phaser.Scene { } gameWon() { + this.game.onWon && this.game.onWon(); this.stopInputEvents(); this.text1.setText("Won!!"); @@ -665,26 +473,6 @@ class PlayScene extends Phaser.Scene { var i = this.clearGrid(); - // Put the winning monster in the middle - - var monster = this.add.image( - 400, - 300, - "flood", - "icon-" + this.frames[this.currentColor] - ); - - monster.setScale(0); - - this.tweens.add({ - targets: monster, - scaleX: 4, - scaleY: 4, - angle: 360 * 4, - duration: 1000, - delay: i, - }); - this.time.delayedCall(2000, this.boom, [], this); } diff --git a/games/game-flood-fill/scenes/bg.jpg b/games/game-flood-fill/scenes/bg.jpg new file mode 100644 index 0000000..f90a06b Binary files /dev/null and b/games/game-flood-fill/scenes/bg.jpg differ diff --git a/games/game-flood-fill/scenes/bu.png b/games/game-flood-fill/scenes/bu.png new file mode 100644 index 0000000..0046f71 Binary files /dev/null and b/games/game-flood-fill/scenes/bu.png differ diff --git a/games/game-flood-fill/scenes/gr.png b/games/game-flood-fill/scenes/gr.png new file mode 100644 index 0000000..b1342dd Binary files /dev/null and b/games/game-flood-fill/scenes/gr.png differ diff --git a/games/game-flood-fill/scenes/grey.png b/games/game-flood-fill/scenes/grey.png new file mode 100644 index 0000000..7bcd8ab Binary files /dev/null and b/games/game-flood-fill/scenes/grey.png differ diff --git a/games/game-flood-fill/scenes/instruction.png b/games/game-flood-fill/scenes/instruction.png new file mode 100644 index 0000000..f8fbe42 Binary files /dev/null and b/games/game-flood-fill/scenes/instruction.png differ diff --git a/games/game-flood-fill/scenes/pr.png b/games/game-flood-fill/scenes/pr.png new file mode 100644 index 0000000..ab44309 Binary files /dev/null and b/games/game-flood-fill/scenes/pr.png differ diff --git a/games/game-flood-fill/scenes/red.png b/games/game-flood-fill/scenes/red.png new file mode 100644 index 0000000..902f8b0 Binary files /dev/null and b/games/game-flood-fill/scenes/red.png differ diff --git a/games/game-flood-fill/scenes/tiles.json b/games/game-flood-fill/scenes/tiles.json new file mode 100644 index 0000000..91da1e3 --- /dev/null +++ b/games/game-flood-fill/scenes/tiles.json @@ -0,0 +1,146 @@ +{ + "textures": [ + { + "image": "tiles.png", + "format": "RGBA8888", + "size": { + "w": 588, + "h": 98 + }, + "scale": 1, + "frames": [ + { + "filename": "bu.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 96, + "h": 96 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 96, + "h": 96 + }, + "frame": { + "x": 1, + "y": 1, + "w": 96, + "h": 96 + } + }, + { + "filename": "gr.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 96, + "h": 96 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 96, + "h": 96 + }, + "frame": { + "x": 99, + "y": 1, + "w": 96, + "h": 96 + } + }, + { + "filename": "grey.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 96, + "h": 96 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 96, + "h": 96 + }, + "frame": { + "x": 197, + "y": 1, + "w": 96, + "h": 96 + } + }, + { + "filename": "pr.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 96, + "h": 96 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 96, + "h": 96 + }, + "frame": { + "x": 295, + "y": 1, + "w": 96, + "h": 96 + } + }, + { + "filename": "red.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 96, + "h": 96 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 96, + "h": 96 + }, + "frame": { + "x": 393, + "y": 1, + "w": 96, + "h": 96 + } + }, + { + "filename": "ye.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 96, + "h": 96 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 96, + "h": 96 + }, + "frame": { + "x": 491, + "y": 1, + "w": 96, + "h": 96 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:448d6f6ac325281bdfac54338d3b71aa:d38095e268c28c803ed294a284637824:accbe1e7e294ded8391337fc1c446319$" + } +} diff --git a/games/game-flood-fill/scenes/tiles.png b/games/game-flood-fill/scenes/tiles.png new file mode 100644 index 0000000..60ed6e0 Binary files /dev/null and b/games/game-flood-fill/scenes/tiles.png differ diff --git a/games/game-flood-fill/scenes/title.png b/games/game-flood-fill/scenes/title.png new file mode 100644 index 0000000..d7124ad Binary files /dev/null and b/games/game-flood-fill/scenes/title.png differ diff --git a/games/game-flood-fill/scenes/ye.png b/games/game-flood-fill/scenes/ye.png new file mode 100644 index 0000000..7937cb9 Binary files /dev/null and b/games/game-flood-fill/scenes/ye.png differ