Polygonal zone fix + zones redesing + cleaning

This commit is contained in:
Sebastien Riviere
2026-02-16 01:28:31 +01:00
parent 0768609ada
commit e0aaeb63f7
8 changed files with 278 additions and 121 deletions

View File

@@ -1,5 +1,5 @@
// React
import { useState, useEffect, Fragment } from 'react';
import { useState, useEffect, useMemo, Fragment } from 'react';
import { View, Text, Image, Alert, StyleSheet, TouchableOpacity } from 'react-native';
// Expo
import { useRouter } from 'expo-router';
@@ -15,18 +15,36 @@ import { useTimeDifference } from '../hook/useTimeDifference';
// Util
import { GameState } from '../util/gameState';
import { TimerMMSS } from '../components/timer';
import { secondsToMMSS } from '../util/format';
import { secondsToMMSS } from '../util/functions';
import { Colors } from '../util/colors';
const Interface = () => {
const router = useRouter();
const {messages, nextZoneDate, isShrinking, startLocationTracking, stopLocationTracking, gameState} = useTeamContext();
const {loggedIn, logout, loading} = useTeamConnexion();
const {name, ready, captured, locationSendDeadline, outOfZone, outOfZoneDeadline, hasHandicap, enemyHasHandicap} = useGame();
const {name, ready, captured, locationSendDeadline, sendCurrentPosition, outOfZone, outOfZoneDeadline, hasHandicap, enemyHasHandicap} = useGame();
const [timeLeftSendLocation] = useTimeDifference(locationSendDeadline, 1000);
const [timeLeftNextZone] = useTimeDifference(nextZoneDate, 1000);
const [timeLeftOutOfZone] = useTimeDifference(outOfZoneDeadline, 1000);
const [bottomContainerHeight, setBottomContainerHeight] = useState(0);
const statusMessage = useMemo(() => {
switch (gameState) {
case GameState.SETUP:
return messages?.waiting || "Préparation de la partie";
case GameState.PLACEMENT:
return "Phase de placement";
case GameState.PLAYING:
if (captured) return messages?.captured || "Vous avez été éliminé...";
if (!outOfZone) return "La partie est en cours";
if (!hasHandicap) return `Veuillez retourner dans la zone\nHandicap dans ${secondsToMMSS(-timeLeftOutOfZone)}`;
else return `Veuillez retourner dans la zone\nVotre position est révélée en continue`;
case GameState.FINISHED:
return `Vous avez ${captured ? (messages?.loser || "perdu...") : (messages?.winner || "gagné !")}`;
default:
return "Inconnue";
}
}, [gameState, messages, outOfZone, hasHandicap, timeLeftOutOfZone, captured]);
// Router
useEffect(() => {
@@ -61,45 +79,35 @@ const Interface = () => {
<Text style={{fontSize: 36, fontWeight: "bold", textAlign: "center"}}>{(name ?? "Indisponible")}</Text>
</View>
<View style={styles.logContainer}>
<TouchableOpacity style={{width:"100%"}}>
{ gameState == GameState.SETUP && <Text style={styles.gameState}>{messages?.waiting || "Préparation de la partie"}</Text>}
{ gameState == GameState.PLACEMENT && <Text style={styles.gameState}>Phase de placement</Text>}
{ gameState == GameState.PLAYING && !outOfZone && <Text style={styles.gameState}>La partie est en cours</Text>}
{ gameState == GameState.PLAYING && outOfZone && !hasHandicap && <Text style={styles.gameStateOutOfZone}>{`Veuillez retourner dans la zone\nHandicap dans ${secondsToMMSS(-timeLeftOutOfZone)}`}</Text>}
{ gameState == GameState.PLAYING && hasHandicap && <Text style={styles.gameStateOutOfZone}>{`Veuillez retourner dans la zone\nVotre position est révélée en continue`}</Text>}
{ gameState == GameState.FINISHED && <Text style={styles.gameState}>La partie est terminée</Text>}
<TouchableOpacity style={styles.gameState}>
<Text style={{fontSize: 18}}>{statusMessage}</Text>
</TouchableOpacity>
</View>
{ gameState == GameState.PLACEMENT &&
<View style={styles.timersContainer}>
<View style={styles.infoContainer}>
{ gameState == GameState.PLACEMENT &&
<View style={[styles.readyIndicator, {backgroundColor: ready ? "#3C3" : "#C33"}]}>
<Text style={{color: '#fff', fontSize: 16}}>{ready ? "Placé" : "Non placé"}</Text>
</View>
</View>
}
{ gameState == GameState.PLAYING && !captured && <Fragment>
<View style={styles.timersContainer}>
}
{ gameState == GameState.PLAYING && !captured && <Fragment>
<TimerMMSS style={{width: "50%"}} title={isShrinking ? "Réduction de la zone" : "Durée de la zone"} seconds={-timeLeftNextZone} />
<TimerMMSS style={{width: "50%"}} title={"Position envoyée dans"} seconds={!hasHandicap ? -timeLeftSendLocation: 0} />
</View>
{enemyHasHandicap &&
<Text style={{fontSize: 18, marginTop: 6, fontWeight: "bold"}}>Position ennemie révélée en continue !</Text>
}
</Fragment>}
{ gameState == GameState.PLAYING && captured &&
<View style={[styles.timersContainer, {height: 61}]}>
<Text style={{fontSize: 20}}>{messages?.captured || "Vous avez été éliminé..."}</Text>
</View>
}
{ gameState == GameState.FINISHED &&
<View style={[styles.timersContainer, {height: 61}]}>
{captured && <Text style={{fontSize: 20}}>{captured ? (messages?.loser || "Vous avez perdu...") : (messages?.winner || "Vous avez gagné !")}</Text>}
</View>
</Fragment>}
</View>
{ enemyHasHandicap &&
<Text style={{fontSize: 18, marginTop: 6, fontWeight: "bold"}}>Position ennemie révélée en continue !</Text>
}
</View>
<View style={styles.bottomContainer} onLayout={(event) => setBottomContainerHeight(event.nativeEvent.layout.height)}>
<CustomMap/>
<Drawer height={bottomContainerHeight}/>
{ gameState == GameState.PLAYING && !captured && !hasHandicap &&
<TouchableOpacity style={styles.updatePosition} onPress={sendCurrentPosition}>
<Image source={require("../assets/images/update_position.png")} style={{width: 40, height: 40}} resizeMode="contain"></Image>
</TouchableOpacity>
}
{ gameState == GameState.PLAYING && !captured &&
<Drawer height={bottomContainerHeight}/>
}
</View>
</View>
);
@@ -138,19 +146,9 @@ const styles = StyleSheet.create({
borderRadius: 10,
width: "100%",
backgroundColor: 'white',
fontSize: 18,
padding: 10,
},
gameStateOutOfZone: {
borderWidth: 2,
borderRadius: 10,
width: "100%",
backgroundColor: 'white',
fontSize: 18,
padding: 10,
borderColor: 'red'
},
timersContainer: {
infoContainer: {
width: '100%',
alignItems: 'center',
justifyContent: 'center',
@@ -168,5 +166,18 @@ const styles = StyleSheet.create({
},
bottomContainer: {
flex: 1,
}
},
updatePosition: {
position: 'absolute',
right: 30,
bottom: 80,
width: 60,
height: 60,
borderRadius: 30,
backgroundColor: 'white',
borderWidth: 4,
borderColor: 'black',
alignItems: 'center',
justifyContent: 'center',
},
});