forked from vergnet/application-amicale
Improved game UI
This commit is contained in:
parent
fdf0fffabc
commit
4bff6e15a8
7 changed files with 179 additions and 123 deletions
|
@ -363,6 +363,9 @@
|
|||
},
|
||||
"game": {
|
||||
"title": "Game",
|
||||
"score": "Score : %{score}",
|
||||
"time": "Time :",
|
||||
"level": "Level :",
|
||||
"pause": "Game Paused",
|
||||
"pauseMessage": "The game is paused",
|
||||
"resume": "Resume",
|
||||
|
|
|
@ -361,16 +361,19 @@
|
|||
"homeButtonSubtitle": "Contacte le développeur de l'appli"
|
||||
},
|
||||
"game": {
|
||||
"title": "Le jeu trop ouf",
|
||||
"title": "Le Jeu trop ouf",
|
||||
"score": "Score : %{score}",
|
||||
"time": "Temps :",
|
||||
"level": "Niveau :",
|
||||
"pause": "Pause",
|
||||
"pauseMessage": "Le jeu est en pause",
|
||||
"pauseMessage": "T'as fait pause, t'es nul",
|
||||
"resume": "Continuer",
|
||||
"restart": {
|
||||
"text": "Redémarrer",
|
||||
"confirm": "Est-tu sûr de vouloir redémarrer ?",
|
||||
"confirm": "T'es sûr de vouloir redémarrer ?",
|
||||
"confirmMessage": "Tout ton progrès sera perdu, continuer ?",
|
||||
"confirmYes": "Oui",
|
||||
"confirmNo": "Non"
|
||||
"confirmNo": "Oula non"
|
||||
},
|
||||
"gameOver": {
|
||||
"text": "Game Over",
|
||||
|
|
|
@ -119,8 +119,7 @@ export default class ThemeManager {
|
|||
tutorinsaColor: '#f93943',
|
||||
|
||||
// Tetris
|
||||
tetrisBackground: '#e6e6e6',
|
||||
tetrisBorder: '#2f2f2f',
|
||||
tetrisBackground: '#f0f0f0',
|
||||
tetrisScore: '#e2bd33',
|
||||
tetrisI: '#3cd9e6',
|
||||
tetrisO: '#ffdd00',
|
||||
|
@ -182,8 +181,7 @@ export default class ThemeManager {
|
|||
tutorinsaColor: '#f93943',
|
||||
|
||||
// Tetris
|
||||
tetrisBackground: '#2c2c2c',
|
||||
tetrisBorder: '#1b1b1b',
|
||||
tetrisBackground: '#181818',
|
||||
tetrisScore: '#e2d707',
|
||||
tetrisI: '#30b3be',
|
||||
tetrisO: '#c1a700',
|
||||
|
|
|
@ -21,9 +21,8 @@ class CellComponent extends React.PureComponent<Props> {
|
|||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: item.isEmpty ? 'transparent' : item.color,
|
||||
borderColor: item.isEmpty ? 'transparent' : this.props.theme.colors.tetrisBorder,
|
||||
borderStyle: 'solid',
|
||||
borderRadius: 2,
|
||||
borderColor: 'transparent',
|
||||
borderRadius: 4,
|
||||
borderWidth: 1,
|
||||
aspectRatio: 1,
|
||||
}}
|
||||
|
|
|
@ -5,16 +5,15 @@ import {View} from 'react-native';
|
|||
import {withTheme} from 'react-native-paper';
|
||||
import type {Cell} from "./CellComponent";
|
||||
import CellComponent from "./CellComponent";
|
||||
import type {ViewStyle} from "react-native/Libraries/StyleSheet/StyleSheet";
|
||||
|
||||
export type Grid = Array<Array<CellComponent>>;
|
||||
|
||||
type Props = {
|
||||
grid: Array<Array<Object>>,
|
||||
backgroundColor: string,
|
||||
height: number,
|
||||
width: number,
|
||||
containerMaxHeight: number | string,
|
||||
containerMaxWidth: number | string,
|
||||
style: ViewStyle,
|
||||
}
|
||||
|
||||
class GridComponent extends React.Component<Props> {
|
||||
|
@ -23,10 +22,7 @@ class GridComponent extends React.Component<Props> {
|
|||
let cells = this.props.grid[rowNumber].map(this.getCellRender);
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
backgroundColor: this.props.backgroundColor,
|
||||
}}
|
||||
style={{flexDirection: 'row',}}
|
||||
key={rowNumber.toString()}
|
||||
>
|
||||
{cells}
|
||||
|
@ -49,12 +45,8 @@ class GridComponent extends React.Component<Props> {
|
|||
render() {
|
||||
return (
|
||||
<View style={{
|
||||
flexDirection: 'column',
|
||||
maxWidth: this.props.containerMaxWidth,
|
||||
maxHeight: this.props.containerMaxHeight,
|
||||
aspectRatio: this.props.width / this.props.height,
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
...this.props.style
|
||||
}}>
|
||||
{this.getGrid()}
|
||||
</View>
|
||||
|
|
|
@ -5,9 +5,11 @@ import {View} from 'react-native';
|
|||
import {withTheme} from 'react-native-paper';
|
||||
import type {Grid} from "./GridComponent";
|
||||
import GridComponent from "./GridComponent";
|
||||
import type {ViewStyle} from "react-native/Libraries/StyleSheet/StyleSheet";
|
||||
|
||||
type Props = {
|
||||
items: Array<Grid>,
|
||||
style: ViewStyle
|
||||
}
|
||||
|
||||
class Preview extends React.PureComponent<Props> {
|
||||
|
@ -25,9 +27,10 @@ class Preview extends React.PureComponent<Props> {
|
|||
width={item[0].length}
|
||||
height={item.length}
|
||||
grid={item}
|
||||
containerMaxHeight={50}
|
||||
containerMaxWidth={50}
|
||||
backgroundColor={'transparent'}
|
||||
style={{
|
||||
marginRight: 5,
|
||||
marginLeft: 5,
|
||||
}}
|
||||
key={index.toString()}
|
||||
/>;
|
||||
};
|
||||
|
@ -35,7 +38,7 @@ class Preview extends React.PureComponent<Props> {
|
|||
render() {
|
||||
if (this.props.items.length > 0) {
|
||||
return (
|
||||
<View>
|
||||
<View style={this.props.style}>
|
||||
{this.getGrids()}
|
||||
</View>
|
||||
);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import * as React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {IconButton, Text, withTheme} from 'react-native-paper';
|
||||
import {Caption, IconButton, Text, withTheme} from 'react-native-paper';
|
||||
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
|
||||
import GameLogic from "../logic/GameLogic";
|
||||
import type {Grid} from "../components/GridComponent";
|
||||
|
@ -51,7 +51,8 @@ class GameMainScreen extends React.Component<Props, State> {
|
|||
dialogTitle: "",
|
||||
dialogMessage: "",
|
||||
dialogButtons: [],
|
||||
onDialogDismiss: () => {},
|
||||
onDialogDismiss: () => {
|
||||
},
|
||||
};
|
||||
this.props.navigation.addListener('blur', this.onScreenBlur);
|
||||
this.props.navigation.addListener('focus', this.onScreenFocus);
|
||||
|
@ -146,11 +147,11 @@ class GameMainScreen extends React.Component<Props, State> {
|
|||
dialogMessage: i18n.t("screens.game.pauseMessage"),
|
||||
dialogButtons: [
|
||||
{
|
||||
title: i18n.t("screens.game.restart.text"),
|
||||
title: i18n.t("screens.game.restart.text"),
|
||||
onPress: this.showRestartConfirm
|
||||
},
|
||||
{
|
||||
title: i18n.t("screens.game.resume"),
|
||||
title: i18n.t("screens.game.resume"),
|
||||
onPress: onDismiss
|
||||
}
|
||||
],
|
||||
|
@ -165,14 +166,14 @@ class GameMainScreen extends React.Component<Props, State> {
|
|||
dialogMessage: i18n.t("screens.game.restart.confirmMessage"),
|
||||
dialogButtons: [
|
||||
{
|
||||
title: i18n.t("screens.game.restart.confirmYes"),
|
||||
title: i18n.t("screens.game.restart.confirmYes"),
|
||||
onPress: () => {
|
||||
this.onDialogDismiss();
|
||||
this.startGame();
|
||||
}
|
||||
},
|
||||
{
|
||||
title: i18n.t("screens.game.restart.confirmNo"),
|
||||
title: i18n.t("screens.game.restart.confirmNo"),
|
||||
onPress: this.showPausePopup
|
||||
}
|
||||
],
|
||||
|
@ -194,11 +195,11 @@ class GameMainScreen extends React.Component<Props, State> {
|
|||
dialogMessage: message,
|
||||
dialogButtons: [
|
||||
{
|
||||
title: i18n.t("screens.game.gameOver.exit"),
|
||||
title: i18n.t("screens.game.gameOver.exit"),
|
||||
onPress: () => this.props.navigation.goBack()
|
||||
},
|
||||
{
|
||||
title: i18n.t("screens.game.resume"),
|
||||
title: i18n.t("screens.game.resume"),
|
||||
onPress: onDismiss
|
||||
}
|
||||
],
|
||||
|
@ -223,111 +224,168 @@ class GameMainScreen extends React.Component<Props, State> {
|
|||
this.showGameOverConfirm();
|
||||
}
|
||||
|
||||
render() {
|
||||
const colors = this.props.theme.colors;
|
||||
getStatusIcons() {
|
||||
return (
|
||||
<View style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
flex: 1,
|
||||
marginTop: "auto",
|
||||
marginBottom: "auto"
|
||||
}}>
|
||||
<View style={{
|
||||
flexDirection: 'row',
|
||||
position: 'absolute',
|
||||
top: 5,
|
||||
left: 10,
|
||||
}}>
|
||||
<MaterialCommunityIcons
|
||||
name={'timer'}
|
||||
color={colors.subtitle}
|
||||
size={20}/>
|
||||
<Text style={{
|
||||
marginLeft: 5,
|
||||
color: colors.subtitle
|
||||
}}>{this.getFormattedTime(this.state.gameTime)}</Text>
|
||||
</View>
|
||||
<View style={{
|
||||
flexDirection: 'row',
|
||||
position: 'absolute',
|
||||
top: 50,
|
||||
left: 10,
|
||||
}}>
|
||||
<MaterialCommunityIcons
|
||||
name={'gamepad'}
|
||||
color={colors.text}
|
||||
size={20}/>
|
||||
<Text style={{
|
||||
marginLeft: 5
|
||||
}}>{this.state.gameLevel}</Text>
|
||||
</View>
|
||||
<View style={{
|
||||
flexDirection: 'row',
|
||||
marginRight: 'auto',
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
}}>
|
||||
<MaterialCommunityIcons
|
||||
name={'star'}
|
||||
color={colors.tetrisScore}
|
||||
size={30}/>
|
||||
<Text style={{
|
||||
marginLeft: 5,
|
||||
fontSize: 22,
|
||||
}}>{this.state.gameScore}</Text>
|
||||
<Caption style={{
|
||||
marginLeft: "auto",
|
||||
marginRight: "auto",
|
||||
marginBottom: 5,
|
||||
}}>{i18n.t("screens.game.time")}</Caption>
|
||||
<View style={{
|
||||
flexDirection: "row"
|
||||
}}>
|
||||
<MaterialCommunityIcons
|
||||
name={'timer'}
|
||||
color={this.props.theme.colors.subtitle}
|
||||
size={20}/>
|
||||
<Text style={{
|
||||
marginLeft: 5,
|
||||
color: this.props.theme.colors.subtitle
|
||||
}}>{this.getFormattedTime(this.state.gameTime)}</Text>
|
||||
</View>
|
||||
|
||||
</View>
|
||||
<GridComponent
|
||||
width={this.logic.getWidth()}
|
||||
height={this.logic.getHeight()}
|
||||
containerMaxHeight={'80%'}
|
||||
containerMaxWidth={'60%'}
|
||||
grid={this.state.grid}
|
||||
backgroundColor={colors.tetrisBackground}
|
||||
<View style={{
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
marginTop: 20,
|
||||
}}>
|
||||
<Caption style={{
|
||||
marginLeft: "auto",
|
||||
marginRight: "auto",
|
||||
marginBottom: 5,
|
||||
}}>{i18n.t("screens.game.level")}</Caption>
|
||||
<View style={{
|
||||
flexDirection: "row"
|
||||
}}>
|
||||
<MaterialCommunityIcons
|
||||
name={'gamepad-square'}
|
||||
color={this.props.theme.colors.text}
|
||||
size={20}/>
|
||||
<Text style={{
|
||||
marginLeft: 5
|
||||
}}>{this.state.gameLevel}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
getScoreIcon() {
|
||||
return (
|
||||
<View style={{
|
||||
flexDirection: "row",
|
||||
marginLeft: "auto",
|
||||
marginRight: "auto",
|
||||
marginTop: 10,
|
||||
marginBottom: 10,
|
||||
}}>
|
||||
<Text style={{
|
||||
marginLeft: 5,
|
||||
fontSize: 22,
|
||||
}}>{i18n.t("screens.game.score", {score: this.state.gameScore})}</Text>
|
||||
<MaterialCommunityIcons
|
||||
name={'star'}
|
||||
color={this.props.theme.colors.tetrisScore}
|
||||
size={20}
|
||||
style={{
|
||||
marginTop: "auto",
|
||||
marginBottom: "auto",
|
||||
marginLeft: 5
|
||||
}}/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
getControlButtons() {
|
||||
return (
|
||||
<View style={{
|
||||
height: 80,
|
||||
flexDirection: "row"
|
||||
}}>
|
||||
<IconButton
|
||||
icon="rotate-right-variant"
|
||||
size={40}
|
||||
onPress={() => this.logic.rotatePressed(this.updateGrid)}
|
||||
style={{flex: 1}}
|
||||
/>
|
||||
<View style={{
|
||||
position: 'absolute',
|
||||
top: 50,
|
||||
right: 5,
|
||||
}}>
|
||||
<Preview
|
||||
items={this.logic.getNextPiecesPreviews()}
|
||||
/>
|
||||
</View>
|
||||
<View style={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
flex: 4
|
||||
}}>
|
||||
<IconButton
|
||||
icon="rotate-right-variant"
|
||||
icon="chevron-left"
|
||||
size={40}
|
||||
onPress={() => this.logic.rotatePressed(this.updateGrid)}
|
||||
style={{marginRight: 'auto'}}
|
||||
/>
|
||||
<View style={{
|
||||
flexDirection: 'row',
|
||||
}}>
|
||||
<IconButton
|
||||
icon="arrow-left"
|
||||
size={40}
|
||||
onPress={() => this.logic.pressedOut()}
|
||||
onPressIn={() => this.logic.leftPressedIn(this.updateGrid)}
|
||||
style={{flex: 1}}
|
||||
onPress={() => this.logic.pressedOut()}
|
||||
onPressIn={() => this.logic.leftPressedIn(this.updateGrid)}
|
||||
|
||||
/>
|
||||
<IconButton
|
||||
icon="arrow-right"
|
||||
size={40}
|
||||
onPress={() => this.logic.pressedOut()}
|
||||
onPressIn={() => this.logic.rightPressed(this.updateGrid)}
|
||||
/>
|
||||
<IconButton
|
||||
icon="chevron-right"
|
||||
size={40}
|
||||
style={{flex: 1}}
|
||||
onPress={() => this.logic.pressedOut()}
|
||||
onPressIn={() => this.logic.rightPressed(this.updateGrid)}
|
||||
/>
|
||||
</View>
|
||||
<IconButton
|
||||
icon="arrow-down-bold"
|
||||
size={40}
|
||||
onPressIn={() => this.logic.downPressedIn(this.updateGridScore)}
|
||||
onPress={() => this.logic.pressedOut()}
|
||||
style={{flex: 1}}
|
||||
color={this.props.theme.colors.tetrisScore}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<View style={{
|
||||
flex: 1,
|
||||
flexDirection: "row",
|
||||
}}>
|
||||
{this.getStatusIcons()}
|
||||
<View style={{flex: 4}}>
|
||||
{this.getScoreIcon()}
|
||||
<GridComponent
|
||||
width={this.logic.getWidth()}
|
||||
height={this.logic.getHeight()}
|
||||
grid={this.state.grid}
|
||||
style={{
|
||||
backgroundColor: this.props.theme.colors.tetrisBackground,
|
||||
flex: 1,
|
||||
marginLeft: "auto",
|
||||
marginRight: "auto",
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={{flex: 1}}>
|
||||
<Preview
|
||||
items={this.logic.getNextPiecesPreviews()}
|
||||
style={{
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
marginTop: 10,
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<IconButton
|
||||
icon="arrow-down"
|
||||
size={40}
|
||||
onPressIn={() => this.logic.downPressedIn(this.updateGridScore)}
|
||||
onPress={() => this.logic.pressedOut()}
|
||||
style={{marginLeft: 'auto'}}
|
||||
color={colors.tetrisScore}
|
||||
/>
|
||||
</View>
|
||||
{this.getControlButtons()}
|
||||
|
||||
<OptionsDialog
|
||||
visible={this.state.dialogVisible}
|
||||
title={this.state.dialogTitle}
|
||||
|
|
Loading…
Reference in a new issue