Skip to content
This repository has been archived by the owner on Nov 11, 2021. It is now read-only.

Commit

Permalink
gameover screen
Browse files Browse the repository at this point in the history
  • Loading branch information
lochungtin committed May 31, 2021
1 parent 37a108d commit 2586a41
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 21 deletions.
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"react-dom": "16.13.1",
"react-native": "~0.63.4",
"react-native-gesture-handler": "^1.10.3",
"react-native-modal": "^11.10.0",
"react-native-reanimated": "^2.1.0",
"react-native-safe-area-context": "^3.2.0",
"react-native-screens": "^3.0.0",
Expand Down
74 changes: 53 additions & 21 deletions src/components/Board/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { View } from 'react-native';
import { Directions, FlingGestureHandler } from 'react-native-gesture-handler';
import { connect } from 'react-redux';

import GameoverModal from '../GameoverModal';
import Tile from './Tile';

import { darktheme } from '../../data/color';
Expand All @@ -21,47 +22,78 @@ interface ReduxProps {

class BoardView extends React.Component<ReduxProps> {

state = {
open: true,
}

getHighestTile = (): number => {
let highest = 0;
this.props.game.board.forEach(row => row.forEach(num => {
if (num > highest)
highest = num;
}));

return highest;
}

onNewGame = () => {
store.dispatch(updateGame({ ...new Board(4) }));
this.setState({ open: false });
}

onSaveGame = () => {
this.setState({ open: false });
}

swipe = (direction: Direction): void => {
let temp = { ...this.props.game };

// update history
store.dispatch(updateHistory({ ...temp }));
console.log(temp);

// perform swipe
Board.swipe(temp, direction);

// validate board
if (!Board.validate(temp))
console.log('e');
this.setState({ open: true });

// save game config
store.dispatch(updateGame(temp));
console.log(temp);
}

render() {
return (
<FlingGestureHandler direction={Directions.UP} onEnded={() => this.swipe(Direction.up)}>
<FlingGestureHandler direction={Directions.DOWN} onEnded={() => this.swipe(Direction.down)} >
<FlingGestureHandler direction={Directions.LEFT} onEnded={() => this.swipe(Direction.left)}>
<FlingGestureHandler direction={Directions.RIGHT} onEnded={() => this.swipe(Direction.right)}>
<View style={{ ...BoardStyles.root, backgroundColor: darktheme.boardColor }}>
{this.props.game.board.map(row => {
return (
<View key={keygen()} style={BoardStyles.row}>
{row.map(cell => {
return (
<Tile key={keygen()} dim={4} number={cell} />
);
})}
</View>
);
})}
</View>
<>
<FlingGestureHandler direction={Directions.UP} onEnded={() => this.swipe(Direction.up)}>
<FlingGestureHandler direction={Directions.DOWN} onEnded={() => this.swipe(Direction.down)} >
<FlingGestureHandler direction={Directions.LEFT} onEnded={() => this.swipe(Direction.left)}>
<FlingGestureHandler direction={Directions.RIGHT} onEnded={() => this.swipe(Direction.right)}>
<View style={{ ...BoardStyles.root, backgroundColor: darktheme.boardColor }}>
{this.props.game.board.map(row => {
return (
<View key={keygen()} style={BoardStyles.row}>
{row.map(cell => {
return (
<Tile key={keygen()} dim={4} number={cell} />
);
})}
</View>
);
})}
</View>
</FlingGestureHandler>
</FlingGestureHandler>
</FlingGestureHandler>
</FlingGestureHandler>
</FlingGestureHandler>
<GameoverModal
highestTile={this.getHighestTile()}
onNewGame={this.onNewGame}
onSaveGame={this.onSaveGame}
open={this.state.open}
score={this.props.game.score}
/>
</>
);
}
}
Expand Down
31 changes: 31 additions & 0 deletions src/components/Board/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,36 @@ export const BoardStyles = StyleSheet.create({
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
},
gameoverModalRoot: {
alignItems: 'center',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
height: 300,
},
gameoverText: {
fontSize: 20,
},
gameoverStatsContainer: {
alignItems: 'center',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
height: 70,
},
gameoverStatsRow: {
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
width: screenWidth * 0.7
},
gameoverOptionBar: {
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
width: screenWidth * 0.7
}
});
71 changes: 71 additions & 0 deletions src/components/GameoverModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from 'react';
import { TouchableOpacity, Text, View, } from 'react-native';
import Modal from 'react-native-modal';
import { connect } from 'react-redux';

import { darktheme } from '../../data/color';
import { ModalStyles } from './styles';

import { GameConfig } from '../../utils/types';

interface ModalProps {
onSaveGame: () => void,
onNewGame: () => void,
score: number,
highestTile: number,
open: boolean,
}

class BoardView extends React.Component<ModalProps> {

render() {
return (
<Modal
backdropOpacity={0.9}
isVisible={this.props.open}
>
<View style={ModalStyles.modalRoot}>
<Text style={{ ...ModalStyles.text, color: darktheme.textColor }}>
<Text style={{ color: darktheme.accentColor }}>G A M E</Text> O V E R
</Text>
<View style={ModalStyles.statsContainer}>
<View style={ModalStyles.statsRow}>
<Text style={{ ...ModalStyles.text, color: darktheme.accentColor }}>
Score :
</Text>
<Text style={{ ...ModalStyles.text, color: darktheme.textColor }}>
{this.props.score}
</Text>
</View>
<View style={ModalStyles.statsRow}>
<Text style={{ ...ModalStyles.text, color: darktheme.accentColor }}>
Highest Tile :
</Text>
<Text style={{ ...ModalStyles.text, color: darktheme.textColor }}>
{this.props.highestTile}
</Text>
</View>
</View>
<View style={ModalStyles.optionBar}>
<TouchableOpacity onPress={this.props.onSaveGame}>
<Text style={{ ...ModalStyles.text, color: darktheme.accentColor }}>
SAVE RECORD
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.props.onNewGame}>
<Text style={{ ...ModalStyles.text, color: darktheme.textColor }}>
NEW GAME
</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
);
}
}

const mapStateToProps = state => ({

});

export default connect(mapStateToProps)(BoardView);
37 changes: 37 additions & 0 deletions src/components/GameoverModal/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Dimensions, StyleSheet } from 'react-native';

const screenWidth = Dimensions.get('screen').width;

export const ModalStyles = StyleSheet.create({
modalRoot: {
alignItems: 'center',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
height: 300,
},
text: {
fontSize: 20,
},
statsContainer: {
alignItems: 'center',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
height: 70,
},
statsRow: {
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
width: screenWidth * 0.7
},
optionBar: {
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
width: screenWidth * 0.7
}
});

0 comments on commit 2586a41

Please sign in to comment.