diff --git a/demo/src/animationDemo.ts b/demo/src/animationDemo.ts index 25afe225..24a66d94 100644 --- a/demo/src/animationDemo.ts +++ b/demo/src/animationDemo.ts @@ -9,8 +9,13 @@ import { Axis2dAction, buttonMoments, createAnimation, - FlipComponent, + createResetInputsEcsSystem, + createSpriteAnimationEcsSystem, + createUpdateInputEcsSystem, + flipId, Game, + InputManager, + inputsId, KeyboardAxis1dBinding, KeyboardAxis2dBinding, KeyboardInputSource, @@ -18,24 +23,23 @@ import { keyCodes, MouseAxis2dBinding, MouseInputSource, - PositionComponent, - registerInputs, - ScaleComponent, + positionId, + scaleId, Sprite, - SpriteAnimationComponent, - SpriteComponent, + spriteAnimationId, + spriteId, Time, TriggerAction, Vector2, - World, } from '../../src'; +import { EcsWorld } from '../../src/new-ecs'; import { FiniteStateMachine } from '../../src/finite-state-machine/finite-state-machine'; import { Transition } from '../../src/finite-state-machine/transition'; import { ADVENTURER_ANIMATIONS, SHIP_ANIMATIONS } from './animationEnums'; -import { ControlAdventurerComponent } from './control-adventurer-component'; +import { controlAdventurerId } from './control-adventurer-component'; export function setupAnimationsDemo( - world: World, + world: EcsWorld, game: Game, time: Time, shipSprite: Sprite, @@ -43,6 +47,9 @@ export function setupAnimationsDemo( ): ReturnType { const inputs = setupInputs(world, game, time); + // Add animation system + world.addSystem(createSpriteAnimationEcsSystem(time)); + const ShipController = createShipAnimationController(); buildShipEntities(world, shipSprite, ShipController); @@ -58,7 +65,7 @@ export function setupAnimationsDemo( return inputs; } -function setupInputs(world: World, game: Game, time: Time) { +function setupInputs(world: EcsWorld, game: Game, time: Time) { const gameInputGroup = 'game'; const attackInput = new TriggerAction('attack', gameInputGroup); @@ -78,22 +85,28 @@ function setupInputs(world: World, game: Game, time: Time) { actionResetTypes.noReset, ); - const { inputsManager } = registerInputs(world, time, { - triggerActions: [ - attackInput, - runRInput, - runLInput, - jumpInput, - takeDamageInput, - ], - axis2dActions: [axis2dInput], - axis1dActions: [axis1dInput], - }); + // Create input manager and register actions + const inputsManager = new InputManager(gameInputGroup); + inputsManager.addTriggerActions( + attackInput, + runRInput, + runLInput, + jumpInput, + takeDamageInput, + ); + inputsManager.addAxis2dActions(axis2dInput); + inputsManager.addAxis1dActions(axis1dInput); + + // Create an entity with inputs component + const inputEntity = world.createEntity(); + world.addComponent(inputEntity, inputsId, { inputManager: inputsManager }); - inputsManager.setActiveGroup(gameInputGroup); + // Add input systems + world.addSystem(createUpdateInputEcsSystem(time)); + world.addSystem(createResetInputsEcsSystem()); const keyboardInputSource = new KeyboardInputSource(inputsManager); - const mouseInputSource = new MouseInputSource(inputsManager, game); + const mouseInputSource = new MouseInputSource(inputsManager, game.container); keyboardInputSource.axis2dBindings.add( new KeyboardAxis2dBinding( @@ -234,32 +247,65 @@ function createAdventurerControllableInputs() { } function buildShipEntities( - world: World, + world: EcsWorld, shipSprite: Sprite, stateMachine: FiniteStateMachine, ) { const animationInputs = new AnimationInputs(); - world.buildAndAddEntity([ - new PositionComponent(-500, -150), - new SpriteComponent(shipSprite), - new ScaleComponent(0.5, 0.5), - new SpriteAnimationComponent(stateMachine, animationInputs), - ]); + const entity = world.createEntity(); + world.addComponent(entity, positionId, { + local: new Vector2(-500, -150), + world: new Vector2(-500, -150), + }); + world.addComponent(entity, spriteId, { + sprite: shipSprite, + enabled: true, + }); + world.addComponent(entity, scaleId, { + local: new Vector2(0.5, 0.5), + world: new Vector2(0.5, 0.5), + }); + world.addComponent(entity, spriteAnimationId, { + animationFrameIndex: 0, + playbackSpeed: 1, + frameDurationMilliseconds: 33.3333, + lastFrameChangeTimeInSeconds: 0, + animationInputs, + stateMachine, + }); } function buildAdventurerControllableEntities( - world: World, + world: EcsWorld, adventurerSprite: Sprite, stateMachine: FiniteStateMachine, animationInputs: AnimationInputs, ) { - world.buildAndAddEntity([ - new PositionComponent(400, 0), - new SpriteComponent(adventurerSprite), - new ScaleComponent(0.3, 0.6), - new SpriteAnimationComponent(stateMachine, animationInputs, 33.3333, 0.3), - new ControlAdventurerComponent(), - new FlipComponent(), - ]); + const entity = world.createEntity(); + world.addComponent(entity, positionId, { + local: new Vector2(400, 0), + world: new Vector2(400, 0), + }); + world.addComponent(entity, spriteId, { + sprite: adventurerSprite, + enabled: true, + }); + world.addComponent(entity, scaleId, { + local: new Vector2(0.3, 0.6), + world: new Vector2(0.3, 0.6), + }); + world.addComponent(entity, spriteAnimationId, { + animationFrameIndex: 0, + playbackSpeed: 0.3, + frameDurationMilliseconds: 33.3333, + lastFrameChangeTimeInSeconds: 0, + animationInputs, + stateMachine, + }); + world.addTag(entity, controlAdventurerId); + world.addComponent(entity, flipId, { + flipX: false, + flipY: false, + }); } diff --git a/demo/src/control-adventurer-component.ts b/demo/src/control-adventurer-component.ts index a6366398..93c94b6e 100644 --- a/demo/src/control-adventurer-component.ts +++ b/demo/src/control-adventurer-component.ts @@ -1,3 +1,3 @@ -import { Component } from '../../src'; +import { createTagId } from '../../src/new-ecs/ecs-component'; -export class ControlAdventurerComponent extends Component {} +export const controlAdventurerId = createTagId('control-adventurer'); diff --git a/demo/src/control-adventurer-system.ts b/demo/src/control-adventurer-system.ts index 3422c15c..2dadc7c3 100644 --- a/demo/src/control-adventurer-system.ts +++ b/demo/src/control-adventurer-system.ts @@ -1,54 +1,31 @@ import { - Entity, - FlipComponent, - PositionComponent, - SpriteAnimationComponent, - System, + FlipEcsComponent, + flipId, + PositionEcsComponent, + positionId, + SpriteAnimationEcsComponent, + spriteAnimationId, TriggerAction, } from '../../src'; -import { ControlAdventurerComponent } from './control-adventurer-component'; - -export class ControlAdventurerSystem extends System { - private readonly _attackTriggerInput: TriggerAction; - private readonly _runRTriggerInput: TriggerAction; - private readonly _runLTriggerInput: TriggerAction; - private readonly _jumpTriggerInput: TriggerAction; - private readonly _takeDamageTriggerInput: TriggerAction; - - constructor( - attackTriggerInput: TriggerAction, - runRTriggerInput: TriggerAction, - runLTriggerInput: TriggerAction, - jumpTriggerInput: TriggerAction, - takeDamageTriggerInput: TriggerAction, - ) { - super( - [ - ControlAdventurerComponent, - SpriteAnimationComponent, - FlipComponent, - PositionComponent, - ], - 'ControlAdventurerSystem', - ); - - this._attackTriggerInput = attackTriggerInput; - this._runRTriggerInput = runRTriggerInput; - this._runLTriggerInput = runLTriggerInput; - this._jumpTriggerInput = jumpTriggerInput; - this._takeDamageTriggerInput = takeDamageTriggerInput; - } - - public run(entity: Entity): void { - const spriteAnimationComponent = entity.getComponentRequired( - SpriteAnimationComponent, - ); - - const flipComponent = entity.getComponentRequired(FlipComponent); +import { EcsSystem } from '../../src/new-ecs'; +import { controlAdventurerId } from './control-adventurer-component'; + +export const createControlAdventurerEcsSystem = ( + attackTriggerInput: TriggerAction, + runRTriggerInput: TriggerAction, + runLTriggerInput: TriggerAction, + jumpTriggerInput: TriggerAction, + takeDamageTriggerInput: TriggerAction, +): EcsSystem< + [SpriteAnimationEcsComponent, FlipEcsComponent, PositionEcsComponent] +> => ({ + query: [controlAdventurerId, spriteAnimationId, flipId, positionId], + run: (result) => { + const [spriteAnimationComponent, flipComponent] = result.components; const animationInputs = spriteAnimationComponent.animationInputs; - if (this._jumpTriggerInput.isTriggered) { + if (jumpTriggerInput.isTriggered) { console.log('Jumping!'); animationInputs.setTrigger('jump'); @@ -56,14 +33,14 @@ export class ControlAdventurerSystem extends System { return; } - if (this._runLTriggerInput.isTriggered) { + if (runLTriggerInput.isTriggered) { animationInputs.setToggle('run', true); flipComponent.flipX = true; return; } - if (this._runRTriggerInput.isTriggered) { + if (runRTriggerInput.isTriggered) { animationInputs.setToggle('run', true); flipComponent.flipX = false; @@ -72,13 +49,13 @@ export class ControlAdventurerSystem extends System { animationInputs.setToggle('run', false); - if (this._attackTriggerInput.isTriggered) { + if (attackTriggerInput.isTriggered) { animationInputs.setText('attack', 'attack is being set'); return; } - if (this._takeDamageTriggerInput.isTriggered) { + if (takeDamageTriggerInput.isTriggered) { const health = animationInputs.getNumber('health'); if (!health) { @@ -87,5 +64,5 @@ export class ControlAdventurerSystem extends System { health.value = Math.max(0, health.value - 50); } - } -} + }, +}); diff --git a/demo/src/fire-system.ts b/demo/src/fire-system.ts index 203eac96..ad75ce06 100644 --- a/demo/src/fire-system.ts +++ b/demo/src/fire-system.ts @@ -1,23 +1,18 @@ -import { HoldAction, InputsComponent, System, TriggerAction } from '../../src'; +import { HoldAction, InputsEcsComponent, inputsId, TriggerAction } from '../../src'; +import { EcsSystem } from '../../src/new-ecs'; -export class FireSystem extends System { - private readonly _fireAction: TriggerAction; - private readonly _runAction: HoldAction; - - constructor(fireAction: TriggerAction, runAction: HoldAction) { - super([InputsComponent], 'FireSystem'); - - this._fireAction = fireAction; - this._runAction = runAction; - } - - public run(): void { - if (this._fireAction.isTriggered) { +export const createFireEcsSystem = ( + fireAction: TriggerAction, + runAction: HoldAction, +): EcsSystem<[InputsEcsComponent]> => ({ + query: [inputsId], + run: () => { + if (fireAction.isTriggered) { console.log(`Fire action triggered`); } - if (this._runAction.isHeld) { + if (runAction.isHeld) { console.log(`Run action is being held`); } - } -} + }, +}); diff --git a/demo/src/game.ts b/demo/src/game.ts index 843c6f42..bfa6aa9c 100644 --- a/demo/src/game.ts +++ b/demo/src/game.ts @@ -1,11 +1,12 @@ import { + cameraId, + createCameraEcsSystem, createGame, createImageSprite, createRenderEcsSystem, positionId, Random, Rect, - registerCamera, spriteId, Vector2, } from '../../src'; @@ -20,9 +21,21 @@ enum RenderLayer { const { game, world, renderContext, time } = createGame('demo-container'); -registerCamera(world, time, { - scissorRect: new Rect(Vector2.zero, new Vector2(0.5, 1)), +// Create camera entity +const cameraEntity = world.createEntity(); +world.addComponent(cameraEntity, positionId, { + world: Vector2.zero, + local: Vector2.zero, +}); +world.addComponent(cameraEntity, cameraId, { + zoom: 1, + zoomSensitivity: 0.1, + panSensitivity: 1, + minZoom: 0.1, + maxZoom: 10, + isStatic: false, layerMask: RenderLayer.default | RenderLayer.foreground, + scissorRect: new Rect(Vector2.zero, new Vector2(0.5, 1)), }); const planetSprite = await createImageSprite( @@ -86,6 +99,7 @@ setInterval(() => { }, 1000); world.addSystem(createMoveEcsSystem(time)); +world.addSystem(createCameraEcsSystem(time)); world.addSystem(createRenderEcsSystem(renderContext)); game.run();