Added rotation feature

This commit is contained in:
Arnaud Vergnet 2020-03-15 19:28:41 +01:00
parent 3aaf56a660
commit bb54186d9e
3 changed files with 70 additions and 9 deletions

View file

@ -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;
}
}

View file

@ -22,6 +22,7 @@ class TetrisScreen extends React.Component<Props, State> {
logic: GameLogic;
onTick: Function;
onGameEnd: Function;
updateGrid: Function;
constructor(props) {
@ -34,6 +35,7 @@ class TetrisScreen extends React.Component<Props, State> {
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<Props, State> {
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 (
<View style={{
@ -104,8 +113,13 @@ class TetrisScreen extends React.Component<Props, State> {
<IconButton
icon="format-rotate-90"
size={40}
onPress={() => this.startGame()}
onPress={() => this.logic.rotatePressed(this.updateGrid)}
/>
<IconButton
icon="power"
size={40}
onPress={() => this.startGame()}
/>
</View>
</View>
);

View file

@ -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;