forked from vergnet/application-amicale
Added rotation feature
This commit is contained in:
parent
3aaf56a660
commit
bb54186d9e
3 changed files with 70 additions and 9 deletions
|
@ -19,6 +19,7 @@ export default class GameLogic {
|
||||||
gameTickInterval: IntervalID;
|
gameTickInterval: IntervalID;
|
||||||
|
|
||||||
onTick: Function;
|
onTick: Function;
|
||||||
|
endCallback: Function;
|
||||||
|
|
||||||
constructor(height: number, width: number) {
|
constructor(height: number, width: number) {
|
||||||
this.height = height;
|
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) {
|
onTick(callback: Function) {
|
||||||
this.gameTime++;
|
this.gameTime++;
|
||||||
this.score++;
|
this.score++;
|
||||||
|
@ -131,6 +138,11 @@ export default class GameLogic {
|
||||||
callback(this.getFinalGrid());
|
callback(this.getFinalGrid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rotatePressed(callback: Function) {
|
||||||
|
this.tryRotateTetromino();
|
||||||
|
callback(this.getFinalGrid());
|
||||||
|
}
|
||||||
|
|
||||||
createTetromino() {
|
createTetromino() {
|
||||||
let shape = Math.floor(Math.random() * 7);
|
let shape = Math.floor(Math.random() * 7);
|
||||||
this.currentObject = new Tetromino(shape);
|
this.currentObject = new Tetromino(shape);
|
||||||
|
@ -140,10 +152,12 @@ export default class GameLogic {
|
||||||
|
|
||||||
endGame() {
|
endGame() {
|
||||||
console.log('Game Over!');
|
console.log('Game Over!');
|
||||||
|
this.gameRunning = false;
|
||||||
clearInterval(this.gameTickInterval);
|
clearInterval(this.gameTickInterval);
|
||||||
|
this.endCallback(this.gameTime, this.score);
|
||||||
}
|
}
|
||||||
|
|
||||||
startGame(callback: Function) {
|
startGame(tickCallback: Function, endCallback: Function) {
|
||||||
if (this.gameRunning)
|
if (this.gameRunning)
|
||||||
return;
|
return;
|
||||||
this.gameRunning = true;
|
this.gameRunning = true;
|
||||||
|
@ -151,8 +165,10 @@ export default class GameLogic {
|
||||||
this.score = 0;
|
this.score = 0;
|
||||||
this.currentGrid = this.getEmptyGrid();
|
this.currentGrid = this.getEmptyGrid();
|
||||||
this.createTetromino();
|
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.gameTickInterval = setInterval(this.onTick, this.gameTick);
|
||||||
|
this.endCallback = endCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ class TetrisScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
logic: GameLogic;
|
logic: GameLogic;
|
||||||
onTick: Function;
|
onTick: Function;
|
||||||
|
onGameEnd: Function;
|
||||||
updateGrid: Function;
|
updateGrid: Function;
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -34,6 +35,7 @@ class TetrisScreen extends React.Component<Props, State> {
|
||||||
gameScore: 0,
|
gameScore: 0,
|
||||||
};
|
};
|
||||||
this.onTick = this.onTick.bind(this);
|
this.onTick = this.onTick.bind(this);
|
||||||
|
this.onGameEnd = this.onGameEnd.bind(this);
|
||||||
this.updateGrid = this.updateGrid.bind(this);
|
this.updateGrid = this.updateGrid.bind(this);
|
||||||
const onScreenBlur = this.onScreenBlur.bind(this);
|
const onScreenBlur = this.onScreenBlur.bind(this);
|
||||||
this.props.navigation.addListener('blur', onScreenBlur);
|
this.props.navigation.addListener('blur', onScreenBlur);
|
||||||
|
@ -63,10 +65,17 @@ class TetrisScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
startGame() {
|
startGame() {
|
||||||
if (!this.logic.isGameRunning()) {
|
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() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={{
|
<View style={{
|
||||||
|
@ -104,8 +113,13 @@ class TetrisScreen extends React.Component<Props, State> {
|
||||||
<IconButton
|
<IconButton
|
||||||
icon="format-rotate-90"
|
icon="format-rotate-90"
|
||||||
size={40}
|
size={40}
|
||||||
onPress={() => this.startGame()}
|
onPress={() => this.logic.rotatePressed(this.updateGrid)}
|
||||||
/>
|
/>
|
||||||
|
<IconButton
|
||||||
|
icon="power"
|
||||||
|
size={40}
|
||||||
|
onPress={() => this.startGame()}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
|
@ -22,6 +22,11 @@ export default class Tetromino {
|
||||||
[0, 1, 0],
|
[0, 1, 0],
|
||||||
[1, 1, 1],
|
[1, 1, 1],
|
||||||
],
|
],
|
||||||
|
20: [
|
||||||
|
[1, 0],
|
||||||
|
[1, 1],
|
||||||
|
[1, 0],
|
||||||
|
],
|
||||||
3: [
|
3: [
|
||||||
[0, 1, 1],
|
[0, 1, 1],
|
||||||
[1, 1, 0],
|
[1, 1, 0],
|
||||||
|
@ -48,14 +53,18 @@ export default class Tetromino {
|
||||||
4: '#ff000b',
|
4: '#ff000b',
|
||||||
5: '#1000ff',
|
5: '#1000ff',
|
||||||
6: '#ff9400',
|
6: '#ff9400',
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
currentType: Tetromino.types;
|
currentType: Object;
|
||||||
|
currentShape: Object;
|
||||||
|
currentRotation: number;
|
||||||
position: Object;
|
position: Object;
|
||||||
|
|
||||||
constructor(type: Tetromino.types) {
|
constructor(type: Tetromino.types) {
|
||||||
this.currentType = type;
|
this.currentType = type;
|
||||||
|
this.currentShape = Tetromino.shapes[type];
|
||||||
|
this.currentRotation = 0;
|
||||||
this.position = {x: 0, y: 0};
|
this.position = {x: 0, y: 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,15 +74,37 @@ export default class Tetromino {
|
||||||
|
|
||||||
getCellsCoordinates() {
|
getCellsCoordinates() {
|
||||||
let coordinates = [];
|
let coordinates = [];
|
||||||
for (let row = 0; row < Tetromino.shapes[this.currentType].length; row++) {
|
for (let row = 0; row < this.currentShape.length; row++) {
|
||||||
for (let col = 0; col < Tetromino.shapes[this.currentType][row].length; col++) {
|
for (let col = 0; col < this.currentShape[row].length; col++) {
|
||||||
if (Tetromino.shapes[this.currentType][row][col] === 1)
|
if (this.currentShape[row][col] === 1)
|
||||||
coordinates.push({x: this.position.x + col, y: this.position.y + row});
|
coordinates.push({x: this.position.x + col, y: this.position.y + row});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return coordinates;
|
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) {
|
move(x: number, y: number) {
|
||||||
this.position.x += x;
|
this.position.x += x;
|
||||||
this.position.y += y;
|
this.position.y += y;
|
||||||
|
|
Loading…
Reference in a new issue