11const canvas = document . getElementById ( 'game-canvas' ) ;
2- const context = canvas . getContext ( '2d' ) ;
2+ const context =
3+ canvas . getContext ( '2d' , { alpha : false , desynchronized : true } ) ||
4+ canvas . getContext ( '2d' ) ;
35const fpsDisplay = document . getElementById ( 'fps-counter' ) ;
46let wasmExports = null ;
57let lastTime = null ;
68let fpsFrameCount = 0 ;
79let fpsLastTimestamp = 0 ;
10+ let ballStatePtr = 0 ;
11+ let ballStateView = null ;
12+ const MAX_PIXEL_RATIO = 1.5 ;
13+
14+ function getBallStateView ( ) {
15+ if ( ! wasmExports || ! wasmExports . memory ) {
16+ return null ;
17+ }
18+
19+ const memoryBuffer = wasmExports . memory . buffer ;
20+ if ( ! ballStatePtr && typeof wasmExports . get_ball_state_ptr === 'function' ) {
21+ ballStatePtr = wasmExports . get_ball_state_ptr ( ) ;
22+ }
23+
24+ if ( ! ballStatePtr ) {
25+ return null ;
26+ }
27+
28+ if (
29+ ! ballStateView ||
30+ ballStateView . byteOffset !== ballStatePtr ||
31+ ballStateView . buffer !== memoryBuffer
32+ ) {
33+ ballStateView = new Float32Array ( memoryBuffer , ballStatePtr , 3 ) ;
34+ }
35+
36+ return ballStateView ;
37+ }
838
939function resizeCanvas ( ) {
10- canvas . width = window . innerWidth ;
11- canvas . height = window . innerHeight ;
40+ const deviceRatio = window . devicePixelRatio || 1 ;
41+ const pixelRatio = Math . min ( deviceRatio , MAX_PIXEL_RATIO ) ;
42+ const displayWidth = Math . floor ( window . innerWidth * pixelRatio ) ;
43+ const displayHeight = Math . floor ( window . innerHeight * pixelRatio ) ;
44+
45+ canvas . width = displayWidth ;
46+ canvas . height = displayHeight ;
47+ canvas . style . width = `${ window . innerWidth } px` ;
48+ canvas . style . height = `${ window . innerHeight } px` ;
49+
50+ if ( context && typeof context . resetTransform === 'function' ) {
51+ context . resetTransform ( ) ;
52+ }
53+
54+ ballStateView = null ;
1255
1356 if ( wasmExports ) {
1457 wasmExports . set_canvas_size ( canvas . width , canvas . height ) ;
1558 }
1659}
1760
1861function drawFrame ( ) {
19- if ( ! wasmExports ) {
62+ if ( ! wasmExports || ! context ) {
2063 return ;
2164 }
2265
23- context . clearRect ( 0 , 0 , canvas . width , canvas . height ) ;
66+ const state = getBallStateView ( ) ;
67+ let x ;
68+ let y ;
69+ let radius ;
70+
71+ if ( state ) {
72+ x = state [ 0 ] ;
73+ y = state [ 1 ] ;
74+ radius = state [ 2 ] ;
75+ } else {
76+ if ( typeof wasmExports . get_ball_radius !== 'function' ) {
77+ return ;
78+ }
79+
80+ radius = wasmExports . get_ball_radius ( ) ;
81+ x = wasmExports . get_ball_x ( ) ;
82+ y = wasmExports . get_ball_y ( ) ;
83+ }
84+
2485 context . fillStyle = '#0d47a1' ;
2586 context . fillRect ( 0 , 0 , canvas . width , canvas . height ) ;
2687
27- const radius = wasmExports . get_ball_radius ( ) ;
28- const x = wasmExports . get_ball_x ( ) ;
29- const y = wasmExports . get_ball_y ( ) ;
30-
3188 context . fillStyle = '#ffca28' ;
3289 context . beginPath ( ) ;
3390 context . arc ( x , y , radius , 0 , Math . PI * 2 ) ;
@@ -40,10 +97,24 @@ function updateAndRender(timestamp) {
4097 fpsLastTimestamp = timestamp ;
4198 }
4299
43- const deltaSeconds = ( timestamp - lastTime ) / 1000 ;
100+ const deltaSecondsRaw = ( timestamp - lastTime ) / 1000 ;
101+ const deltaSeconds = Math . min ( deltaSecondsRaw , 0.25 ) ;
44102 lastTime = timestamp ;
45103
46- wasmExports . update ( deltaSeconds ) ;
104+ if ( wasmExports ) {
105+ let ptr = 0 ;
106+ if ( typeof wasmExports . update_and_get_state === 'function' ) {
107+ ptr = wasmExports . update_and_get_state ( deltaSeconds ) ;
108+ } else if ( typeof wasmExports . update === 'function' ) {
109+ wasmExports . update ( deltaSeconds ) ;
110+ }
111+
112+ if ( ptr && ptr !== ballStatePtr ) {
113+ ballStatePtr = ptr ;
114+ ballStateView = null ;
115+ }
116+ }
117+
47118 drawFrame ( ) ;
48119
49120 fpsFrameCount += 1 ;
@@ -67,10 +138,18 @@ async function start() {
67138 wasmExports = instance . exports ;
68139
69140 resizeCanvas ( ) ;
70- wasmExports . reset_ball ( ) ;
141+
142+ if ( typeof wasmExports . get_ball_state_ptr === 'function' ) {
143+ ballStatePtr = wasmExports . get_ball_state_ptr ( ) ;
144+ }
145+
146+ if ( typeof wasmExports . reset_ball === 'function' ) {
147+ wasmExports . reset_ball ( ) ;
148+ }
149+
71150 drawFrame ( ) ;
72151 requestAnimationFrame ( updateAndRender ) ;
73152}
74153
75- window . addEventListener ( 'resize' , resizeCanvas ) ;
154+ window . addEventListener ( 'resize' , resizeCanvas , { passive : true } ) ;
76155start ( ) ;
0 commit comments