import { Camera } from "../../libraries/Camera.js"; import { Point } from "../../libraries/spatial/Point.js"; import { TweenManager, Tween, Easing } from "../../libraries/Tween.js"; import { Board } from "../Board.js"; import { Global } from "../../libraries/Global.js"; import { Piece } from "../Piece.js"; export class GameState { constructor(fsm) { this.stateMachine = fsm; this.boundEvents = {}; this.camera = new Camera(0, 0); this.tweenManager = new TweenManager() this.ballPosition = new Point(0,0); this.cameraTweenId = -1; this.frameFocus = 0; this.tileWidth = 64; this.boards = []; this.pieces = []; } init() { this.boundEvents['mousedown'] = this.mouseDown.bind(this); this.boundEvents['mousemove'] = this.mouseMove.bind(this); this.boundEvents['touchstart'] = this.touchStart.bind(this); this.boundEvents['touchmove'] = this.touchMove.bind(this); this.boundEvents['touchend'] = this.touchEnd.bind(this); this.boundEvents['mouseup'] = this.mouseUp.bind(this); this.boundEvents['resize'] = this.resize.bind(this); this.boundEvents['touch'] for(let key in this.boundEvents) { window.addEventListener(key, this.boundEvents[key]); } this.boards = []; this.boards.push(new Board(this)) this.boards.push(new Board(this)) this.boards.push(new Board(this)) this.pieces = []; this.pieces.push(new Piece(this, "L", 0, 0)) this.pieces.push(new Piece(this, "S", 0, 0)) this.pieces.push(new Piece(this, "U", 0, 0)) this.resize() } draw(ctx) { this.camera.drawAtCamera(ctx, () => { for(let i = 0; i < this.boards.length; i++) { let board = this.boards[i]; board.draw(ctx); } }) let toolbarTop = Global.screenBounds.height / 2; let toolbarHeight = this.tileWidth * 6; ctx.save(); ctx.translate(0, toolbarTop); ctx.fillStyle = "rgba(255, 255, 255, 0.5)"; ctx.beginPath() ctx.rect(0, 0, Global.screenBounds.width, toolbarHeight) ctx.fill() ctx.fillStyle = "black"; ctx.font = "24px Ariel" ctx.fillText("Toolbar", 0, 24) for(let i = 0; i < this.pieces.length; i++) { let piece = this.pieces[i]; piece.draw(ctx); } ctx.restore(); ctx.fillStyle = "rgba(40, 40, 220, 0.5)"; ctx.beginPath() let navTop = toolbarTop + toolbarHeight; let navHeight = Global.screenBounds.height - navTop; ctx.rect(0, navTop, Global.screenBounds.width, navHeight) ctx.fill() ctx.fillStyle = "black"; ctx.font = "24px Ariel" ctx.fillText("Nav", 0, navTop + 24) } update(delta) { for(let i = 0; i < this.boards.length; i++) { let board = this.boards[i]; board.update(delta); } for(let i = 0; i < this.pieces.length; i++) { let piece = this.pieces[i]; piece.update(delta); } this.tweenManager.update(); } mouseDown(event) { let mousePoint = new Point(event.clientX, event.clientY); if(mousePoint.y <= Global.screenBounds.center.y) { let direction = Math.sign(mousePoint.x - Global.screenBounds.center.x) this.frameFocus += direction this.frameFocus = Math.max(Math.min(this.boards.length - 1, this.frameFocus), 0) let tween = new Tween(this.camera.position, {x: this.boards[this.frameFocus].position.x}, 1000, Easing.Cubic.EaseOut); this.tweenManager.cancel(this.cameraTweenId) this.cameraTweenId = this.tweenManager.add(tween); } if(event.button == 0) { this.dragStartPoint = mousePoint; this.draggedPiece = null; mousePoint.y -= Global.screenBounds.height / 2; for(let i = 0; i < this.pieces.length; i++) { let piece = this.pieces[i]; if(piece.pointWithin(mousePoint)) { this.draggedPiece = piece; break; } } } } touchStart(event) { let mousePoint = new Point(event.touches[0].clientX, event.touches[0].clientY); if(event.touches.length == 1) { this.dragStartPoint = mousePoint; this.draggedPiece = null; mousePoint.y -= Global.screenBounds.height / 2; for(let i = 0; i < this.pieces.length; i++) { let piece = this.pieces[i]; if(piece.pointWithin(mousePoint)) { this.draggedPiece = piece; break; } } } } mouseMove(event) { document.body.style.cursor = "default"; let mousePoint = new Point(event.clientX, event.clientY); if(this.draggedPiece && !this.dragStartPoint.equals(mousePoint)) { this.dragStarted = true; this.draggedPiece.position.x = mousePoint.x this.draggedPiece.position.y = mousePoint.y - Global.screenBounds.height / 2 } } touchMove(event) { let mousePoint = new Point(event.touches[0].clientX, event.touches[0].clientY); if(this.draggedPiece && !this.dragStartPoint.equals(mousePoint)) { this.dragStarted = true; this.draggedPiece.position.x = mousePoint.x this.draggedPiece.position.y = mousePoint.y - Global.screenBounds.height / 2 } } mouseUp(event) { if(this.dragStarted) { this.dragStarted = false; this.draggedPiece = null; return } this.dragStarted = false; this.draggedPiece = null; let mousePoint = new Point(event.clientX, event.clientY); mousePoint.y -= Global.screenBounds.height / 2; for(let i = 0; i < this.pieces.length; i++) { let piece = this.pieces[i]; piece.mouseDown(event, mousePoint, this.tweenManager); } } touchEnd(event) { if(this.dragStarted) { this.dragStarted = false; this.draggedPiece = null; return } this.dragStarted = false; this.draggedPiece = null; let mousePoint = new Point(event.clientX, event.clientY); mousePoint.y -= Global.screenBounds.height / 2; for(let i = 0; i < this.pieces.length; i++) { let piece = this.pieces[i]; piece.mouseDown(event, mousePoint, this.tweenManager); } } resize(event) { let possibleWidth = Math.min(64, Math.floor(Global.screenBounds.width / 11)) let possibleHeight = Math.min(64, Math.floor((Global.screenBounds.height / 2) / 11)) this.tileWidth = Math.min(possibleWidth, possibleHeight); for(let i = 0; i < this.boards.length; i++) { let board = this.boards[i]; board.position.x = (14 * this.tileWidth) * i; if(board == this.boards[this.frameFocus]) { this.camera.position.x = board.position.x } } let toolbarHeight = this.tileWidth * 6; this.pieces[0].position.x = Global.screenBounds.width / 4 this.pieces[0].position.y = toolbarHeight / 2 this.pieces[1].position.x = Global.screenBounds.width / 2 this.pieces[1].position.y = toolbarHeight / 2 this.pieces[2].position.x = 3 /4 * Global.screenBounds.width this.pieces[2].position.y = toolbarHeight / 2 } enter() { this.init(this.stateMachine.getState("game")); } leave() { this.board.destroy(); for(let key in this.boundEvents) { window.removeEventListener(key, this.boundEvents[key]); } } }