123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- // @flow
-
- import Piece from "./Piece";
- import ScoreManager from "./ScoreManager";
- import GridManager from "./GridManager";
-
- export default class GameLogic {
-
- static levelTicks = [
- 1000,
- 800,
- 600,
- 400,
- 300,
- 200,
- 150,
- 100,
- ];
-
- #scoreManager: ScoreManager;
- #gridManager: GridManager;
-
- #height: number;
- #width: number;
-
- #gameRunning: boolean;
- #gamePaused: boolean;
- #gameTime: number;
-
- #currentObject: Piece;
-
- #gameTick: number;
- #gameTickInterval: IntervalID;
- #gameTimeInterval: IntervalID;
-
- #pressInInterval: TimeoutID;
- #isPressedIn: boolean;
- #autoRepeatActivationDelay: number;
- #autoRepeatDelay: number;
-
- #nextPieces: Array<Piece>;
- #nextPiecesCount: number;
-
- #onTick: Function;
- #onClock: Function;
- endCallback: Function;
-
- #colors: Object;
-
- constructor(height: number, width: number, colors: Object) {
- this.#height = height;
- this.#width = width;
- this.#gameRunning = false;
- this.#gamePaused = false;
- this.#colors = colors;
- this.#autoRepeatActivationDelay = 300;
- this.#autoRepeatDelay = 50;
- this.#nextPieces = [];
- this.#nextPiecesCount = 3;
- this.#scoreManager = new ScoreManager();
- this.#gridManager = new GridManager(this.getWidth(), this.getHeight(), this.#colors);
- }
-
- getHeight(): number {
- return this.#height;
- }
-
- getWidth(): number {
- return this.#width;
- }
-
- getCurrentGrid() {
- return this.#gridManager.getCurrentGrid();
- }
-
- isGameRunning(): boolean {
- return this.#gameRunning;
- }
-
- isGamePaused(): boolean {
- return this.#gamePaused;
- }
-
- onFreeze() {
- this.#gridManager.freezeTetromino(this.#currentObject, this.#scoreManager);
- this.createTetromino();
- }
-
- setNewGameTick(level: number) {
- if (level >= GameLogic.levelTicks.length)
- return;
- this.#gameTick = GameLogic.levelTicks[level];
- clearInterval(this.#gameTickInterval);
- this.#gameTickInterval = setInterval(this.#onTick, this.#gameTick);
- }
-
- onTick(callback: Function) {
- this.#currentObject.tryMove(0, 1,
- this.#gridManager.getCurrentGrid(), this.getWidth(), this.getHeight(),
- () => this.onFreeze());
- callback(
- this.#scoreManager.getScore(),
- this.#scoreManager.getLevel(),
- this.#gridManager.getCurrentGrid());
- if (this.#scoreManager.canLevelUp())
- this.setNewGameTick(this.#scoreManager.getLevel());
- }
-
- onClock(callback: Function) {
- this.#gameTime++;
- callback(this.#gameTime);
- }
-
- canUseInput() {
- return this.#gameRunning && !this.#gamePaused
- }
-
- rightPressed(callback: Function) {
- this.#isPressedIn = true;
- this.movePressedRepeat(true, callback, 1, 0);
- }
-
- leftPressedIn(callback: Function) {
- this.#isPressedIn = true;
- this.movePressedRepeat(true, callback, -1, 0);
- }
-
- downPressedIn(callback: Function) {
- this.#isPressedIn = true;
- this.movePressedRepeat(true, callback, 0, 1);
- }
-
- movePressedRepeat(isInitial: boolean, callback: Function, x: number, y: number) {
- if (!this.canUseInput() || !this.#isPressedIn)
- return;
- const moved = this.#currentObject.tryMove(x, y,
- this.#gridManager.getCurrentGrid(), this.getWidth(), this.getHeight(),
- () => this.onFreeze());
- if (moved) {
- if (y === 1) {
- this.#scoreManager.incrementScore();
- callback(this.#gridManager.getCurrentGrid(), this.#scoreManager.getScore());
- } else
- callback(this.#gridManager.getCurrentGrid());
- }
- this.#pressInInterval = setTimeout(() =>
- this.movePressedRepeat(false, callback, x, y),
- isInitial ? this.#autoRepeatActivationDelay : this.#autoRepeatDelay
- );
- }
-
- pressedOut() {
- this.#isPressedIn = false;
- clearTimeout(this.#pressInInterval);
- }
-
- rotatePressed(callback: Function) {
- if (!this.canUseInput())
- return;
-
- if (this.#currentObject.tryRotate(this.#gridManager.getCurrentGrid(), this.getWidth(), this.getHeight()))
- callback(this.#gridManager.getCurrentGrid());
- }
-
- getNextPiecesPreviews() {
- let finalArray = [];
- for (let i = 0; i < this.#nextPieces.length; i++) {
- finalArray.push(this.#gridManager.getEmptyGrid(4, 4));
- this.#nextPieces[i].toGrid(finalArray[i], true);
- }
-
- return finalArray;
- }
-
- recoverNextPiece() {
- this.#currentObject = this.#nextPieces.shift();
- this.generateNextPieces();
- }
-
- generateNextPieces() {
- while (this.#nextPieces.length < this.#nextPiecesCount) {
- this.#nextPieces.push(new Piece(this.#colors));
- }
- }
-
- createTetromino() {
- this.pressedOut();
- this.recoverNextPiece();
- if (!this.#currentObject.isPositionValid(this.#gridManager.getCurrentGrid(), this.getWidth(), this.getHeight()))
- this.endGame(false);
- }
-
- togglePause() {
- if (!this.#gameRunning)
- return;
- this.#gamePaused = !this.#gamePaused;
- if (this.#gamePaused) {
- clearInterval(this.#gameTickInterval);
- clearInterval(this.#gameTimeInterval);
- } else {
- this.#gameTickInterval = setInterval(this.#onTick, this.#gameTick);
- this.#gameTimeInterval = setInterval(this.#onClock, 1000);
- }
- }
-
- endGame(isRestart: boolean) {
- this.#gameRunning = false;
- this.#gamePaused = false;
- clearInterval(this.#gameTickInterval);
- clearInterval(this.#gameTimeInterval);
- this.endCallback(this.#gameTime, this.#scoreManager.getScore(), isRestart);
- }
-
- startGame(tickCallback: Function, clockCallback: Function, endCallback: Function) {
- if (this.#gameRunning)
- this.endGame(true);
- this.#gameRunning = true;
- this.#gamePaused = false;
- this.#gameTime = 0;
- this.#scoreManager = new ScoreManager();
- this.#gameTick = GameLogic.levelTicks[this.#scoreManager.getLevel()];
- this.#gridManager = new GridManager(this.getWidth(), this.getHeight(), this.#colors);
- this.#nextPieces = [];
- this.generateNextPieces();
- this.createTetromino();
- tickCallback(
- this.#scoreManager.getScore(),
- this.#scoreManager.getLevel(),
- this.#gridManager.getCurrentGrid());
- clockCallback(this.#gameTime);
- this.#onTick = this.onTick.bind(this, tickCallback);
- this.#onClock = this.onClock.bind(this, clockCallback);
- this.#gameTickInterval = setInterval(this.#onTick, this.#gameTick);
- this.#gameTimeInterval = setInterval(this.#onClock, 1000);
- this.endCallback = endCallback;
- }
- }
|