123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- import { Point } from "../../libraries/spatial/Point.js";
- import { Rectangle } from "../../libraries/spatial/Rectangle.js";
- import { Board } from "../Board.js";
- import {Slot} from "../Slot.js";
- export class GameState {
- constructor(fsm) {
- this.stateMachine = fsm;
- this.board = null;
- this.playerData = {current: 1, level: 1};
- this.canvasBounds = null;
- this.showNextButton = false;
- this.showUndoButton = false;
- this.movelist = [];
- this.boundMouseEvent = {};
- this.levelData = [];
- }
- init() {
- this.board = new Board();
- this.board.init(this);
- this.boundMouseEvent['mousedown'] = this.mouseDown.bind(this);
- this.boundMouseEvent['mousemove'] = this.mouseMove.bind(this);
- for(let key in this.boundMouseEvent) {
- window.addEventListener(key, this.boundMouseEvent[key]);
- }
- //TODO: replace next button
- //TODO: replace undo button
- }
- setLevelData(data) {
- this.levelData = data;
- }
- getLevelData() {
- return this.levelData;
- }
- setPlayerData(data) {
- this.playerData = data;
- }
- getPlayerData() {
- return this.playerData;
- }
- getLevel(levelId) {
- return this.getLevelData()[levelId];
- }
- draw(ctx, scaledCanvas) {
- this.canvasBounds = scaledCanvas.bounds;
- try {
- this.board.draw(ctx, scaledCanvas);
- ctx.fillStyle = "white";
- ctx.strokeStyle = "black";
- ctx.font = "48px Luckiest Guy";
- ctx.textAlign = "center";
- ctx.lineWidth = 4;
- ctx.fillText(`Level ${this.playerData.current}`, scaledCanvas.center.x, 48);
- ctx.strokeText(`Level ${this.playerData.current}`, scaledCanvas.center.x, 48);
- if(this.showNextButton) {
- this.drawNextButton(ctx, scaledCanvas);
- }
- if(this.showUndoButton) {
- this.drawUndoButton(ctx, scaledCanvas);
- }
- } catch(e) {
- ctx.setTransform(1, 0, 0, 1, 0, 0);
- ctx.fillStyle = 'crimson';
- ctx.font = "32px Arial";
- ctx.fontAlign = "left";
- ctx.fillText(`error: ${e.message}`, 4, 32);
- console.error(e);
- }
- if(this.showWinDialog) {
- this.drawWinDialog(ctx, scaledCanvas);
- }
- }
- update(delta) {
- this.board.update(delta);
- }
- drawNextButton(ctx, scaledCanvas) {
- let bounds = this.getNextButtonBounds();
- ctx.fillStyle = "rgba(255,255,255,0.5)";
- ctx.save();
- ctx.translate(bounds.x, bounds.y);
- ctx.beginPath();
- ctx.moveTo(bounds.width, bounds.height / 2);
- ctx.lineTo(bounds.width / 2, bounds.height);
- ctx.lineTo(bounds.width / 2, 0);
- ctx.closePath();
- ctx.fill();
- ctx.fillStyle = "white";
- ctx.font = "24px Arial";
- ctx.textAlign = "left";
- ctx.fillText(`next`, 0, bounds.height/2 + 8);
- ctx.restore();
- }
- drawUndoButton(ctx, scaledCanvas) {
- let bounds = this.getUndoButtonBounds();
- ctx.fillStyle = "rgba(255,255,255,0.5)";
- ctx.save();
- ctx.translate(bounds.x, bounds.y);
- ctx.beginPath();
- ctx.rect(0, 0, bounds.width, bounds.height);
- ctx.closePath();
- ctx.fill();
- ctx.fillStyle = "white";
- ctx.font = "24px Arial";
- ctx.textAlign = "center";
- let undoText = this.movelist.length < 9 ? `undo (${this.movelist.length})` : `undo`;
- ctx.fillText(undoText, bounds.width / 2, bounds.height - 20);
- ctx.restore();
- }
- drawWinDialog(ctx, scaledCanvas) {
- let bounds = scaledCanvas.bounds;
- ctx.fillStyle = "rgba(255, 255, 255, 0.5)";
- ctx.beginPath();
- ctx.rect(bounds.width / 4, bounds.height / 4 + bounds.height / 16, bounds.width / 2, bounds.height / 8);
- ctx.closePath();
- ctx.fill();
- ctx.fillStyle = "white";
- ctx.strokeStyle = "black";
- ctx.font = "48px Luckiest Guy";
- ctx.textAlign = "center";
- ctx.lineWidth = 4;
- ctx.fillText(`You Win!`, bounds.center.x, bounds.height / 2 - bounds.height / 8 + 12);
- ctx.strokeText(`You Win!`, bounds.center.x, bounds.height / 2 - bounds.height / 8 + 12);
- }
- mouseDown(event) {
- let mousePoint = new Point(event.clientX, event.clientY);
- let nextBounds = this.getNextButtonBounds();
- if(this.showNextButton && nextBounds.pointWithin(mousePoint)) {
- if(this.playerData.level == this.playerData.current) {
- this.playerData.level++;
- }
- this.playerData.current++;
- localStorage.setItem('ballsort-playerdata', JSON.stringify(this.playerData));
- this.board.reset();
- this.showNextButton = false;
- this.showWinDialog = false;
- }
- if(this.showUndoButton) {
- let undoBounds = this.getUndoButtonBounds();
- if(undoBounds.pointWithin(mousePoint)) {
- this.undo();
- }
- }
- if(!this.showWinDialog) {
- this.board.mouseDown(event);
- }
- }
- mouseMove(event) {
- document.body.style.cursor = "default";
- let mousePoint = new Point(event.clientX, event.clientY);
- if(this.showNextButton) {
- let nextBounds = this.getNextButtonBounds();
- if(nextBounds.pointWithin(mousePoint)) {
- document.body.style.cursor = "pointer";
- }
- }
- if(this.showUndoButton) {
- let undoBounds = this.getUndoButtonBounds();
- if(undoBounds.pointWithin(mousePoint)) {
- document.body.style.cursor = "pointer";
- }
- }
- if(!this.showWinDialog) {
- this.board.mouseMove(event);
- }
- }
- trackMove(fromSlot, toSlot) {
- let move = {from: fromSlot, to: toSlot};
- this.movelist.push(move);
- this.showUndoButton = this.movelist.length > 0;
- }
- undo() {
- if(this.board.heldBall) {
- this.board.placeHeldBallInSlot(this.board.removedFromSlot);
- return;
- }
- let move = this.movelist.pop();
- if(move) {
- let ball = move.to.removeBall();
- move.from.addBall(ball);
- }
- this.showUndoButton = this.movelist.length > 0;
- }
- getNextButtonBounds() {
- let boardBounds = this.board.getBounds();
- let position = {
- x: this.canvasBounds.center.x,
- y: boardBounds.y + boardBounds.height + 20,
- }
- if(this.canvasBounds.height < 660) {
- position.x = this.canvasBounds.width - 100;
- position.y = Slot.height + (Slot.heightPadding / 2) + boardBounds.y - 25;
- }
- return new Rectangle(position.x, position.y, 100, 50);
- }
- getUndoButtonBounds() {
- let boardBounds = this.board.getBounds();
- let position = {
- x: this.canvasBounds.center.x,
- y: boardBounds.y + boardBounds.height + 20,
- }
- if(this.canvasBounds.height < 660) {
- position.x = this.canvasBounds.width - 100;
- position.y = Slot.height + (Slot.heightPadding / 2) + boardBounds.y - 25;
- }
- return new Rectangle(position.x, position.y, 100, 50);
- }
- win() {
- setTimeout(() => {
- this.showWinDialog = true;
- this.showNextButton = true;
- this.showUndoButton = false;
- this.movelist = [];
- }, 400);
-
- }
- enter() {
- this.init(this.stateMachine.getState("game"));
- }
- leave() {
- this.board.destroy();
- for(let key in this.boundMouseEvent) {
- window.removeEventListener(key, this.boundMouseEvent[key]);
- }
- }
- }
|