@@ -5,12 +5,31 @@ import { ref } from 'vue'
55
66const { gameState, startGame } = useGameManager ()
77const loading = ref (false )
8+ const seedInput = ref (' ' )
9+ const copied = ref (false )
810
911async function start() {
1012 loading .value = true
1113 await startGame ()
1214 loading .value = false
1315}
16+
17+ async function copySeed() {
18+ if (! gameState .value .seed ) return
19+ await navigator .clipboard .writeText (String (gameState .value .seed ))
20+ copied .value = true
21+ setTimeout (() => (copied .value = false ), 1200 )
22+ }
23+
24+ async function applySeed() {
25+ const newSeed = seedInput .value .trim ()
26+ if (! newSeed ) return
27+ ;(document .getElementById (' multiplayerModal' ) as HTMLDialogElement )?.close ()
28+ seedInput .value = ' '
29+ loading .value = true
30+ await startGame (newSeed )
31+ loading .value = false
32+ }
1433 </script >
1534
1635<template >
@@ -20,10 +39,78 @@ async function start() {
2039 <p class =" py-4" >Here, you will find explanation on how to play the game</p >
2140 <div class =" modal-action" >
2241 <form method =" dialog" >
23- <button class =" btn btn-soft btn-primary" >Close</button >
42+ <button class =" btn btn-soft btn-primary" >
43+ <FontAwesomeIcon icon="xmark" class="w-5 h-5" />
44+ Close
45+ </button >
46+ </form >
47+ </div >
48+ </div >
49+ </dialog >
50+
51+ <dialog id =" multiplayerModal" class =" modal" >
52+ <div class =" modal-box" >
53+ <h3 class =" text-lg font-bold" >Multiplayer</h3 >
54+ <p class =" py-2 text-sm opacity-70" >
55+ Every game has a seed. Two players using the same seed get the same start station and the
56+ same target, so you can race a friend on identical journeys. Share your seed to challenge
57+ someone, or enter theirs below to join their game.
58+ </p >
59+
60+ <!-- Share your current seed -->
61+ <div class =" mt-4" >
62+ <label class =" label pb-1" >
63+ <span class =" label-text font-bold" >Your current seed</span >
64+ </label >
65+ <div class =" join w-full" >
66+ <input
67+ type =" text"
68+ class =" input input-bordered join-item flex-1 font-mono text-center"
69+ :value =" gameState.seed ?? '—'"
70+ readonly
71+ aria-label =" Your current seed"
72+ />
73+ <button class =" btn join-item" @click =" copySeed" :disabled =" !gameState.seed" >
74+ <FontAwesomeIcon :icon =" copied ? ' check' : ' copy' " class="w-5 h-5" />
75+ {{ copied ? 'Copied' : 'Copy' }}
76+ </button >
77+ </div >
78+ </div >
79+
80+ <div class =" mt-4" >
81+ <label class =" label pb-1" >
82+ <span class =" label-text font-bold" >Join a game</span >
83+ </label >
84+ <input
85+ v-model =" seedInput"
86+ type =" text"
87+ class =" input input-bordered w-full font-mono"
88+ placeholder =" Enter a seed"
89+ @keyup.enter =" applySeed"
90+ />
91+ <label class =" label pt-1" >
92+ <span class =" label-text-alt opacity-60" >
93+ Applying restarts the game with this seed.
94+ </span >
95+ </label >
96+ </div >
97+
98+ <div class =" modal-action" >
99+ <form method =" dialog" >
100+ <button class =" btn btn-joined" >
101+ <FontAwesomeIcon icon="xmark" class="w-5 h-5" />
102+ Cancel
103+ </button >
24104 </form >
105+ <button class =" btn btn-primary" @click =" applySeed" :disabled =" !seedInput.trim()" >
106+ <FontAwesomeIcon icon="check" class="w-5 h-5" />
107+ Apply & restart
108+ </button >
25109 </div >
26110 </div >
111+ <form method =" dialog" class =" modal-backdrop" >
112+ <button >close</button >
113+ </form >
27114 </dialog >
28115
29116 <div
@@ -60,22 +147,29 @@ async function start() {
60147 <div
61148 class =" w-full lg:w-auto flex flex-row gap-2 justify-center lg:justify-end max-w-md lg:max-w-none mx-auto lg:mx-0 shrink-0"
62149 >
150+ <button
151+ class =" btn btn-secondary btn-soft flex-1 lg:flex-initial font-bold lg:px-6"
152+ onclick =" multiplayerModal.showModal()"
153+ >
154+ <FontAwesomeIcon icon="users" class="w-5 h-5" />
155+ Multiplayer
156+ </button >
63157 <button
64158 class =" btn btn-secondary btn-soft flex-1 lg:flex-initial font-bold lg:px-6"
65159 onclick =" helpModal.showModal()"
66160 >
67- How to play?
161+ <FontAwesomeIcon icon="circle-question" class="w-5 h-5" />
162+ How to play
68163 </button >
69164 <button
70165 class =" btn btn-primary btn-soft flex-1 lg:flex-initial font-bold lg:px-6"
71166 @click =" start()"
72167 :disabled =" loading"
73168 >
74169 <span v-if =" loading" class =" loading loading-spinner loading-xs" ></span >
170+ <FontAwesomeIcon icon="arrow-rotate-left" class="w-5 h-5" />
75171 Restart
76172 </button >
77173 </div >
78174 </div >
79175</template >
80-
81- <style scoped></style >
0 commit comments