File tree Expand file tree Collapse file tree
apps/examples/src/hello-world
tests/odyc-e2e/functional Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -30,6 +30,12 @@ const game = createGame({
3030 ...66...
3131 ` ,
3232 dialog : 'Hello adventurer!' ,
33+ onCollide ( ) {
34+ console . log ( 'You have collided with the cell!' )
35+ } ,
36+ onCollideStart ( ) {
37+ console . log ( 'You have previously collided with the cell!' )
38+ } ,
3339 } ,
3440 } ,
3541 map : `
Original file line number Diff line number Diff line change @@ -44,17 +44,21 @@ class GameLoop<T extends string> {
4444 if ( this . #isCellOnworld( to . value ) ) {
4545 const cell = this . #gameState. cells . getCellAt ( ...to . value )
4646
47- if ( ! cell . solid ) {
47+ if ( cell . solid ) {
48+ await this . #gameState. cells . getEvent ( ...to . value , 'onCollideStart' ) ?.( )
49+ } else {
4850 await this . #gameState. cells . getEvent ( ...from . value , 'onLeave' ) ?.( )
4951 this . #gameState. player . position = to . value
52+ await this . #gameState. cells . getEvent ( ...to . value , 'onEnterStart' ) ?.( )
5053 }
5154
5255 this . #playSound( cell )
5356 await this . #openDialog( cell )
5457
55- if ( cell . solid )
56- await this . #gameState. cells . getEvent ( ...to . value , 'onCollide' ) ?.( )
57- else await this . #gameState. cells . getEvent ( ...to . value , 'onEnter' ) ?.( )
58+ await this . #gameState. cells . getEvent (
59+ ...to . value ,
60+ cell . solid ? 'onCollide' : 'onEnter' ,
61+ ) ?.( )
5862 }
5963
6064 for ( const cell of this . #gameState. cells . get ( ) ) {
Original file line number Diff line number Diff line change @@ -163,7 +163,9 @@ export class Cells<T extends string> {
163163 y : number ,
164164 eventKey :
165165 | 'onCollide'
166+ | 'onCollideStart'
166167 | 'onEnter'
168+ | 'onEnterStart'
167169 | 'onLeave'
168170 | 'onScreenLeave'
169171 | 'onScreenEnter'
@@ -247,6 +249,8 @@ export class Cells<T extends string> {
247249 visible : template . visible !== false ,
248250 foreground : template . foreground === true ,
249251 onCollide : template . onCollide ,
252+ onCollideStart : template . onCollideStart ,
253+ onEnterStart : template . onEnterStart ,
250254 onEnter : template . onEnter ,
251255 onLeave : template . onLeave ,
252256 onScreenEnter : template . onScreenEnter ,
Original file line number Diff line number Diff line change @@ -45,6 +45,10 @@ export type CellState<T extends string> = {
4545 position : [ number , number ]
4646 /** Called when player tries to move into this cell's position */
4747 onCollide ?: ( target : CellFacade < T > ) => any
48+ /** Called after player collides with this cell */
49+ onCollideStart ?: ( target : CellFacade < T > ) => any
50+ /** Call when a player begins to enter a cell, before dialog and sounds */
51+ onEnterStart ?: ( target : CellFacade < T > ) => any
4852 /** Called when player moves into this cell's position */
4953 onEnter ?: ( target : CellFacade < T > ) => any
5054 /** Called when player leaves this cell's position */
@@ -70,6 +74,8 @@ export type CellParams = Partial<
7074 | 'symbol'
7175 | 'position'
7276 | 'onCollide'
77+ | 'onCollideStart'
78+ | 'onEnterStart'
7379 | 'onEnter'
7480 | 'onLeave'
7581 | 'onScreenEnter'
Original file line number Diff line number Diff line change @@ -5,13 +5,14 @@ const state = {
55 turnSpy : null as any ,
66 enterSpy : null as any ,
77 collideSpy : null as any ,
8+ onCollideStartSpy : null as any ,
89}
910
1011export const init = ( ) => {
1112 state . turnSpy = vi . fn ( )
1213 state . enterSpy = vi . fn ( )
1314 state . collideSpy = vi . fn ( )
14-
15+ state . onCollideStartSpy = vi . fn ( )
1516 const game = createGame ( {
1617 templates : {
1718 x : {
@@ -21,6 +22,7 @@ export const init = () => {
2122 onTurn : state . turnSpy ,
2223 onEnter : state . enterSpy ,
2324 onCollide : state . collideSpy ,
25+ onCollideStart : state . onCollideStartSpy ,
2426 } ,
2527 y : {
2628 sprite : 2 ,
Original file line number Diff line number Diff line change 1+ import { expect , test , describe , vi } from 'vitest'
2+ import { createGame } from 'odyc'
3+ import { userEvent } from '@vitest/browser/context'
4+
5+ describe ( 'onCollide and onCollideStart events' , ( ) => {
6+ test ( 'should call onCollide when player collides with a cell' , async ( ) => {
7+ const collideSpy = vi . fn ( )
8+ const game = createGame ( {
9+ player : {
10+ position : [ 0 , 1 ] ,
11+ } ,
12+ templates : {
13+ x : {
14+ onCollide : collideSpy ,
15+ } ,
16+ } ,
17+ map :
18+ `
19+ x.
20+ ..
21+ ` ,
22+ } )
23+ expect ( collideSpy ) . not . toHaveBeenCalled ( )
24+ await userEvent . keyboard ( '[ArrowUp]' )
25+ expect ( collideSpy ) . toHaveBeenCalled ( )
26+ } )
27+ test ( 'should call onCollideStart when player collides with a cell for the first time' , async ( ) => {
28+ const collideStartSpy = vi . fn ( )
29+ const game = createGame ( {
30+ templates : {
31+ x : {
32+ onCollideStart : collideStartSpy ,
33+ } ,
34+ } ,
35+ map :
36+ `
37+ x.
38+ ..
39+ ` ,
40+ } )
41+ expect ( collideStartSpy ) . not . toHaveBeenCalled ( )
42+ // slightly more complex route for funsies
43+ await userEvent . keyboard ( '[ArrowRight]' )
44+ await userEvent . keyboard ( '[ArrowUp]' )
45+ await userEvent . keyboard ( '[ArrowLeft]' )
46+ expect ( collideStartSpy ) . toHaveBeenCalled ( )
47+ } )
48+ } )
You can’t perform that action at this time.
0 commit comments