@@ -2,6 +2,7 @@ import { Application, Container, type Ticker } from "pixi.js";
22import { derived , get , writable } from "svelte/store" ;
33import { Facing } from "./constants.ts" ;
44import { Grid , createCellsFromStageDefinition } from "./grid.ts" ;
5+ import * as History from "./history.ts" ;
56import * as Player from "./player.ts" ;
67import type { Context , GameState , UIInfo } from "./public-types.ts" ;
78import { bunnyTexture } from "./resources.ts" ;
@@ -12,18 +13,13 @@ export async function setup(
1213 el : HTMLElement ,
1314 stageDefinition : StageDefinition ,
1415 bindings : {
15- onpause : ( ) => void ;
16- onresume : ( ) => void ;
17- ondestroy : ( ) => void ;
16+ pause : ( ) => void ;
17+ resume : ( ) => void ;
18+ destroy : ( ) => void ;
19+ reset : ( ) => void ;
1820 uiInfo : UIInfo ;
1921 } ,
2022) : Promise < void > {
21- bindings . onpause = ( ) => {
22- cx . state . update ( ( prev ) => {
23- prev . paused = true ;
24- return prev ;
25- } ) ;
26- } ;
2723 const cleanups : ( ( ) => void ) [ ] = [ ] ;
2824 const unlessPaused = ( f : ( ticker : Ticker ) => void ) => ( ticker : Ticker ) => {
2925 const paused = get ( cx . state ) . paused ;
@@ -65,6 +61,7 @@ export async function setup(
6561
6662 const gridMarginY =
6763 ( app . screen . height - blockSize * stageDefinition . stage . length ) / 2 ;
64+ // things that don't need to reset on reset()
6865 const config = writable ( {
6966 gridX,
7067 gridY,
@@ -73,7 +70,12 @@ export async function setup(
7370 initialPlayerX : stageDefinition . initialPlayerX ,
7471 initialPlayerY : stageDefinition . initialPlayerY ,
7572 } ) ;
76- const state = writable < GameState > ( {
73+
74+ const initialHistory = {
75+ index : 0 ,
76+ tree : [ ] ,
77+ } ;
78+ const initialGameState = {
7779 inventory : null ,
7880 inventoryIsInfinite : false ,
7981 usage : {
@@ -86,7 +88,27 @@ export async function setup(
8688 paused : false ,
8789 switches : [ ] ,
8890 switchingBlocks : [ ] ,
89- } ) ;
91+ } ;
92+ const initialDynamic = {
93+ focus : null ,
94+ player : {
95+ // HACK: these values are immediately overwritten inside Player.init().
96+ sprite : null ,
97+ coords : {
98+ x : stageDefinition . initialPlayerX ,
99+ y : stageDefinition . initialPlayerY ,
100+ } ,
101+ x : 0 ,
102+ y : 0 ,
103+ vx : 0 ,
104+ vy : 0 ,
105+ onGround : false ,
106+ jumpingBegin : null ,
107+ holdingKeys : { } ,
108+ facing : Facing . right ,
109+ } ,
110+ } ;
111+ const state = writable < GameState > ( structuredClone ( initialGameState ) ) ;
90112 const grid = new Grid (
91113 {
92114 _stage_container : stage ,
@@ -97,44 +119,40 @@ export async function setup(
97119 blockSize ,
98120 stageDefinition ,
99121 ) ;
100- const history = writable ( {
101- index : - 1 ,
102- tree : [ ] ,
103- } ) ;
104- const uiContext = derived ( [ state , history ] , ( [ $state , $history ] ) => {
105- return useUI ( $state , $history ) ;
106- } ) ;
122+ const history = writable ( structuredClone ( initialHistory ) ) ;
107123 const cx : Context = {
108124 _stage_container : stage ,
109125 grid,
110- dynamic : {
111- focus : null ,
112- player : {
113- // HACK: these values are immediately overwritten inside Player.init().
114- sprite : null ,
115- coords ( ) {
116- return { x : this . x , y : this . y } ;
117- } ,
118- x : 0 ,
119- y : 0 ,
120- vx : 0 ,
121- vy : 0 ,
122- onGround : false ,
123- jumpingBegin : null ,
124- holdingKeys : { } ,
125- facing : Facing . right ,
126- } ,
127- } ,
126+ dynamic : structuredClone ( initialDynamic ) ,
128127 state : state ,
129128 history,
130- uiContext,
131129 config,
132- elapsed : writable ( 0 ) ,
130+ elapsed : 0 , // does this need to be writable? like is anyone listening to this/
131+ } ;
132+ bindings . reset = ( ) => {
133+ const d = stageDefinition ;
134+ cx . history = writable ( structuredClone ( initialHistory ) ) ;
135+ // 内部実装ゴリゴリに知ってるリセットなので、直したかったら直して。多分 coords の各プロパティのセッターをいい感じにしてやれば良い
136+ // MEMO: `coords` は抽象化失敗してるので、直すか消すほうが良い
137+ cx . dynamic . player . x = blockSize * d . initialPlayerX ;
138+ cx . dynamic . player . y = blockSize * d . initialPlayerY + get ( cx . config ) . marginY ;
139+ cx . dynamic . focus = null ;
140+ cx . elapsed = 0 ;
141+ cx . state . update ( ( prev ) => ( {
142+ ...prev ,
143+ paused : false ,
144+ } ) ) ;
145+ cx . grid . diffAndUpdateTo (
146+ cx ,
147+ createCellsFromStageDefinition ( stageDefinition ) ,
148+ ) ;
149+ // 上に同じく。 init を使う?でも init は中で document.addEventListener してるので...
150+ History . record ( cx ) ;
133151 } ;
134152
135153 app . ticker . add (
136154 unlessPaused ( ( ticker ) => {
137- cx . elapsed . update ( ( prev ) => prev + ticker . deltaTime ) ;
155+ cx . elapsed += ticker . deltaTime ;
138156 } ) ,
139157 ) ;
140158
@@ -157,23 +175,27 @@ export async function setup(
157175 window . removeEventListener ( "resize" , onresize ) ;
158176 } ) ;
159177
160- bindings . ondestroy = ( ) => {
178+ bindings . destroy = ( ) => {
161179 for ( const cleanup of cleanups ) {
162180 cleanup ( ) ;
163181 }
164182 } ;
165- bindings . onresume = ( ) => {
183+ bindings . resume = ( ) => {
166184 cx . state . update ( ( prev ) => {
167185 prev . paused = false ;
168186 return prev ;
169187 } ) ;
170188 } ;
171- bindings . onpause = ( ) => {
189+ bindings . pause = ( ) => {
172190 cx . state . update ( ( prev ) => {
173191 prev . paused = true ;
174192 return prev ;
175193 } ) ;
176194 } ;
195+
196+ const uiContext = derived ( [ state , history ] , ( [ $state , $history ] ) => {
197+ return useUI ( $state , $history ) ;
198+ } ) ;
177199 uiContext . subscribe ( ( uiInfo ) => {
178200 bindings . uiInfo = uiInfo ;
179201 } ) ;
0 commit comments