Integrate match score into each player card

Changed score display approach to show score directly on each player's card:
- Removed separate ScoreDisplay overlay component
- Added matchScore prop to LifeCounter component
- Created MatchScoreBadge: circular badge in corner of each player card
- Score only displays for 2-player games when score > 0
- Badge positioned in safe corner (adapts to rotation)
- Styled as 12vmin circle with 6vmin text, black/70 background

Score is now part of each player's area rather than a separate overlay.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Viktor Rådberg
2025-11-16 18:27:28 +01:00
parent 873d85ca18
commit c71dbc2769
3 changed files with 27 additions and 5 deletions

View File

@@ -24,6 +24,21 @@ const SettingsButtonTwc = twc.button<RotationButtonProps>((props) => [
: 'top-1/4 right-[1vmax]', : 'top-1/4 right-[1vmax]',
]); ]);
const MatchScoreBadge = twc.div<RotationDivProps>((props) => [
'absolute flex items-center justify-center',
'bg-black/70 backdrop-blur-sm',
'rounded-full',
'w-[12vmin] h-[12vmin]',
'text-white font-bold',
'text-[6vmin]',
'z-[1]',
'pointer-events-none',
'select-none webkit-user-select-none',
props.$rotation === Rotation.Side || props.$rotation === Rotation.SideFlipped
? `left-[1vmax] top-1/4`
: 'left-1/4 top-[1vmax]',
]);
type SettingsButtonProps = { type SettingsButtonProps = {
onClick: () => void; onClick: () => void;
rotation: Rotation; rotation: Rotation;
@@ -98,11 +113,12 @@ type LifeCounterProps = {
player: Player; player: Player;
opponents: Player[]; opponents: Player[];
isStartingPlayer?: boolean; isStartingPlayer?: boolean;
matchScore?: number;
}; };
const RECENT_DIFFERENCE_TTL = 3_000; const RECENT_DIFFERENCE_TTL = 3_000;
const LifeCounter = ({ player, opponents }: LifeCounterProps) => { const LifeCounter = ({ player, opponents, matchScore }: LifeCounterProps) => {
const { updatePlayer, updateLifeTotal } = usePlayers(); const { updatePlayer, updateLifeTotal } = usePlayers();
const { settings, playing } = useGlobalSettings(); const { settings, playing } = useGlobalSettings();
const recentDifferenceTimerRef = useRef<NodeJS.Timeout | undefined>( const recentDifferenceTimerRef = useRef<NodeJS.Timeout | undefined>(
@@ -209,6 +225,14 @@ const LifeCounter = ({ player, opponents }: LifeCounterProps) => {
{player.hasLost && ( {player.hasLost && (
<PlayerLostWrapper $rotation={player.settings.rotation} /> <PlayerLostWrapper $rotation={player.settings.rotation} />
)} )}
{matchScore !== undefined && matchScore > 0 && (
<MatchScoreBadge
$rotation={player.settings.rotation}
style={{ rotate: `${calcRotation}deg` }}
>
{matchScore}
</MatchScoreBadge>
)}
<CommanderDamageBar <CommanderDamageBar
opponents={opponents} opponents={opponents}
player={player} player={player}

View File

@@ -31,7 +31,7 @@ const PlayersWrapper = twc.div`w-full h-full bg-black`;
export const Players = ({ gridLayout }: { gridLayout: GridLayout }) => { export const Players = ({ gridLayout }: { gridLayout: GridLayout }) => {
const { players } = usePlayers(); const { players } = usePlayers();
const { playing, settings, preStartCompleted } = useGlobalSettings(); const { playing, settings, preStartCompleted, gameScore } = useGlobalSettings();
return ( return (
<PlayersWrapper> <PlayersWrapper>
@@ -48,6 +48,7 @@ export const Players = ({ gridLayout }: { gridLayout: GridLayout }) => {
opponents={players.filter( opponents={players.filter(
(opponent) => opponent.index !== player.index (opponent) => opponent.index !== player.index
)} )}
matchScore={players.length === 2 ? gameScore[player.index] : undefined}
/> />
{settings.preStartMode === PreStartMode.RandomKing && {settings.preStartMode === PreStartMode.RandomKing &&

View File

@@ -7,7 +7,6 @@ import { Orientation, PreStartMode } from '../../Types/Settings';
import { Players } from '../Players/Players'; import { Players } from '../Players/Players';
import { PreStart } from '../PreStartGame/PreStart'; import { PreStart } from '../PreStartGame/PreStart';
import { GameOver } from '../GameOver/GameOver'; import { GameOver } from '../GameOver/GameOver';
import { ScoreDisplay } from '../ScoreDisplay/ScoreDisplay';
const MainWrapper = twc.div`w-[100dvmax] h-[100dvmin] overflow-hidden, setPlayers`; const MainWrapper = twc.div`w-[100dvmax] h-[100dvmin] overflow-hidden, setPlayers`;
@@ -138,8 +137,6 @@ export const Play = () => {
<Players gridLayout={gridLayout} /> <Players gridLayout={gridLayout} />
{players.length === 2 && <ScoreDisplay players={players} gameScore={gameScore} />}
{winner !== null && ( {winner !== null && (
<GameOver <GameOver
winner={players[winner]} winner={players[winner]}