// @flow import * as React from 'react'; import {Alert, View} from 'react-native'; import {IconButton, Text, withTheme} from 'react-native-paper'; import {MaterialCommunityIcons} from "@expo/vector-icons"; import GameLogic from "./GameLogic"; import Grid from "./components/Grid"; import HeaderButton from "../../components/HeaderButton"; import Preview from "./components/Preview"; type Props = { navigation: Object, } type State = { grid: Array>, gameRunning: boolean, gameTime: number, gameScore: number, gameLevel: number, } class TetrisScreen extends React.Component { colors: Object; logic: GameLogic; onTick: Function; onClock: Function; onGameEnd: Function; updateGrid: Function; updateGridScore: Function; constructor(props) { super(props); this.colors = props.theme.colors; this.logic = new GameLogic(20, 10, this.colors); this.state = { grid: this.logic.getEmptyGrid(this.logic.getHeight(), this.logic.getWidth()), gameRunning: false, gameTime: 0, gameScore: 0, gameLevel: 0, }; this.onTick = this.onTick.bind(this); this.onClock = this.onClock.bind(this); this.onGameEnd = this.onGameEnd.bind(this); this.updateGrid = this.updateGrid.bind(this); this.updateGridScore = this.updateGridScore.bind(this); this.props.navigation.addListener('blur', this.onScreenBlur.bind(this)); this.props.navigation.addListener('focus', this.onScreenFocus.bind(this)); } componentDidMount() { const rightButton = this.getRightButton.bind(this); this.props.navigation.setOptions({ headerRight: rightButton, }); this.startGame(); } getRightButton() { return ( this.togglePause()}/> ); } /** * 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) { let date = new Date(); date.setHours(0); date.setMinutes(0); date.setSeconds(seconds); let format; if (date.getHours()) format = date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds(); else if (date.getMinutes()) format = date.getMinutes() + ':' + date.getSeconds(); else format = date.getSeconds(); return format; } onTick(score: number, level: number, newGrid: Array>) { this.setState({ gameScore: score, gameLevel: level, grid: newGrid, }); } onClock(time: number) { this.setState({ gameTime: time, }); } updateGrid(newGrid: Array>) { this.setState({ grid: newGrid, }); } updateGridScore(newGrid: Array>, score: number) { this.setState({ grid: newGrid, gameScore: score, }); } togglePause() { this.logic.togglePause(); if (this.logic.isGamePaused()) this.showPausePopup(); } showPausePopup() { Alert.alert( 'PAUSE', 'GAME PAUSED', [ {text: 'RESTART', onPress: () => this.showRestartConfirm()}, {text: 'RESUME', onPress: () => this.togglePause()}, ], {cancelable: false}, ); } showRestartConfirm() { Alert.alert( 'RESTART?', 'WHOA THERE', [ {text: 'NO', onPress: () => this.showPausePopup()}, {text: 'YES', onPress: () => this.startGame()}, ], {cancelable: false}, ); } showGameOverConfirm() { let message = 'SCORE: ' + this.state.gameScore + '\n'; message += 'LEVEL: ' + this.state.gameLevel + '\n'; message += 'TIME: ' + this.getFormattedTime(this.state.gameTime) + '\n'; Alert.alert( 'GAME OVER', message, [ {text: 'LEAVE', onPress: () => this.props.navigation.goBack()}, {text: 'RESTART', onPress: () => this.startGame()}, ], {cancelable: false}, ); } startGame() { this.logic.startGame(this.onTick, this.onClock, this.onGameEnd); this.setState({ gameRunning: true, }); } onGameEnd(time: number, score: number, isRestart: boolean) { this.setState({ gameTime: time, gameScore: score, gameRunning: false, }); if (!isRestart) this.showGameOverConfirm(); } render() { return ( {this.getFormattedTime(this.state.gameTime)} {this.state.gameLevel} {this.state.gameScore} this.logic.rotatePressed(this.updateGrid)} style={{marginRight: 'auto'}} /> this.logic.pressedOut()} onPressIn={() => this.logic.leftPressedIn(this.updateGrid)} /> this.logic.pressedOut()} onPressIn={() => this.logic.rightPressed(this.updateGrid)} /> this.logic.downPressedIn(this.updateGridScore)} onPress={() => this.logic.pressedOut()} style={{marginLeft: 'auto'}} color={this.colors.tetrisScore} /> ); } } export default withTheme(TetrisScreen);