From bb54186d9e74cd9044a6d57334ba3e9fc4d4919d Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Sun, 15 Mar 2020 19:28:41 +0100 Subject: [PATCH] Added rotation feature --- screens/Tetris/GameLogic.js | 20 +++++++++++++++-- screens/Tetris/TetrisScreen.js | 18 +++++++++++++-- screens/Tetris/Tetromino.js | 41 +++++++++++++++++++++++++++++----- 3 files changed, 70 insertions(+), 9 deletions(-) diff --git a/screens/Tetris/GameLogic.js b/screens/Tetris/GameLogic.js index a9b8263..cacda8f 100644 --- a/screens/Tetris/GameLogic.js +++ b/screens/Tetris/GameLogic.js @@ -19,6 +19,7 @@ export default class GameLogic { gameTickInterval: IntervalID; onTick: Function; + endCallback: Function; constructor(height: number, width: number) { this.height = height; @@ -114,6 +115,12 @@ export default class GameLogic { } } + tryRotateTetromino() { + this.currentObject.rotate(true); + if (!this.isTetrominoPositionValid()) + this.currentObject.rotate(false); + } + onTick(callback: Function) { this.gameTime++; this.score++; @@ -131,6 +138,11 @@ export default class GameLogic { callback(this.getFinalGrid()); } + rotatePressed(callback: Function) { + this.tryRotateTetromino(); + callback(this.getFinalGrid()); + } + createTetromino() { let shape = Math.floor(Math.random() * 7); this.currentObject = new Tetromino(shape); @@ -140,10 +152,12 @@ export default class GameLogic { endGame() { console.log('Game Over!'); + this.gameRunning = false; clearInterval(this.gameTickInterval); + this.endCallback(this.gameTime, this.score); } - startGame(callback: Function) { + startGame(tickCallback: Function, endCallback: Function) { if (this.gameRunning) return; this.gameRunning = true; @@ -151,8 +165,10 @@ export default class GameLogic { this.score = 0; this.currentGrid = this.getEmptyGrid(); this.createTetromino(); - this.onTick = this.onTick.bind(this, callback); + tickCallback(this.gameTime, this.score, this.getFinalGrid()); + this.onTick = this.onTick.bind(this, tickCallback); this.gameTickInterval = setInterval(this.onTick, this.gameTick); + this.endCallback = endCallback; } } diff --git a/screens/Tetris/TetrisScreen.js b/screens/Tetris/TetrisScreen.js index a405e05..a21c2a3 100644 --- a/screens/Tetris/TetrisScreen.js +++ b/screens/Tetris/TetrisScreen.js @@ -22,6 +22,7 @@ class TetrisScreen extends React.Component { logic: GameLogic; onTick: Function; + onGameEnd: Function; updateGrid: Function; constructor(props) { @@ -34,6 +35,7 @@ class TetrisScreen extends React.Component { gameScore: 0, }; this.onTick = this.onTick.bind(this); + this.onGameEnd = this.onGameEnd.bind(this); this.updateGrid = this.updateGrid.bind(this); const onScreenBlur = this.onScreenBlur.bind(this); this.props.navigation.addListener('blur', onScreenBlur); @@ -63,10 +65,17 @@ class TetrisScreen extends React.Component { startGame() { if (!this.logic.isGameRunning()) { - this.logic.startGame(this.onTick); + this.logic.startGame(this.onTick, this.onGameEnd); } } + onGameEnd(time: number, score: number) { + this.setState({ + gameTime: time, + gameScore: score, + }) + } + render() { return ( { this.startGame()} + onPress={() => this.logic.rotatePressed(this.updateGrid)} /> + this.startGame()} + /> ); diff --git a/screens/Tetris/Tetromino.js b/screens/Tetris/Tetromino.js index 1b15293..5aa75fe 100644 --- a/screens/Tetris/Tetromino.js +++ b/screens/Tetris/Tetromino.js @@ -22,6 +22,11 @@ export default class Tetromino { [0, 1, 0], [1, 1, 1], ], + 20: [ + [1, 0], + [1, 1], + [1, 0], + ], 3: [ [0, 1, 1], [1, 1, 0], @@ -48,14 +53,18 @@ export default class Tetromino { 4: '#ff000b', 5: '#1000ff', 6: '#ff9400', - } + }; - currentType: Tetromino.types; + currentType: Object; + currentShape: Object; + currentRotation: number; position: Object; constructor(type: Tetromino.types) { this.currentType = type; + this.currentShape = Tetromino.shapes[type]; + this.currentRotation = 0; this.position = {x: 0, y: 0}; } @@ -65,15 +74,37 @@ export default class Tetromino { getCellsCoordinates() { let coordinates = []; - for (let row = 0; row < Tetromino.shapes[this.currentType].length; row++) { - for (let col = 0; col < Tetromino.shapes[this.currentType][row].length; col++) { - if (Tetromino.shapes[this.currentType][row][col] === 1) + for (let row = 0; row < this.currentShape.length; row++) { + for (let col = 0; col < this.currentShape[row].length; col++) { + if (this.currentShape[row][col] === 1) coordinates.push({x: this.position.x + col, y: this.position.y + row}); } } return coordinates; } + rotate(isForward) { + this.currentRotation++; + if (this.currentRotation > 3) + this.currentRotation = 0; + + if (this.currentRotation === 0) { + this.currentShape = Tetromino.shapes[this.currentType]; + } else { + let result = []; + for(let i = 0; i < this.currentShape[0].length; i++) { + let row = this.currentShape.map(e => e[i]); + + if (isForward) + result.push(row.reverse()); + else + result.push(row); + } + this.currentShape = result; + } + + } + move(x: number, y: number) { this.position.x += x; this.position.y += y;