1- import { type Container , Sprite } from "pixi.js" ;
1+ import { type Container , Sprite , type Ticker } from "pixi.js" ;
22import { type Writable , get } from "svelte/store" ;
33import { Block } from "./constants.ts" ;
4+ import * as consts from "./constants.ts" ;
45import { assert } from "./lib.ts" ;
56import type {
67 Context ,
@@ -21,6 +22,8 @@ import type { StageDefinition } from "./stages.ts";
2122type VirtualSpriteCell = {
2223 sprite : Sprite | null ;
2324 block : Block ;
25+ dy ?: number ; // in pixels
26+ dvy ?: number ;
2427} ;
2528export type GridCell =
2629 | {
@@ -34,7 +37,6 @@ export type GridCell =
3437 | {
3538 block : Block . fallable ;
3639 objectId : string ;
37- dy : number ; // in pixels
3840 }
3941 | {
4042 block : Block . air ;
@@ -646,7 +648,6 @@ export class Grid {
646648 cells [ y ] [ x ] = {
647649 block : cell . block ,
648650 objectId : cell . objectId ,
649- dy : 0 ,
650651 } ;
651652 prev . sprite = movableSprite ;
652653 prev . block = cell . block ;
@@ -661,6 +662,48 @@ export class Grid {
661662 cells : cells ,
662663 } ) ) ;
663664 }
665+ tick ( cx : Context , ticker : Ticker ) {
666+ const { blockSize, gridX, gridY, marginY } = get ( cx . config ) ;
667+ const cells = get ( cx . state ) . cells ;
668+ for ( let y = gridY - 1 ; y >= 0 ; y -- ) {
669+ for ( let x = 0 ; x < gridX ; x ++ ) {
670+ let cellY = y ;
671+ const vsom = this . vsom [ cellY ] [ x ] ;
672+ const cell = cells [ cellY ] [ x ] ;
673+ if ( cell . block === Block . fallable ) {
674+ vsom . dy = ( vsom . dy ?? 0 ) + ( vsom . dvy ?? 0 ) * ticker . deltaTime ;
675+ vsom . dvy =
676+ ( vsom . dvy ?? 0 ) + consts . gravity * blockSize * ticker . deltaTime ;
677+ while ( vsom . dy > 0 && cellY <= gridY - 2 ) {
678+ // 下のブロックと接触判定を行う
679+ const vsomBelow = this . vsom [ cellY + 1 ] [ x ] ;
680+ const cellBelow = cells [ cellY + 1 ] [ x ] ;
681+ if ( cellBelow . block === Block . air ) {
682+ assert ( vsomBelow . sprite === null , "air sprite is not null" ) ;
683+ // fallableを1ブロック下に動かしdyを1blockSize分上げる
684+ vsom . dy -= blockSize ;
685+ this . vsom [ cellY + 1 ] [ x ] = vsom ;
686+ this . vsom [ cellY ] [ x ] = vsomBelow ;
687+ cells [ cellY + 1 ] [ x ] = cell ;
688+ cells [ cellY ] [ x ] = cellBelow ;
689+ cellY += 1 ;
690+ cx . state . update ( ( prev ) => ( {
691+ ...prev ,
692+ cells : cells ,
693+ } ) ) ;
694+ } else {
695+ // 衝突したので止める
696+ vsom . dy = 0 ;
697+ vsom . dvy = 0 ;
698+ break ;
699+ }
700+ }
701+ assert ( ! ! vsom . sprite , "falling sprite is null" ) ;
702+ vsom . sprite . y = cellY * blockSize + marginY + vsom . dy ;
703+ }
704+ }
705+ }
706+ }
664707}
665708
666709export function createCellsFromStageDefinition (
@@ -695,7 +738,6 @@ export function createCellsFromStageDefinition(
695738 const cell : GridCell = {
696739 block,
697740 objectId,
698- dy : 0 ,
699741 } ;
700742 row . push ( cell ) ;
701743 break ;
0 commit comments