11import { Application , Container , type Ticker } from "pixi.js" ;
2- import { type Writable , get , writable } from "svelte/store" ;
2+ import { derived , get , writable } from "svelte/store" ;
33import { Facing } from "./constants.ts" ;
44import { Grid } from "./grid.ts" ;
5- import { Player } from "./player.ts" ;
6- import type { Context , GameState , UIContext } from "./public-types.ts" ;
5+ import * as Player from "./player.ts" ;
6+ import type { Context , GameState , UIInfo } from "./public-types.ts" ;
77import { bunnyTexture } from "./resources.ts" ;
88import type { StageDefinition } from "./stages.ts" ;
9+ import { useUI } from "./ui-info.ts" ;
910
1011export async function setup (
1112 el : HTMLElement ,
1213 stageDefinition : StageDefinition ,
13- uiContext : Writable < UIContext > ,
14- ) {
15- let paused = false ;
16- uiContext . subscribe ( ( v ) => {
17- paused = v . paused ;
18- } ) ;
14+ bindings : {
15+ onpause : ( ) => void ;
16+ onresume : ( ) => void ;
17+ ondestroy : ( ) => void ;
18+ uiInfo : UIInfo ;
19+ } ,
20+ ) : Promise < void > {
21+ bindings . onpause = ( ) => {
22+ cx . state . update ( ( prev ) => {
23+ prev . paused = true ;
24+ return prev ;
25+ } ) ;
26+ } ;
27+ const cleanups : ( ( ) => void ) [ ] = [ ] ;
1928 const unlessPaused = ( f : ( ticker : Ticker ) => void ) => ( ticker : Ticker ) => {
29+ const paused = get ( cx . state ) . paused ;
2030 if ( ! paused ) {
2131 f ( ticker ) ;
2232 }
2333 } ;
2434
2535 function tick ( ) {
2636 // highlight is re-rendered every tick
27- const highlight = player . createHighlight ( cx ) ;
37+ const highlight = Player . createHighlight ( cx ) ;
2838 if ( highlight ) {
2939 stage . addChild ( highlight ) ;
3040 }
@@ -39,6 +49,9 @@ export async function setup(
3949 const app = new Application ( ) ;
4050 const stage = new Container ( ) ;
4151 app . stage . addChild ( stage ) ;
52+ cleanups . push ( ( ) => {
53+ app . destroy ( true , { children : true } ) ;
54+ } ) ;
4255
4356 const gridX = stageDefinition . stage [ 0 ] . length ;
4457 const gridY = stageDefinition . stage . length ;
@@ -51,27 +64,49 @@ export async function setup(
5164 ) ;
5265 const grid = new Grid ( stage , app . screen . height , blockSize , stageDefinition ) ;
5366
67+ const state = writable < GameState > ( {
68+ inventory : null ,
69+ inventoryIsInfinite : false ,
70+ usage : {
71+ // TODO
72+ copy : Number . POSITIVE_INFINITY ,
73+ paste : Number . POSITIVE_INFINITY ,
74+ cut : Number . POSITIVE_INFINITY ,
75+ } ,
76+ cells : grid . snapshot ( ) ,
77+ paused : false ,
78+ } ) ;
79+ const history = writable ( {
80+ index : - 1 ,
81+ tree : [ ] ,
82+ } ) ;
83+ const uiContext = derived ( [ state , history ] , ( [ $state , $history ] ) => {
84+ return useUI ( $state , $history ) ;
85+ } ) ;
5486 const cx : Context = {
55- _stage : stage ,
87+ _stage_container : stage ,
5688 grid,
5789 dynamic : {
5890 focus : null ,
59- playerX : stageDefinition . initialPlayerX ,
60- playerY : stageDefinition . initialPlayerY ,
61- playerFacing : Facing . right ,
62- } ,
63-
64- state : writable < GameState > ( {
65- inventory : null ,
66- inventoryIsInfinite : false ,
67- usage : {
68- // TODO
69- copy : Number . POSITIVE_INFINITY ,
70- paste : Number . POSITIVE_INFINITY ,
71- cut : Number . POSITIVE_INFINITY ,
91+ player : {
92+ // HACK: these values are immediately overwritten inside Player.init().
93+ sprite : null ,
94+ coords ( ) {
95+ return { x : this . x , y : this . y } ;
96+ } ,
97+ x : 0 ,
98+ y : 0 ,
99+ vx : 0 ,
100+ vy : 0 ,
101+ onGround : false ,
102+ jumpingBegin : null ,
103+ holdingKeys : { } ,
104+ facing : Facing . left ,
72105 } ,
73- cells : grid . snapshot ( ) ,
74- } ) ,
106+ } ,
107+ state : state ,
108+ history,
109+ uiContext,
75110 config : writable ( {
76111 gridX,
77112 gridY,
@@ -80,22 +115,17 @@ export async function setup(
80115 initialPlayerX : stageDefinition . initialPlayerX ,
81116 initialPlayerY : stageDefinition . initialPlayerY ,
82117 } ) ,
83- history : writable ( {
84- index : - 1 ,
85- tree : [ ] ,
86- } ) ,
87118 elapsed : writable ( 0 ) ,
88- uiContext,
89119 } ;
120+
90121 app . ticker . add (
91122 unlessPaused ( ( ticker ) => {
92123 cx . elapsed . update ( ( prev ) => prev + ticker . deltaTime ) ;
93124 } ) ,
94125 ) ;
95126
96- const player = new Player ( cx , bunnyTexture ) ;
97- app . ticker . add ( unlessPaused ( ( ticker ) => player . tick ( cx , ticker ) ) ) ;
98- app . stage . addChild ( player . sprite ) ;
127+ cx . dynamic . player = Player . init ( cx , bunnyTexture ) ;
128+ app . ticker . add ( unlessPaused ( ( ticker ) => Player . tick ( cx , ticker ) ) ) ;
99129
100130 let cleanup : undefined | ( ( ) => void ) = undefined ;
101131 app . ticker . add (
@@ -107,8 +137,42 @@ export async function setup(
107137
108138 // Append the application canvas to the document body
109139 el . appendChild ( app . canvas ) ;
140+ const onresize = useOnResize ( cx , app , grid , gridX , gridY ) ;
141+ window . addEventListener ( "resize" , onresize ) ;
142+ cleanups . push ( ( ) => {
143+ window . removeEventListener ( "resize" , onresize ) ;
144+ } ) ;
145+
146+ bindings . ondestroy = ( ) => {
147+ for ( const cleanup of cleanups ) {
148+ cleanup ( ) ;
149+ }
150+ } ;
151+ bindings . onresume = ( ) => {
152+ cx . state . update ( ( prev ) => {
153+ prev . paused = false ;
154+ return prev ;
155+ } ) ;
156+ } ;
157+ bindings . onpause = ( ) => {
158+ cx . state . update ( ( prev ) => {
159+ prev . paused = true ;
160+ return prev ;
161+ } ) ;
162+ } ;
163+ uiContext . subscribe ( ( uiInfo ) => {
164+ bindings . uiInfo = uiInfo ;
165+ } ) ;
166+ }
110167
111- window . addEventListener ( "resize" , ( ) => {
168+ function useOnResize (
169+ cx : Context ,
170+ app : Application ,
171+ grid : Grid ,
172+ gridX : number ,
173+ gridY : number ,
174+ ) {
175+ return ( ) => {
112176 app . renderer . resize ( window . innerWidth , window . innerHeight ) ;
113177 const blockSize = Math . min (
114178 app . screen . width / gridX ,
@@ -120,6 +184,6 @@ export async function setup(
120184 return prev ;
121185 } ) ;
122186 cx . grid . rerender ( app . screen . height , blockSize ) ;
123- player . resize ( cx ) ;
124- } ) ;
187+ Player . resize ( cx ) ;
188+ } ;
125189}
0 commit comments