start work on game view

This commit is contained in:
Branden J Brown 2024-01-29 22:11:56 -06:00
parent 23703dbe3e
commit f3971a4b28
7 changed files with 169 additions and 1 deletions

View File

@ -7,7 +7,12 @@ export {}
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
Game: typeof import('./src/components/Game.vue')['default']
GameRound: typeof import('./src/components/GameRound.vue')['default']
GameStatus: typeof import('./src/components/GameStatus.vue')['default']
HelloWorld: typeof import('./src/components/HelloWorld.vue')['default'] HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
Player: typeof import('./src/components/Player.vue')['default']
PlayerHP: typeof import('./src/components/PlayerHP.vue')['default']
TheLanding: typeof import('./src/components/TheLanding.vue')['default'] TheLanding: typeof import('./src/components/TheLanding.vue')['default']
} }
} }

View File

@ -7,7 +7,8 @@
</template> </template>
</v-app-bar> </v-app-bar>
<v-main> <v-main>
<TheLanding @play="playing = !playing" /> <TheLanding v-if="!playing" @play="playing = !playing" />
<Game v-else />
</v-main> </v-main>
</v-app> </v-app>
</template> </template>

View File

@ -0,0 +1,38 @@
<template>
<v-container>
<v-row class="d-flex justify-center">
<v-sheet :elevation="2" width="800" height="600">
<v-row class="d-flex justify-center">
<v-col cols="auto">
<GameStatus :game="testGame" />
</v-col>
</v-row>
<v-row>
<v-col cols="6">
<!-- dealer -->
<Player :stats="testGame.players[0]" :dealer="true" />
</v-col>
<v-divider vertical />
<v-col cols="6">
<!-- challenger -->
<Player :stats="testGame.players[1]" :dealer="false" />
</v-col>
</v-row>
</v-sheet>
</v-row>
</v-container>
</template>
<script setup lang="ts">
import type { Game } from '@/lib/game';
const testGame: Game = {
players: [
{ hp: 4, items: ['🔍', '', '', '', '', '', '', ''] },
{ hp: 3, items: ['🔍', '🔍', '', '', '', '', '', ''] },
],
round: 1,
damage: 1,
previous: true,
};
</script>

View File

@ -0,0 +1,27 @@
<template>
<v-sheet class="d-flex justify-center mt-2" :elevation="2">
<v-row v-if="gameOn">
<v-chip v-for="c of roundChips" class="ma-4" :variant="c.variant">{{ c.text }}</v-chip>
</v-row>
</v-sheet>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { Game } from '@/lib/game';
export interface Props {
game: Game;
}
const props = defineProps<Props>();
// TODO(zeph): simplify this condition, this should just come in the game state
const gameOn = computed(() => props.game.round < 3 || props.game.players.every((p) => p.hp > 0))
const roundChips = computed(() => [
{ text: "I", variant: props.game.round === 1 ? 'elevated' : undefined },
{ text: "II", variant: props.game.round === 2 ? 'elevated' : undefined },
{ text: "III", variant: props.game.round === 3 ? 'elevated' : undefined },
] as const)
</script>

View File

@ -0,0 +1,21 @@
<template>
<v-container class="fill-height">
<v-row :class="rowClass">
<PlayerHP :hp="props.stats.hp" />
</v-row>
</v-container>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { Player } from '@/lib/game';
export interface Props {
stats: Player
dealer: boolean
}
const props = defineProps<Props>();
const rowClass = computed(() => ({ 'd-flex': true, 'justify-end': props.dealer, 'justify-start': !props.dealer }));
</script>

View File

@ -0,0 +1,17 @@
<template>
<v-sheet :elevation="2" width="100" class="text-center">
{{ text }}
</v-sheet>
</template>
<script setup lang="ts">
import { computed } from 'vue';
export interface Props {
hp: number;
}
const props = defineProps<Props>();
const text = computed(() => '⚡'.repeat(props.hp));
</script>

59
site/src/lib/game.ts Normal file
View File

@ -0,0 +1,59 @@
/**
* Overall game state as received from the server.
*/
export interface Game {
/**
* Players in the game.
* The first element is the dealer and the second is the challenger.
*/
players: [Player, Player];
/**
* Round number.
*/
round: number;
/**
* Damage that a live round will deal this turn.
*/
damage: number;
/**
* The current shell if it is revealed for the player receiving this state.
*/
shell?: boolean;
/**
* The previous discharged shell, if any.
*/
previous: boolean | null;
/**
* Number of live shells this game.
* Only included on the first turn of the game.
*/
live?: number;
/**
* Number of blank shells this game.
* Only included on the first tuurn of the game.
*/
blank?: number;
}
/**
* Displayed state of a player as received from the server.
*/
export interface Player {
hp: number;
items: string[];
cuffs?: boolean;
}
/**
* DTO for the game start.
*/
export interface GameStart {
/**
* Game ID for sharing.
*/
id: string;
/**
* Whether the player receiving this object is the dealer.
*/
dealer: boolean;
}