import gems from "./gems.png"; import Match3 from "./match3"; import bg from "./bg.jpg"; import "../../font.css"; const gameOptions = { gemSize: 260, frameSize: 238, swapSpeed: 200, fallSpeed: 100, destroySpeed: 200, boardOffset: { x: 300, y: 520, }, }; export default class playGame extends Phaser.Scene { constructor() { super("scene"); } preload() { this.load.image("bg", bg); this.load.spritesheet("gems", gems, { frameWidth: gameOptions.frameSize, frameHeight: gameOptions.frameSize, }); } updateTexts() { this.score.text = this.scoreNum; this.moves.text = this.moveNum; } create() { const bg = this.add.image( this.game.config.width / 2, this.game.config.height / 2, "bg" ); bg.displayWidth = this.game.config.width; bg.displayHeight = this.game.config.height; this.scoreNum = 0; this.moveNum = 30; this.score = this.add.text(700, 320, this.scoreNum, { fontSize: 100, fontFamily: "game", color: "#3aab7d", }); this.moves = this.add.text(1552, 320, this.moveNum, { fontSize: 100, fontFamily: "game", color: "#3aab7d", }); this.match3 = new Match3({ rows: 6, columns: 6, items: 6, }); this.match3.generateField(); this.canPick = true; this.dragging = false; this.drawField(); this.input.on("pointerdown", this.gemSelect, this); } drawField() { this.poolArray = []; for (let i = 0; i < this.match3.getRows(); i++) { for (let j = 0; j < this.match3.getColumns(); j++) { let gemX = gameOptions.boardOffset.x + gameOptions.gemSize * j + gameOptions.gemSize / 2; let gemY = gameOptions.boardOffset.y + gameOptions.gemSize * i + gameOptions.gemSize / 2; let gem = this.add.sprite( gemX, gemY, "gems", this.match3.valueAt(i, j) ); this.match3.setCustomData(i, j, gem); } } } gemSelect(pointer) { if (this.canPick) { this.dragging = true; let row = Math.floor( (pointer.y - gameOptions.boardOffset.y) / gameOptions.gemSize ); let col = Math.floor( (pointer.x - gameOptions.boardOffset.x) / gameOptions.gemSize ); if (this.match3.validPick(row, col)) { let selectedGem = this.match3.getSelectedItem(); if (!selectedGem) { this.match3.customDataOf(row, col).setScale(1.2); this.match3.customDataOf(row, col).setDepth(1); this.match3.setSelectedItem(row, col); } else { if ( this.match3.areTheSame( row, col, selectedGem.row, selectedGem.column ) ) { this.match3.customDataOf(row, col).setScale(1); this.match3.deleselectItem(); } else { if ( this.match3.areNext(row, col, selectedGem.row, selectedGem.column) ) { this.match3 .customDataOf(selectedGem.row, selectedGem.column) .setScale(1); this.match3.deleselectItem(); if (this.moveNum === 0) { return this.game.onLose && this.game.onLose(); } this.moveNum--; this.updateTexts(); this.swapGems( row, col, selectedGem.row, selectedGem.column, true ); } else { this.match3 .customDataOf(selectedGem.row, selectedGem.column) .setScale(1); this.match3.customDataOf(row, col).setScale(1.2); this.match3.setSelectedItem(row, col); } } } } } } swapGems(row, col, row2, col2, swapBack) { let movements = this.match3.swapItems(row, col, row2, col2); this.swappingGems = 2; this.canPick = false; movements.forEach( function (movement) { this.tweens.add({ targets: this.match3.customDataOf(movement.row, movement.column), x: this.match3.customDataOf(movement.row, movement.column).x + gameOptions.gemSize * movement.deltaColumn, y: this.match3.customDataOf(movement.row, movement.column).y + gameOptions.gemSize * movement.deltaRow, duration: gameOptions.swapSpeed, callbackScope: this, onComplete: function () { this.swappingGems--; if (this.swappingGems == 0) { if (!this.match3.matchInBoard()) { if (swapBack) { this.swapGems(row, col, row2, col2, false); } else { this.canPick = true; } } else { this.handleMatches(); } } }, }); }.bind(this) ); } handleMatches() { let gemsToRemove = this.match3.getMatchList(); this.scoreNum += gemsToRemove.length * 10; this.updateTexts(); let destroyed = 0; gemsToRemove.forEach( function (gem) { this.poolArray.push(this.match3.customDataOf(gem.row, gem.column)); destroyed++; this.tweens.add({ targets: this.match3.customDataOf(gem.row, gem.column), alpha: 0, duration: gameOptions.destroySpeed, callbackScope: this, onComplete: function (event, sprite) { destroyed--; if (destroyed == 0) { this.makeGemsFall(); } }, }); }.bind(this) ); } makeGemsFall() { let moved = 0; this.match3.removeMatches(); let fallingMovements = this.match3.arrangeBoardAfterMatch(); fallingMovements.forEach( function (movement) { moved++; this.tweens.add({ targets: this.match3.customDataOf(movement.row, movement.column), y: this.match3.customDataOf(movement.row, movement.column).y + movement.deltaRow * gameOptions.gemSize, duration: gameOptions.fallSpeed * Math.abs(movement.deltaRow), callbackScope: this, onComplete: function () { moved--; if (moved == 0) { this.endOfMove(); } }, }); }.bind(this) ); let replenishMovements = this.match3.replenishBoard(); replenishMovements.forEach( function (movement) { moved++; let sprite = this.poolArray.pop(); sprite.alpha = 1; sprite.y = gameOptions.boardOffset.y + gameOptions.gemSize * (movement.row - movement.deltaRow + 1) - gameOptions.gemSize / 2; (sprite.x = gameOptions.boardOffset.x + gameOptions.gemSize * movement.column + gameOptions.gemSize / 2), sprite.setFrame(this.match3.valueAt(movement.row, movement.column)); this.match3.setCustomData(movement.row, movement.column, sprite); this.tweens.add({ targets: sprite, y: gameOptions.boardOffset.y + gameOptions.gemSize * movement.row + gameOptions.gemSize / 2, duration: gameOptions.fallSpeed * movement.deltaRow, callbackScope: this, onComplete: function () { moved--; if (moved == 0) { this.endOfMove(); } }, }); }.bind(this) ); } endOfMove() { if (this.match3.matchInBoard()) { this.time.addEvent({ delay: 250, callback: this.handleMatches(), }); } else { this.canPick = true; this.selectedGem = null; } } }