1
1
"use client" ;
2
+ import { useAction } from "@/app/useAction" ;
2
3
import { Comets } from "@/core/comets" ;
4
+ import { KeyManager } from "@/core/keys" ;
3
5
import { init } from "@/core/loop" ;
4
- import { useEffect } from "react" ;
6
+ import { TickRecorder } from "@/core/tickRecorder" ;
7
+ import {
8
+ addToStore ,
9
+ getFromStore ,
10
+ removeFromStore ,
11
+ StorageKey ,
12
+ } from "@/rpc/storage" ;
13
+ import { useEffect , useRef } from "react" ;
5
14
15
+ const LOOP_INTERVAL = 1000 ;
6
16
export const Game = ( ) => {
17
+ const { submit } = useAction ( ) ;
18
+ const tickRecorder = useRef < TickRecorder > ( ) ;
19
+ const isStarting = useRef < boolean > ( false ) ;
20
+ const isEnding = useRef < boolean > ( false ) ;
21
+ const game = useRef < Comets > ( ) ;
22
+
23
+ const handleEndGame = async ( score : number ) => {
24
+ if ( isEnding . current ) {
25
+ return ;
26
+ }
27
+
28
+ isEnding . current = true ;
29
+ try {
30
+ await submit ( "endGame" , {
31
+ gameId : getFromStore ( StorageKey . GAME_ID ) ,
32
+ timestamp : Date . now ( ) ,
33
+ score,
34
+ gameInputs : tickRecorder . current ?. serializedTicks ( ) ,
35
+ } ) ;
36
+ } catch ( e : unknown ) {
37
+ console . error ( "Error sending ticks" , ( e as Error ) . message ) ;
38
+ } finally {
39
+ removeFromStore ( StorageKey . GAME_ID ) ;
40
+ game . current ?. switchToMainPage ( ) ;
41
+ isEnding . current = false ;
42
+ }
43
+ } ;
44
+
45
+ const handleStartGame = async ( ) => {
46
+ if ( isStarting . current ) {
47
+ return ;
48
+ }
49
+
50
+ isStarting . current = true ;
51
+ const res = await submit ( "startGame" , {
52
+ timestamp : Date . now ( ) ,
53
+ } ) ;
54
+ const gameId = res . logs [ 0 ] . value ;
55
+ console . debug ( "Game started" , gameId ) ;
56
+ addToStore ( StorageKey . GAME_ID , gameId ) ;
57
+ isStarting . current = false ;
58
+ return gameId ;
59
+ } ;
60
+
61
+ const createGame = ( ) => {
62
+ const km = new KeyManager ( ) ;
63
+ const tr = new TickRecorder ( km ) ;
64
+ tickRecorder . current = tr ;
65
+
66
+ const comets = new Comets ( km , tr , handleEndGame , handleStartGame ) ;
67
+ game . current = comets ;
68
+ } ;
69
+
7
70
useEffect ( ( ) => {
8
- const game = new Comets ( ) ;
71
+ createGame ( ) ;
72
+
9
73
const tick = setTimeout ( ( ) => {
10
- init ( game ) ;
11
- } , 1000 ) ;
74
+ if ( game . current ) {
75
+ init ( game . current ) ;
76
+ }
77
+ } , LOOP_INTERVAL ) ;
12
78
13
79
return ( ) => {
14
80
if ( tick ) {
@@ -19,7 +85,7 @@ export const Game = () => {
19
85
20
86
return (
21
87
< div id = "game" >
22
- < canvas id = "canvas" > </ canvas >
88
+ < canvas id = "canvas" className = "border-4 rounded-sm" > </ canvas >
23
89
</ div >
24
90
) ;
25
91
} ;
0 commit comments