forked from vergnet/application-amicale
Added game score save support
This commit is contained in:
parent
4f911ce32d
commit
b2ff90855f
8 changed files with 427 additions and 82 deletions
|
@ -366,9 +366,11 @@
|
||||||
"welcomeTitle": "Welcome !",
|
"welcomeTitle": "Welcome !",
|
||||||
"welcomeMessage": "Stuck on the toilet? The teacher is late?\nThis game is for you!\n\nTry to get the best score and beat your friends.",
|
"welcomeMessage": "Stuck on the toilet? The teacher is late?\nThis game is for you!\n\nTry to get the best score and beat your friends.",
|
||||||
"play": "Play!",
|
"play": "Play!",
|
||||||
"score": "Score : %{score}",
|
"score": "Score: %{score}",
|
||||||
"time": "Time :",
|
"highScore": "High score: %{score}",
|
||||||
"level": "Level :",
|
"newHighScore": "New High Score!",
|
||||||
|
"time": "Time:",
|
||||||
|
"level": "Level:",
|
||||||
"pause": "Game Paused",
|
"pause": "Game Paused",
|
||||||
"pauseMessage": "The game is paused",
|
"pauseMessage": "The game is paused",
|
||||||
"resume": "Resume",
|
"resume": "Resume",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"welcomeMessage": "Coincé sur les WC ? Le prof est pas là ?\nCe jeu est fait pour toi !\n\nEssaie d'avoir le meilleur score et de battre tes amis.",
|
"welcomeMessage": "Coincé sur les WC ? Le prof est pas là ?\nCe jeu est fait pour toi !\n\nEssaie d'avoir le meilleur score et de battre tes amis.",
|
||||||
"play": "Jouer !",
|
"play": "Jouer !",
|
||||||
"score": "Score : %{score}",
|
"score": "Score : %{score}",
|
||||||
|
"highScore": "Meilleur score : %{score}",
|
||||||
|
"newHighScore": "Meilleur score !",
|
||||||
"time": "Temps :",
|
"time": "Temps :",
|
||||||
"level": "Niveau :",
|
"level": "Niveau :",
|
||||||
"pause": "Pause",
|
"pause": "Pause",
|
||||||
|
|
|
@ -6,6 +6,7 @@ import Mascot from "./Mascot";
|
||||||
import * as Animatable from "react-native-animatable";
|
import * as Animatable from "react-native-animatable";
|
||||||
import {BackHandler, Dimensions, ScrollView, TouchableWithoutFeedback, View} from "react-native";
|
import {BackHandler, Dimensions, ScrollView, TouchableWithoutFeedback, View} from "react-native";
|
||||||
import type {CustomTheme} from "../../managers/ThemeManager";
|
import type {CustomTheme} from "../../managers/ThemeManager";
|
||||||
|
import SpeechArrow from "./SpeechArrow";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
visible: boolean,
|
visible: boolean,
|
||||||
|
@ -102,19 +103,11 @@ class MascotPopup extends React.Component<Props, State> {
|
||||||
animation={this.props.visible ? "bounceInLeft" : "bounceOutLeft"}
|
animation={this.props.visible ? "bounceInLeft" : "bounceOutLeft"}
|
||||||
duration={this.props.visible ? 1000 : 300}
|
duration={this.props.visible ? 1000 : 300}
|
||||||
>
|
>
|
||||||
<View style={{
|
<SpeechArrow
|
||||||
marginLeft: this.mascotSize / 3,
|
style={{marginLeft: this.mascotSize / 3}}
|
||||||
width: 0,
|
size={20}
|
||||||
height: 0,
|
color={this.props.theme.colors.mascotMessageArrow}
|
||||||
borderLeftWidth: 0,
|
/>
|
||||||
borderRightWidth: 20,
|
|
||||||
borderBottomWidth: 20,
|
|
||||||
borderStyle: 'solid',
|
|
||||||
backgroundColor: 'transparent',
|
|
||||||
borderLeftColor: 'transparent',
|
|
||||||
borderRightColor: 'transparent',
|
|
||||||
borderBottomColor: this.props.theme.colors.mascotMessageArrow,
|
|
||||||
}}/>
|
|
||||||
<Card style={{
|
<Card style={{
|
||||||
borderColor: this.props.theme.colors.mascotMessageArrow,
|
borderColor: this.props.theme.colors.mascotMessageArrow,
|
||||||
borderWidth: 4,
|
borderWidth: 4,
|
||||||
|
|
33
src/components/Mascot/SpeechArrow.js
Normal file
33
src/components/Mascot/SpeechArrow.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import {View} from "react-native";
|
||||||
|
import type {ViewStyle} from "react-native/Libraries/StyleSheet/StyleSheet";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
style?: ViewStyle,
|
||||||
|
size: number,
|
||||||
|
color: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class SpeechArrow extends React.Component<Props> {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<View style={this.props.style}>
|
||||||
|
<View style={{
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
borderLeftWidth: 0,
|
||||||
|
borderRightWidth: this.props.size,
|
||||||
|
borderBottomWidth: this.props.size,
|
||||||
|
borderStyle: 'solid',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
borderLeftColor: 'transparent',
|
||||||
|
borderRightColor: 'transparent',
|
||||||
|
borderBottomColor: this.props.color,
|
||||||
|
}}/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -136,6 +136,11 @@ export default class AsyncStorageManager {
|
||||||
]),
|
]),
|
||||||
current: '',
|
current: '',
|
||||||
},
|
},
|
||||||
|
gameScores: {
|
||||||
|
key: 'gameScores',
|
||||||
|
default: '[]',
|
||||||
|
current: '',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -56,6 +56,10 @@ export type CustomTheme = {
|
||||||
tetrisJ: string,
|
tetrisJ: string,
|
||||||
tetrisL: string,
|
tetrisL: string,
|
||||||
|
|
||||||
|
gameGold: string,
|
||||||
|
gameSilver: string,
|
||||||
|
gameBronze: string,
|
||||||
|
|
||||||
// Mascot Popup
|
// Mascot Popup
|
||||||
mascotMessageArrow: string,
|
mascotMessageArrow: string,
|
||||||
},
|
},
|
||||||
|
@ -129,6 +133,10 @@ export default class ThemeManager {
|
||||||
tetrisJ: '#2a67e3',
|
tetrisJ: '#2a67e3',
|
||||||
tetrisL: '#da742d',
|
tetrisL: '#da742d',
|
||||||
|
|
||||||
|
gameGold: "#ffd610",
|
||||||
|
gameSilver: "#7b7b7b",
|
||||||
|
gameBronze: "#a15218",
|
||||||
|
|
||||||
// Mascot Popup
|
// Mascot Popup
|
||||||
mascotMessageArrow: "#dedede",
|
mascotMessageArrow: "#dedede",
|
||||||
},
|
},
|
||||||
|
@ -191,6 +199,10 @@ export default class ThemeManager {
|
||||||
tetrisJ: '#0f37b9',
|
tetrisJ: '#0f37b9',
|
||||||
tetrisL: '#b96226',
|
tetrisL: '#b96226',
|
||||||
|
|
||||||
|
gameGold: "#ffd610",
|
||||||
|
gameSilver: "#7b7b7b",
|
||||||
|
gameBronze: "#a15218",
|
||||||
|
|
||||||
// Mascot Popup
|
// Mascot Popup
|
||||||
mascotMessageArrow: "#323232",
|
mascotMessageArrow: "#323232",
|
||||||
},
|
},
|
||||||
|
|
|
@ -17,6 +17,7 @@ import OptionsDialog from "../../../components/Dialogs/OptionsDialog";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
|
route: { params: { highScore: number }, ... },
|
||||||
theme: CustomTheme,
|
theme: CustomTheme,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ type State = {
|
||||||
class GameMainScreen extends React.Component<Props, State> {
|
class GameMainScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
logic: GameLogic;
|
logic: GameLogic;
|
||||||
|
highScore: number | null;
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -54,8 +56,8 @@ class GameMainScreen extends React.Component<Props, State> {
|
||||||
onDialogDismiss: () => {
|
onDialogDismiss: () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
this.props.navigation.addListener('blur', this.onScreenBlur);
|
if (this.props.route.params != null)
|
||||||
this.props.navigation.addListener('focus', this.onScreenFocus);
|
this.highScore = this.props.route.params.highScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -71,21 +73,6 @@ class GameMainScreen extends React.Component<Props, State> {
|
||||||
</MaterialHeaderButtons>;
|
</MaterialHeaderButtons>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove any interval on un-focus
|
|
||||||
*/
|
|
||||||
onScreenBlur = () => {
|
|
||||||
if (!this.logic.isGamePaused())
|
|
||||||
this.logic.togglePause();
|
|
||||||
}
|
|
||||||
|
|
||||||
onScreenFocus = () => {
|
|
||||||
if (!this.logic.isGameRunning())
|
|
||||||
this.startGame();
|
|
||||||
else if (this.logic.isGamePaused())
|
|
||||||
this.showPausePopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
getFormattedTime(seconds: number) {
|
getFormattedTime(seconds: number) {
|
||||||
let date = new Date();
|
let date = new Date();
|
||||||
date.setHours(0);
|
date.setHours(0);
|
||||||
|
@ -221,7 +208,14 @@ class GameMainScreen extends React.Component<Props, State> {
|
||||||
gameRunning: false,
|
gameRunning: false,
|
||||||
});
|
});
|
||||||
if (!isRestart)
|
if (!isRestart)
|
||||||
this.showGameOverConfirm();
|
this.props.navigation.replace(
|
||||||
|
"game-start",
|
||||||
|
{
|
||||||
|
score: this.state.gameScore,
|
||||||
|
level: this.state.gameLevel,
|
||||||
|
time: this.state.gameTime,
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getStatusIcons() {
|
getStatusIcons() {
|
||||||
|
@ -281,28 +275,56 @@ class GameMainScreen extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
getScoreIcon() {
|
getScoreIcon() {
|
||||||
|
let highScore = this.highScore == null || this.state.gameScore > this.highScore
|
||||||
|
? this.state.gameScore
|
||||||
|
: this.highScore;
|
||||||
return (
|
return (
|
||||||
<View style={{
|
<View style={{
|
||||||
flexDirection: "row",
|
|
||||||
marginLeft: "auto",
|
|
||||||
marginRight: "auto",
|
|
||||||
marginTop: 10,
|
marginTop: 10,
|
||||||
marginBottom: 10,
|
marginBottom: 10,
|
||||||
}}>
|
}}>
|
||||||
<Text style={{
|
<View style={{
|
||||||
marginLeft: 5,
|
flexDirection: "row",
|
||||||
fontSize: 22,
|
marginLeft: "auto",
|
||||||
}}>{i18n.t("screens.game.score", {score: this.state.gameScore})}</Text>
|
marginRight: "auto",
|
||||||
<MaterialCommunityIcons
|
}}>
|
||||||
name={'star'}
|
<Text style={{
|
||||||
color={this.props.theme.colors.tetrisScore}
|
marginLeft: 5,
|
||||||
size={20}
|
fontSize: 20,
|
||||||
style={{
|
}}>{i18n.t("screens.game.score", {score: this.state.gameScore})}</Text>
|
||||||
marginTop: "auto",
|
<MaterialCommunityIcons
|
||||||
marginBottom: "auto",
|
name={'star'}
|
||||||
marginLeft: 5
|
color={this.props.theme.colors.tetrisScore}
|
||||||
}}/>
|
size={20}
|
||||||
|
style={{
|
||||||
|
marginTop: "auto",
|
||||||
|
marginBottom: "auto",
|
||||||
|
marginLeft: 5
|
||||||
|
}}/>
|
||||||
|
</View>
|
||||||
|
<View style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
marginLeft: "auto",
|
||||||
|
marginRight: "auto",
|
||||||
|
marginTop: 5,
|
||||||
|
}}>
|
||||||
|
<Text style={{
|
||||||
|
marginLeft: 5,
|
||||||
|
fontSize: 10,
|
||||||
|
color: this.props.theme.colors.textDisabled
|
||||||
|
}}>{i18n.t("screens.game.highScore", {score: highScore})}</Text>
|
||||||
|
<MaterialCommunityIcons
|
||||||
|
name={'star'}
|
||||||
|
color={this.props.theme.colors.tetrisScore}
|
||||||
|
size={10}
|
||||||
|
style={{
|
||||||
|
marginTop: "auto",
|
||||||
|
marginBottom: "auto",
|
||||||
|
marginLeft: 5
|
||||||
|
}}/>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||||
import {Button, Card, Divider, Headline, Paragraph, withTheme} from "react-native-paper";
|
import {Button, Card, Divider, Headline, Paragraph, Text, withTheme} from "react-native-paper";
|
||||||
import {View} from "react-native";
|
import {ScrollView, View} from "react-native";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import Mascot, {MASCOT_STYLE} from "../../../components/Mascot/Mascot";
|
import Mascot, {MASCOT_STYLE} from "../../../components/Mascot/Mascot";
|
||||||
import MascotPopup from "../../../components/Mascot/MascotPopup";
|
import MascotPopup from "../../../components/Mascot/MascotPopup";
|
||||||
|
@ -14,9 +14,21 @@ import GridComponent from "../components/GridComponent";
|
||||||
import GridManager from "../logic/GridManager";
|
import GridManager from "../logic/GridManager";
|
||||||
import Piece from "../logic/Piece";
|
import Piece from "../logic/Piece";
|
||||||
import * as Animatable from "react-native-animatable";
|
import * as Animatable from "react-native-animatable";
|
||||||
|
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
|
||||||
|
import LinearGradient from "react-native-linear-gradient";
|
||||||
|
import SpeechArrow from "../../../components/Mascot/SpeechArrow";
|
||||||
|
|
||||||
|
type GameStats = {
|
||||||
|
score: number,
|
||||||
|
level: number,
|
||||||
|
time: number,
|
||||||
|
}
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
|
route: {
|
||||||
|
params: GameStats
|
||||||
|
},
|
||||||
theme: CustomTheme,
|
theme: CustomTheme,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +39,10 @@ type State = {
|
||||||
class GameStartScreen extends React.Component<Props, State> {
|
class GameStartScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
gridManager: GridManager;
|
gridManager: GridManager;
|
||||||
|
scores: Array<number>;
|
||||||
|
|
||||||
|
gameStats: GameStats | null;
|
||||||
|
isHighScore: boolean;
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
mascotDialogVisible: AsyncStorageManager.getInstance().preferences.gameStartShowBanner.current === "1",
|
mascotDialogVisible: AsyncStorageManager.getInstance().preferences.gameStartShowBanner.current === "1",
|
||||||
|
@ -35,6 +51,30 @@ class GameStartScreen extends React.Component<Props, State> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.gridManager = new GridManager(4, 4, props.theme);
|
this.gridManager = new GridManager(4, 4, props.theme);
|
||||||
|
this.scores = JSON.parse(AsyncStorageManager.getInstance().preferences.gameScores.current);
|
||||||
|
this.scores.sort((a, b) => b - a);
|
||||||
|
if (this.props.route.params != null)
|
||||||
|
this.recoverGameScore();
|
||||||
|
}
|
||||||
|
|
||||||
|
recoverGameScore() {
|
||||||
|
this.gameStats = this.props.route.params;
|
||||||
|
this.isHighScore = this.scores.length === 0 || this.gameStats.score > this.scores[0];
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
if (this.scores.length > i && this.gameStats.score > this.scores[i]) {
|
||||||
|
this.scores.splice(i, 0, this.gameStats.score);
|
||||||
|
break;
|
||||||
|
} else if (this.scores.length <= i) {
|
||||||
|
this.scores.push(this.gameStats.score);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.scores.length > 3)
|
||||||
|
this.scores.splice(3, 1);
|
||||||
|
AsyncStorageManager.getInstance().savePref(
|
||||||
|
AsyncStorageManager.getInstance().preferences.gameScores.key,
|
||||||
|
JSON.stringify(this.scores)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
hideMascotDialog = () => {
|
hideMascotDialog = () => {
|
||||||
|
@ -97,10 +137,110 @@ class GameStartScreen extends React.Component<Props, State> {
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPostGameContent(stats: GameStats) {
|
||||||
|
return (
|
||||||
|
<View style={{
|
||||||
|
flex: 1
|
||||||
|
}}>
|
||||||
|
<Mascot
|
||||||
|
emotion={this.isHighScore ? MASCOT_STYLE.LOVE : MASCOT_STYLE.NORMAL}
|
||||||
|
animated={this.isHighScore}
|
||||||
|
style={{
|
||||||
|
width: this.isHighScore ? "50%" : "30%",
|
||||||
|
marginLeft: this.isHighScore ? "auto" : null,
|
||||||
|
marginRight: this.isHighScore ? "auto" : null,
|
||||||
|
}}/>
|
||||||
|
<SpeechArrow
|
||||||
|
style={{marginLeft: this.isHighScore ? "60%" : "20%"}}
|
||||||
|
size={20}
|
||||||
|
color={this.props.theme.colors.mascotMessageArrow}
|
||||||
|
/>
|
||||||
|
<Card style={{
|
||||||
|
borderColor: this.props.theme.colors.mascotMessageArrow,
|
||||||
|
borderWidth: 2,
|
||||||
|
marginLeft: 20,
|
||||||
|
marginRight: 20,
|
||||||
|
}}>
|
||||||
|
<Card.Content>
|
||||||
|
<Headline
|
||||||
|
style={{
|
||||||
|
textAlign: "center",
|
||||||
|
color: this.isHighScore
|
||||||
|
? this.props.theme.colors.gameGold
|
||||||
|
: this.props.theme.colors.primary
|
||||||
|
}}>
|
||||||
|
{this.isHighScore
|
||||||
|
? i18n.t("screens.game.newHighScore")
|
||||||
|
: i18n.t("screens.game.gameOver.text")}
|
||||||
|
</Headline>
|
||||||
|
<Divider/>
|
||||||
|
<View style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
marginLeft: "auto",
|
||||||
|
marginRight: "auto",
|
||||||
|
marginTop: 10,
|
||||||
|
marginBottom: 10,
|
||||||
|
}}>
|
||||||
|
<Text style={{
|
||||||
|
fontSize: 20,
|
||||||
|
}}>
|
||||||
|
{i18n.t("screens.game.score", {score: stats.score})}
|
||||||
|
</Text>
|
||||||
|
<MaterialCommunityIcons
|
||||||
|
name={'star'}
|
||||||
|
color={this.props.theme.colors.tetrisScore}
|
||||||
|
size={30}
|
||||||
|
style={{
|
||||||
|
marginLeft: 5
|
||||||
|
}}/>
|
||||||
|
</View>
|
||||||
|
<View style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
marginLeft: "auto",
|
||||||
|
marginRight: "auto",
|
||||||
|
}}>
|
||||||
|
<Text>{i18n.t("screens.game.level")}</Text>
|
||||||
|
<MaterialCommunityIcons
|
||||||
|
style={{
|
||||||
|
marginRight: 5,
|
||||||
|
marginLeft: 5,
|
||||||
|
}}
|
||||||
|
name={"gamepad-square"}
|
||||||
|
size={20}
|
||||||
|
color={this.props.theme.colors.textDisabled}
|
||||||
|
/>
|
||||||
|
<Text>
|
||||||
|
{stats.level}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
marginLeft: "auto",
|
||||||
|
marginRight: "auto",
|
||||||
|
}}>
|
||||||
|
<Text>{i18n.t("screens.game.time")}</Text>
|
||||||
|
<MaterialCommunityIcons
|
||||||
|
style={{
|
||||||
|
marginRight: 5,
|
||||||
|
marginLeft: 5,
|
||||||
|
}}
|
||||||
|
name={"timer"}
|
||||||
|
size={20}
|
||||||
|
color={this.props.theme.colors.textDisabled}
|
||||||
|
/>
|
||||||
|
<Text>
|
||||||
|
{stats.time}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</Card.Content>
|
||||||
|
</Card>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
getWelcomeText() {
|
getWelcomeText() {
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
|
@ -109,7 +249,14 @@ class GameStartScreen extends React.Component<Props, State> {
|
||||||
marginLeft: "auto",
|
marginLeft: "auto",
|
||||||
marginRight: "auto",
|
marginRight: "auto",
|
||||||
}}/>
|
}}/>
|
||||||
|
<SpeechArrow
|
||||||
|
style={{marginLeft: "60%"}}
|
||||||
|
size={20}
|
||||||
|
color={this.props.theme.colors.mascotMessageArrow}
|
||||||
|
/>
|
||||||
<Card style={{
|
<Card style={{
|
||||||
|
borderColor: this.props.theme.colors.mascotMessageArrow,
|
||||||
|
borderWidth: 2,
|
||||||
marginLeft: 10,
|
marginLeft: 10,
|
||||||
marginRight: 10,
|
marginRight: 10,
|
||||||
}}>
|
}}>
|
||||||
|
@ -131,44 +278,173 @@ class GameStartScreen extends React.Component<Props, State> {
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPodiumRender(place: 1 | 2 | 3, score: string) {
|
||||||
|
let icon = "podium-gold";
|
||||||
|
let color = this.props.theme.colors.gameGold;
|
||||||
|
let fontSize = 20;
|
||||||
|
let size = 70;
|
||||||
|
if (place === 2) {
|
||||||
|
icon = "podium-silver";
|
||||||
|
color = this.props.theme.colors.gameSilver;
|
||||||
|
fontSize = 18;
|
||||||
|
size = 60;
|
||||||
|
} else if (place === 3) {
|
||||||
|
icon = "podium-bronze";
|
||||||
|
color = this.props.theme.colors.gameBronze;
|
||||||
|
fontSize = 15;
|
||||||
|
size = 50;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<View style={{
|
||||||
|
marginLeft: place === 2 ? 20 : "auto",
|
||||||
|
marginRight: place === 3 ? 20 : "auto",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "flex-end",
|
||||||
|
}}>
|
||||||
|
{
|
||||||
|
this.isHighScore && place === 1
|
||||||
|
?
|
||||||
|
<Animatable.View
|
||||||
|
animation={"swing"}
|
||||||
|
iterationCount={"infinite"}
|
||||||
|
duration={2000}
|
||||||
|
delay={1000}
|
||||||
|
useNativeDriver={true}
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: -20
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Animatable.View
|
||||||
|
animation={"pulse"}
|
||||||
|
iterationCount={"infinite"}
|
||||||
|
useNativeDriver={true}
|
||||||
|
>
|
||||||
|
<MaterialCommunityIcons
|
||||||
|
name={"decagram"}
|
||||||
|
color={this.props.theme.colors.gameGold}
|
||||||
|
size={150}
|
||||||
|
/>
|
||||||
|
</Animatable.View>
|
||||||
|
</Animatable.View>
|
||||||
|
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
<MaterialCommunityIcons
|
||||||
|
name={icon}
|
||||||
|
color={this.isHighScore && place === 1 ? "#fff" : color}
|
||||||
|
size={size}
|
||||||
|
/>
|
||||||
|
<Text style={{
|
||||||
|
textAlign: "center",
|
||||||
|
fontWeight: place === 1 ? "bold" : null,
|
||||||
|
fontSize: fontSize,
|
||||||
|
}}>{score}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTopScoresRender() {
|
||||||
|
const gold = this.scores.length > 0
|
||||||
|
? this.scores[0]
|
||||||
|
: "-";
|
||||||
|
const silver = this.scores.length > 1
|
||||||
|
? this.scores[1]
|
||||||
|
: "-";
|
||||||
|
const bronze = this.scores.length > 2
|
||||||
|
? this.scores[2]
|
||||||
|
: "-";
|
||||||
|
return (
|
||||||
|
<View style={{
|
||||||
|
marginBottom: 20,
|
||||||
|
marginTop: 20
|
||||||
|
}}>
|
||||||
|
{this.getPodiumRender(1, gold.toString())}
|
||||||
|
<View style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
marginLeft: "auto",
|
||||||
|
marginRight: "auto",
|
||||||
|
}}>
|
||||||
|
{this.getPodiumRender(3, bronze.toString())}
|
||||||
|
{this.getPodiumRender(2, silver.toString())}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getMainContent() {
|
||||||
|
return (
|
||||||
|
<LinearGradient
|
||||||
|
style={{flex: 1}}
|
||||||
|
colors={[
|
||||||
|
this.props.theme.colors.background + "00",
|
||||||
|
this.props.theme.colors.background
|
||||||
|
]}
|
||||||
|
start={{x: 0, y: 0.1}}
|
||||||
|
end={{x: 0.1, y: 1}}
|
||||||
|
>
|
||||||
|
<View style={{flex: 1}}>
|
||||||
|
{
|
||||||
|
this.gameStats != null
|
||||||
|
? this.getPostGameContent(this.gameStats)
|
||||||
|
: this.getWelcomeText()
|
||||||
|
}
|
||||||
|
<Button
|
||||||
|
icon={"play"}
|
||||||
|
mode={"contained"}
|
||||||
|
onPress={() => this.props.navigation.replace(
|
||||||
|
"game-main",
|
||||||
|
{
|
||||||
|
highScore: this.scores.length > 0
|
||||||
|
? this.scores[0]
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
style={{
|
||||||
|
marginLeft: "auto",
|
||||||
|
marginRight: "auto",
|
||||||
|
marginTop: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{i18n.t("screens.game.play")}
|
||||||
|
</Button>
|
||||||
|
{this.getTopScoresRender()}
|
||||||
|
</View>
|
||||||
|
</LinearGradient>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
keyExtractor = (item: number) => item.toString();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={{flex: 1}}>
|
<View style={{flex: 1}}>
|
||||||
{this.getPiecesBackground()}
|
{this.getPiecesBackground()}
|
||||||
{this.getWelcomeText()}
|
<ScrollView>
|
||||||
<Button
|
{this.getMainContent()}
|
||||||
icon={"play"}
|
<MascotPopup
|
||||||
mode={"contained"}
|
visible={this.state.mascotDialogVisible}
|
||||||
onPress={() => this.props.navigation.navigate("game-main")}
|
title={i18n.t("screens.game.mascotDialog.title")}
|
||||||
style={{
|
message={i18n.t("screens.game.mascotDialog.message")}
|
||||||
marginLeft: "auto",
|
icon={"gamepad-variant"}
|
||||||
marginRight: "auto",
|
buttons={{
|
||||||
marginTop: 10,
|
action: null,
|
||||||
}}
|
cancel: {
|
||||||
>
|
message: i18n.t("screens.game.mascotDialog.button"),
|
||||||
{i18n.t("screens.game.play")}
|
icon: "check",
|
||||||
</Button>
|
onPress: this.hideMascotDialog,
|
||||||
<MascotPopup
|
}
|
||||||
visible={this.state.mascotDialogVisible}
|
}}
|
||||||
title={i18n.t("screens.game.mascotDialog.title")}
|
emotion={MASCOT_STYLE.COOL}
|
||||||
message={i18n.t("screens.game.mascotDialog.message")}
|
/>
|
||||||
icon={"gamepad-variant"}
|
</ScrollView>
|
||||||
buttons={{
|
|
||||||
action: null,
|
|
||||||
cancel: {
|
|
||||||
message: i18n.t("screens.game.mascotDialog.button"),
|
|
||||||
icon: "check",
|
|
||||||
onPress: this.hideMascotDialog,
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
emotion={MASCOT_STYLE.COOL}
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue