From c9029b8fb505887f9ffdee5c2905e8360fc5747b Mon Sep 17 00:00:00 2001 From: chahinebrini Date: Sat, 9 May 2026 15:46:17 +0200 Subject: [PATCH] fix(games): Tetris controls centered + Snake icon visibility + digital score-dashboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User-Wünsche: 1. Tetris bedien-buttons mittig zum Spielfeld (war off-center) 2. Snake geklickte button-icons NICHT weiß (sonst light-theme unsichtbar) 3. Beide games: digital score-counter über playfield Tetris: - Controls in alignItems:'center'-wrapper mit width:boardWidth child + justifyContent:'space-between' → Move-Pad+Action-Pad bündig zum Feld unabhängig von screen-width - Old Score/Level/Lines header entfernt → DigitalScore übernimmt Snake: - DPadBtn: ALWAYS color={tint} (#007aff iOS-blue) für Ionicons - Active-state via borderColor + scale(1.04), NICHT mehr durch white-icon - Semi-transparent blue bg (rgba) sichtbar in beiden themes - Android-Branches + elevation entfernt (überall einheitlich) DigitalScore (neu): - 7-segment-feel via Courier New monospace + letterSpacing 2 + tabular-nums - padStart(5,'0') Score+Best, padStart(2,'0') Level/Length - Dunkles Panel (#0d1117) + border #1f2937, intentional contrast - width:boardWidth, alignSelf:center - Snake: SCORE+BEST | Tetris: SCORE+BEST+LVL TS clean. Frontend-only, Metro reload reicht. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../components/urge/UrgeGames.tsx | 156 ++++++++++++------ 1 file changed, 107 insertions(+), 49 deletions(-) diff --git a/apps/rebreak-native/components/urge/UrgeGames.tsx b/apps/rebreak-native/components/urge/UrgeGames.tsx index 1deaf6e..e3f6a51 100644 --- a/apps/rebreak-native/components/urge/UrgeGames.tsx +++ b/apps/rebreak-native/components/urge/UrgeGames.tsx @@ -9,6 +9,7 @@ import * as Haptics from 'expo-haptics'; import Slider from '@react-native-community/slider'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { memorySvg, snakeSvg, tetrisSvg, tictactoeSvg } from './gameSvgs'; +import { useColors } from '../../lib/theme'; // Haptic helper — fire-and-forget, swallow errors on platforms without taptic engine function tapHaptic() { @@ -282,23 +283,16 @@ export function SnakeGame({ return ( {/* Header */} - + {lyraMessage} - - - Score - {score} - - - Best - {highScore} - - - - - + + + + {/* Digital score dashboard */} + + {/* Board */} @@ -352,8 +346,6 @@ export function SnakeGame({ ); } -// Platform-native D-Pad button: iOS uses system-blue tinted circle (SF-symbol look), -// Android uses Material elevated surface with ripple. function DPadBtn({ dir, active, onPress }: { dir: Dir; active: boolean; onPress: () => void }) { const icons: Record = { up: 'chevron-up', down: 'chevron-down', left: 'chevron-back', right: 'chevron-forward', @@ -366,29 +358,24 @@ function DPadBtn({ dir, active, onPress }: { dir: Dir; active: boolean; onPress: hitSlop={12} android_ripple={{ color: 'rgba(0,122,255,0.22)', borderless: true, radius: 32 }} style={({ pressed }) => { - const bgIdle = isIOS ? 'rgba(0,122,255,0.10)' : '#ffffff'; - const bgPressed = isIOS ? 'rgba(0,122,255,0.22)' : '#f5f5f5'; - const bgActive = tint; - const bg = active ? bgActive : (pressed && isIOS ? bgPressed : bgIdle); + const bgIdle = 'rgba(0,122,255,0.10)'; + const bgPressed = 'rgba(0,122,255,0.22)'; + const bgActive = 'rgba(0,122,255,0.22)'; + const bg = active ? bgActive : pressed ? bgPressed : bgIdle; return { width: 60, height: 60, borderRadius: 30, backgroundColor: bg, + borderWidth: 1.5, + borderColor: active ? tint : 'rgba(0,122,255,0.30)', alignItems: 'center', justifyContent: 'center', - ...(isIOS ? {} : { - elevation: active ? 4 : 2, - shadowColor: '#000', - shadowOffset: { width: 0, height: 1 }, - shadowOpacity: 0.15, - shadowRadius: 2, - }), - transform: [{ scale: pressed && isIOS ? 0.96 : 1 }], + transform: [{ scale: pressed ? 0.96 : active ? 1.04 : 1 }], }; }} > ); @@ -966,20 +953,19 @@ export function TetrisGame({ const speedColors = ['#22c55e', '#84cc16', '#eab308', '#f97316', '#ef4444']; + const boardWidth = TETRIS_COLS * CELL; + return ( {/* Header */} - + {lyraMessage} - - - {highScore > 0 && } - - - - + + {/* Digital score dashboard */} + + {/* Board */} @@ -1037,17 +1023,24 @@ export function TetrisGame({ /> - {/* Controls — Move Pad (links) + Action Pad (rechts) */} - - {/* Move Pad */} - - - - - {/* Action Pad */} - - - + {/* Controls — aligned to board width, centered on screen */} + + + {/* Move Pad */} + + + + + {/* Action Pad */} + + + + @@ -1062,10 +1055,75 @@ export function TetrisGame({ } function Stat({ label, value, color }: { label: string; value: number; color: string }) { + const colors = useColors(); return ( - {label} + {label} {value} ); } + +function DigitalScore({ + score, + best, + extra, + extraLabel, + boardWidth, +}: { + score: number; + best: number; + extra?: number; + extraLabel?: string; + boardWidth: number; +}) { + const fmt = (n: number, digits = 5) => String(n).padStart(digits, '0'); + return ( + + + + + {extra !== undefined && extraLabel !== undefined && ( + <> + + + + )} + + ); +} + +function ScoreCell({ label, value, bright }: { label: string; value: string; bright?: boolean }) { + return ( + + {label} + {value} + + ); +}