You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
288 lines
8.2 KiB
288 lines
8.2 KiB
import gems from "./gems.png";
|
|
import Match3 from "./match3";
|
|
import bg from "./bg.jpg";
|
|
import tip from "./tip.png";
|
|
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("tip", tip);
|
|
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, 356, this.scoreNum, {
|
|
fontSize: 100,
|
|
fontFamily: "game",
|
|
color: "#3aab7d",
|
|
});
|
|
this.moves = this.add.text(1640, 356, 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);
|
|
this.instructionWrapper = this.add.rectangle(
|
|
this.game.config.width / 2,
|
|
this.game.config.height / 2,
|
|
this.game.config.width,
|
|
this.game.config.height,
|
|
0x000000,
|
|
0.6
|
|
);
|
|
this.instructions = this.add.image(
|
|
this.game.config.width / 2,
|
|
this.game.config.height / 2,
|
|
"tip"
|
|
);
|
|
}
|
|
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.instructionWrapper.active) {
|
|
this.instructionWrapper.destroy();
|
|
this.instructions.destroy();
|
|
return;
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|