import * as ECSA from '../libs/pixi-component';
let engine = new ECSA.GameLoop();
let canvas = (document.getElementById('gameCanvas') as HTMLCanvasElement);
engine.init(canvas, 800, 600, 1, null, true);
engine.app.loader
.reset()
.add('spritesheet', './assets/spritesheet.png')
.load(onAssetsLoaded);
const onAssetsLoaded = () => {
engine.scene.clearScene();
}
let sprite = new ECSA.Sprite('mySprite', PIXI.Texture.from('spritesheet'));
sprite.position.set(engine.app.screen.width / 2, engine.app.screen.height / 2);
sprite.anchor.set(0.5);
engine.scene.stage.asContainer().addChild(sprite);
class RotationComponent extends ECSA.Component {
onUpdate(delta: number, absolute: number) {
this.owner.asContainer().rotation += 0.01 * delta;
}
}
// this will assign a component to the stage element
engine.scene.addGlobalComponent(new RotationComponent());
class RotationComponent extends ECSA.Component {
objects: ECSA.GameObject[];
onInit() {
this.subscribe('GAME_OVER');
this.objects = this.scene.findObjectsByTag('tag_rotating');
}
onMessage(msg: ECSA.Message) {
if(msg.action === 'GAME_OVER') { this.finish(); }
}
onUpdate(delta: number, absolute: number) {
this.objects.forEach(obj => obj.asContainer().rotation += 0.01 * delta);
}
onFinish() { this.objects = null; } // important to prevent memory leaks
}
let newObject = new ECSA.Sprite('arrow', arrowTexture);
// we can store any number of attributes of any type
newObject.assignAttribute(Attributes.SPEED, DEFAULT_ARROW_SPEED);
// we can store as much tags as we want, defining common groups/layers/etc
newObject.addTag('projectile');
// we can store flags within a range of 1-128
newObject.setFlag(FLAG_COLLIDABLE);
// we have only one number for states; for more complex states, we can use attributes
newObject.stateId = STATE_MOVING;
new ECSA.GameLoop().init(canvas, 800, 600, 1, {
debugEnabled: true,
flagsSearchEnabled: true,
statesSearchEnabled: true,
namesSearchEnabled: true,
tagsSearchEnabled: true,
notifyAttributeChanges: true,
notifyFlagChanges: true,
notifyStateChanges: true,
notifyTagChanges: true
}, true);
let droids = scene.findObjectsByTag('droid');
let charged = scene.findObjectsByFlag(FLAG_CHARGED);
let idle = scene.findObjectsByState(STATE_IDLE);
let chargedIdleDroids = scene.findObjectsByQuery({
ownerTag: 'droid',
ownerFlag: FLAG_CHARGED,
ownerState: STATE_IDLE
});
export class GameManager extends ECSA.Component {
... some code here
gameOver() {
this.player.stateId = States.DEAD;
this.sendMessage(Messages.GAME_OVER, this.score);
// wait 3 seconds and reset the game
this.scene.invokeWithDelay(3000, () => {
this.factory.resetGame(this.scene, this.model);
});
}
}
new ECSA.Builder(scene)
.relativePos(0.5, 0.92)
.anchor(0.5, 1)
.withAttribute(Attributes.RANGE, 25)
.withFlag(FLAG_COLLIDABLE)
.withFlag(FLAG_RANGE)
.withState(STATE_IDLE)
.withComponent(new TowerComponent())
.withComponent(new AimControlComponent())
.withComponent(new ProjectileSpawner())
.asSprite(PIXI.Texture.from(Assets.TEX_TOWER), 'tower')
.withParent(rootObject)
.build();
let unitBuilder = new ECSA.Builder(scene)
.anchor(0.5)
.withComponent(() => new UnitController())
.asSprite(PIXI.Texture.from(Assets.TEX_UNIT), 'unit')
.withParent(rootObject);
unitBuilder.relativePos(0, 0).build(false)
unitBuilder.relativePos(0.5, 0).build(false)
unitBuilder.relativePos(1, 0.5).build(false)
unitBuilder.relativePos(1, 1).build(false);
export class CannonInputController extends CannonController {
onUpdate(delta: number, absolute: number) {
// assuming that we added this component to the stage
let cmp = this.scene.findGlobalComponentByName<KeyInputComponent>(ECSA.KeyInputComponent.name);
if (cmp.isKeyPressed(ECSA.Keys.KEY_LEFT)) {
this.rotate(DIRECTION_LEFT, delta);
}
if (cmp.isKeyPressed(ECSA.Keys.KEY_RIGHT)) {
this.rotate(DIRECTION_RIGHT, delta);
}
if (cmp.isKeyPressed(ECSA.Keys.KEY_UP)) {
this.tryFire(absolute);
}
}
}
new ECSA.GenericComponent('view')
.setFrequency(0.1) // 1 update per 10 seconds
.doOnMessage('UNIT_EXPLODED', (cmp, msg) => playSound('SND_EXPLOSION'))
.doOnMessage('UNIT_RESPAWNED', (cmp, msg) => displayWarning(Warnings.UNIT_RESPAWNED))
.doOnUpdate((cmp, delta, absolute) => displayCurrentState())
// displays a sequence of fancy rotating texts whilst in the bonus mode
this.owner.addComponent(new ChainComponent()
.beginWhile(() => this.gameModel.mode === BONUS_LEVEL)
.beginRepeat(4)
.addComponentAndWait(() => new RotationAnimation(0,360))
.addComponentAndWait(() => new TranslateAnimation(0,0,2,2))
.execute(() => textComponent.displayMessage('BONUS 100 POINTS!!!'))
.execute(() => soundComponent.playSound('bonus'))
.endRepeat()
.endWhile()
.execute(() => viewComponent.removeAllTexts()));
// changes background music every 20 seconds
this.owner.addComponent(new ChainComponent()
.waitForMessage('GAME_STARTED')
.beginWhile(() => this.scene.stage.hasFlag(GAME_RUNNING))
.waitTime(20000)
.execute(() => this.changeBackgroundMusic())
.endWhile()