diff --git a/Assets/Background.aseprite b/Assets/Background.aseprite index 33312e2..433a27d 100644 Binary files a/Assets/Background.aseprite and b/Assets/Background.aseprite differ diff --git a/Assets/Door.aseprite b/Assets/Door.aseprite new file mode 100644 index 0000000..40b5f8c Binary files /dev/null and b/Assets/Door.aseprite differ diff --git a/Assets/Door.json b/Assets/Door.json new file mode 100644 index 0000000..c3f52ac --- /dev/null +++ b/Assets/Door.json @@ -0,0 +1,33 @@ +{ "frames": [ + { + "filename": "Door 0.aseprite", + "frame": { "x": 0, "y": 0, "w": 21, "h": 23 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 21, "h": 23 }, + "sourceSize": { "w": 21, "h": 23 }, + "duration": 100 + }, + { + "filename": "Door 1.aseprite", + "frame": { "x": 21, "y": 0, "w": 21, "h": 23 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 21, "h": 23 }, + "sourceSize": { "w": 21, "h": 23 }, + "duration": 100 + } + ], + "meta": { + "app": "http://www.aseprite.org/", + "version": "1.2.16.3-x64", + "image": "Door.png", + "format": "RGBA8888", + "size": { "w": 42, "h": 23 }, + "scale": "1", + "frameTags": [ + ], + "slices": [ + ] + } +} diff --git a/Assets/Human.aseprite b/Assets/Human.aseprite new file mode 100644 index 0000000..617a3c4 Binary files /dev/null and b/Assets/Human.aseprite differ diff --git a/Assets/Mockup.aseprite b/Assets/Mockup.aseprite new file mode 100644 index 0000000..b1222d2 Binary files /dev/null and b/Assets/Mockup.aseprite differ diff --git a/Program/assets/Background.png b/Program/assets/Background.png new file mode 100644 index 0000000..177f7d0 Binary files /dev/null and b/Program/assets/Background.png differ diff --git a/Program/assets/Door.json b/Program/assets/Door.json new file mode 100644 index 0000000..eeb70da --- /dev/null +++ b/Program/assets/Door.json @@ -0,0 +1,33 @@ +{ "frames": [ + { + "filename": "Door 0", + "frame": { "x": 0, "y": 0, "w": 21, "h": 23 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 21, "h": 23 }, + "sourceSize": { "w": 21, "h": 23 }, + "duration": 100 + }, + { + "filename": "Door 1", + "frame": { "x": 21, "y": 0, "w": 21, "h": 23 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 21, "h": 23 }, + "sourceSize": { "w": 21, "h": 23 }, + "duration": 100 + } + ], + "meta": { + "app": "http://www.aseprite.org/", + "version": "1.2.16.3-x64", + "image": "Door.png", + "format": "RGBA8888", + "size": { "w": 42, "h": 23 }, + "scale": "1", + "frameTags": [ + ], + "slices": [ + ] + } +} diff --git a/Program/assets/Door.png b/Program/assets/Door.png new file mode 100644 index 0000000..e4d8725 Binary files /dev/null and b/Program/assets/Door.png differ diff --git a/Program/assets/Human.png b/Program/assets/Human.png new file mode 100644 index 0000000..6295155 Binary files /dev/null and b/Program/assets/Human.png differ diff --git a/src/assets/bunny.png b/Program/assets/bunny.png similarity index 100% rename from src/assets/bunny.png rename to Program/assets/bunny.png diff --git a/src/index.html b/Program/index.html similarity index 79% rename from src/index.html rename to Program/index.html index a77ae77..2f780cd 100644 --- a/src/index.html +++ b/Program/index.html @@ -1,7 +1,7 @@ - Hello! + <%= htmlWebpackPlugin.options.title %> @@ -10,7 +10,7 @@ margin: 0; padding: 0; } - + canvas { image-rendering: -moz-crisp-edges; image-rendering: -webkit-crisp-edges; @@ -18,9 +18,7 @@ image-rendering: crisp-edges; } - - \ No newline at end of file diff --git a/Program/package.json b/Program/package.json new file mode 100644 index 0000000..fa0111b --- /dev/null +++ b/Program/package.json @@ -0,0 +1,18 @@ +{ + "scripts": { + "start": "webpack-dev-server -w", + "build": "rm -rf dist && webpack --config ./webpack.config.js --mode production --progress --colors" + }, + "dependencies": { + "ecsy": "^0.2.2", + "pixi.js": "^5.2.1" + }, + "devDependencies": { + "html-webpack-plugin": "^3.2.0", + "ts-loader": "^6.2.1", + "typescript": "^3.7.5", + "webpack": "^4.41.5", + "webpack-cli": "^3.3.10", + "webpack-dev-server": "^3.10.2" + } +} diff --git a/Program/src/Components/door.ts b/Program/src/Components/door.ts new file mode 100644 index 0000000..af776d3 --- /dev/null +++ b/Program/src/Components/door.ts @@ -0,0 +1,24 @@ +import { Point } from "../Datatypes/point" +import { Texture } from "pixi.js" + + +// Door component +export class Door { + open: boolean + + openPosition: Point + closedPosition: Point + + openTex: Texture + closedTex: Texture + + reset() { + this.open = false + + this.openPosition = null + this.closedPosition = null + + this.openTex = null + this.closedTex = null + } +} \ No newline at end of file diff --git a/Program/src/Components/position.ts b/Program/src/Components/position.ts new file mode 100644 index 0000000..a22124c --- /dev/null +++ b/Program/src/Components/position.ts @@ -0,0 +1,10 @@ +import { Point } from "../Datatypes/point" + +// Position component +export class Position { + value: Point + + reset() { + this.value = new Point(0, 0) + } +} \ No newline at end of file diff --git a/Program/src/Components/shape.ts b/Program/src/Components/shape.ts new file mode 100644 index 0000000..0dfab3d --- /dev/null +++ b/Program/src/Components/shape.ts @@ -0,0 +1,10 @@ +// Shape component +export class Shape { + onStage = false + shape: PIXI.Graphics + + reset() { + this.onStage = false + this.shape = null + } +} \ No newline at end of file diff --git a/Program/src/Components/spriteRenderer.ts b/Program/src/Components/spriteRenderer.ts new file mode 100644 index 0000000..8b2f94d --- /dev/null +++ b/Program/src/Components/spriteRenderer.ts @@ -0,0 +1,9 @@ +import { Sprite } from "pixi.js"; + +export class SpriteRenderer{ + sprite: Sprite + + reset() :void { + this.sprite = null + } +} \ No newline at end of file diff --git a/Program/src/Components/velocity.ts b/Program/src/Components/velocity.ts new file mode 100644 index 0000000..5681b93 --- /dev/null +++ b/Program/src/Components/velocity.ts @@ -0,0 +1,10 @@ +import { Vector } from "../Datatypes/vector" + +// Velocity component +export class Velocity { + value: Vector + + reset() { + this.value = new Vector(0, 0) + } +} \ No newline at end of file diff --git a/Program/src/Datatypes/point.ts b/Program/src/Datatypes/point.ts new file mode 100644 index 0000000..c90833b --- /dev/null +++ b/Program/src/Datatypes/point.ts @@ -0,0 +1,39 @@ +import { IPoint } from "pixi.js" +import { Vector } from "./vector" + +// my own point I can extend however I want to, compatible with pixijs points +export class Point implements IPoint{ + x: number + y: number + + constructor(x: number, y: number){ + this.x = x + this.y = y + } + + to(other: Point): Vector{ + return new Vector(this.x - other.x, this.y - other.y) + } + + add(vec: Vector): Point{ + return this.set(vec.x, vec.y) + } + + set(x?: number, y?: number): this { + if (x !== undefined) + this.x = x + if (y !== undefined) + this.y = y + return this + } + copyFrom(p: IPoint): this { + return this.set(p.x, p.y) + } + copyTo(p: IPoint): IPoint { + p.set(this.x, this.y) + return p + } + equals(p: IPoint): boolean { + return this.x === p.x && this.y === p.y + } +} \ No newline at end of file diff --git a/Program/src/Datatypes/vector.ts b/Program/src/Datatypes/vector.ts new file mode 100644 index 0000000..093d1bc --- /dev/null +++ b/Program/src/Datatypes/vector.ts @@ -0,0 +1,53 @@ +import { IPoint } from "pixi.js" + +// my own point I can extend however I want to, compatible with pixijs points +export class Vector implements IPoint{ + x: number + y: number + + constructor(x: number, y: number){ + this.x = x + this.y = y + } + + normalize(): this { + let len = this.length() + if(len < 0.001){ + this.set(0, 0) + } else { + this.scale(1/len) + } + return this + } + + length(): number { + return Math.sqrt(this.x*this.x + this.y*this.y) + } + + scale(scalar: number): this { + this.set(this.x*scalar, this.y*scalar) + return this + } + + scaled(scalar: number): Vector { + return new Vector(this.x * scalar, this.y * scalar) + } + + set(x?: number, y?: number): void { + if (x !== undefined) + this.x = x + if (y !== undefined) + this.y = y + } + copyFrom(p: IPoint): this { + this.set(p.x, p.y) + return this + } + copyTo(p: IPoint): IPoint { + p.set(this.x, this.y) + return p + } + equals(p: IPoint): boolean { + return this.x === p.x && this.y === p.y + } +} \ No newline at end of file diff --git a/Program/src/Systems/DoorSystem.ts b/Program/src/Systems/DoorSystem.ts new file mode 100644 index 0000000..d148839 --- /dev/null +++ b/Program/src/Systems/DoorSystem.ts @@ -0,0 +1,48 @@ +import { System, Entity } from "ecsy" +import { Position } from "../Components/position"; +import { Door } from "../Components/door"; +import { SpriteRenderer } from "../Components/spriteRenderer"; +import { IPoint, Texture, Sprite } from "pixi.js"; +import { addOrSetComponent } from "../util"; + +// MovableSystem +export class DoorSystem extends System { + // This method will get called on every frame by default + execute(delta : number) { + // Iterate through all the entities on the query + this.queries.newDoors.added.forEach((entity: Entity) => { + let door = entity.getComponent(Door) + + let doorPos: IPoint = door.open ? door.openPosition : door.closedPosition + addOrSetComponent(entity, Position, {value: doorPos}) + + let doorTex: Texture = door.open ? door.openTex : door.closedTex + addOrSetComponent(entity, SpriteRenderer, {sprite: new Sprite(doorTex)}) + }) + + this.queries.changedDoors.changed.forEach((entity: Entity) => { + let door = entity.getComponent(Door) + let pos = entity.getMutableComponent(Position) + let renderer = entity.getMutableComponent(SpriteRenderer) + + pos.value = door.open ? door.openPosition : door.closedPosition + renderer.sprite.texture = door.open ? door.openTex : door.closedTex + }) + } + + static queries = { + newDoors: { + components: [ Door ], + listen: { + added: true, + } + }, + changedDoors: { + components: [ Door, Position, SpriteRenderer ], + listen: { + changed: [ Door ], + } + } + } + queries: any; +} \ No newline at end of file diff --git a/Program/src/Systems/MovableSystem.ts b/Program/src/Systems/MovableSystem.ts new file mode 100644 index 0000000..e7c07a1 --- /dev/null +++ b/Program/src/Systems/MovableSystem.ts @@ -0,0 +1,31 @@ +import { System, Entity } from "ecsy" +import { canvasWidth, canvasHeight } from ".."; +import { Velocity } from "../Components/velocity"; +import { Position } from "../Components/position"; +import { SHAPE_HALF_SIZE } from "../constants"; + +// MovableSystem +export class MovableSystem extends System { + // This method will get called on every frame by default + execute(delta : number) { + // Iterate through all the entities on the query + this.queries.moving.results.forEach((entity: Entity) => { + var velocity = entity.getComponent(Velocity); + var position = entity.getMutableComponent(Position); + //if this system breaks, this is the error: scale might change the base component + position.value.add(velocity.value.scaled(delta)) + + if (position.value.x > canvasWidth + SHAPE_HALF_SIZE) position.value.x = - SHAPE_HALF_SIZE; + if (position.value.x < - SHAPE_HALF_SIZE) position.value.x = canvasWidth + SHAPE_HALF_SIZE; + if (position.value.y > canvasHeight + SHAPE_HALF_SIZE) position.value.y = - SHAPE_HALF_SIZE; + if (position.value.y < - SHAPE_HALF_SIZE) position.value.y = canvasHeight + SHAPE_HALF_SIZE; + }); + } + + static queries = { + moving: { + components: [Velocity, Position] + } + } + queries: any; +} \ No newline at end of file diff --git a/Program/src/Systems/RenderSystem.ts b/Program/src/Systems/RenderSystem.ts new file mode 100644 index 0000000..1da43d5 --- /dev/null +++ b/Program/src/Systems/RenderSystem.ts @@ -0,0 +1,12 @@ +import { System } from "ecsy" +import { app } from ".."; + +// MovableSystem +export class RenderSystem extends System { + priority: 100 + + // This method will get called on every frame by default + execute(_delta : number) { + app.renderer.render(app.stage); + } +} \ No newline at end of file diff --git a/Program/src/Systems/ShapeRenderSystem.ts b/Program/src/Systems/ShapeRenderSystem.ts new file mode 100644 index 0000000..5184f47 --- /dev/null +++ b/Program/src/Systems/ShapeRenderSystem.ts @@ -0,0 +1,36 @@ +import { System, Entity } from "ecsy"; +import { app } from ".."; +import { Position } from "../Components/position"; +import { Shape } from "../Components/shape"; + +// RendererSystem +export class ShapeRenderSystem extends System { + static queries = { + renderables: { + components: [Position, Shape], + } + }; + + queries: any; + + // This method will get called on every frame by default + execute(delta : number) { + + // Iterate through all the entities on the query + this.queries.renderables.results.forEach((entity: Entity) => { + var shape = entity.getComponent(Shape); + var position = entity.getComponent(Position); + this.drawShape(position, shape); + }); + } + + drawShape(position : Position, shape : Shape) { + if(!shape.onStage){ + app.stage.addChild(shape.shape); + shape.onStage = true; + } + + shape.shape.x = position.value.x; + shape.shape.y = position.value.y; + } +} \ No newline at end of file diff --git a/Program/src/Systems/SpriteSystem.ts b/Program/src/Systems/SpriteSystem.ts new file mode 100644 index 0000000..5367158 --- /dev/null +++ b/Program/src/Systems/SpriteSystem.ts @@ -0,0 +1,43 @@ +import { System, Entity } from "ecsy" +import { Position } from "../Components/position"; +import { SpriteRenderer } from "../Components/spriteRenderer"; +import { app } from ".."; + +// MovableSystem +export class SpriteSystem extends System { + priority: 90 + + // This method will get called on every frame by default + execute(delta : number) { + // Iterate through all the entities on the query + this.queries.sprites.added.forEach((entity: Entity) => { + let renderer = entity.getMutableComponent(SpriteRenderer) + let pos = entity.getComponent(Position) + renderer.sprite.position = pos.value + app.stage.addChild(renderer.sprite) + }) + + this.queries.sprites.removed.forEach((entity: Entity) => { + let renderer = entity.getRemovedComponent(SpriteRenderer) + app.stage.removeChild(renderer.sprite) + }) + + this.queries.sprites.changed.forEach((entity: Entity) => { + let renderer = entity.getMutableComponent(SpriteRenderer) + let pos = entity.getComponent(Position) + renderer.sprite.position = pos.value; + }) + } + + static queries = { + sprites: { + components: [ SpriteRenderer, Position ], + listen: { + added: true, + removed: true, + changed: [ Position ] + } + }, + } + queries: any; +} \ No newline at end of file diff --git a/Program/src/Systems/TestSystem.ts b/Program/src/Systems/TestSystem.ts new file mode 100644 index 0000000..86d4506 --- /dev/null +++ b/Program/src/Systems/TestSystem.ts @@ -0,0 +1,21 @@ +import { System, Entity } from "ecsy" +import { Door } from "../Components/door"; + +// MovableSystem +export class TestSystem extends System { + priority = -100 + // This method will get called on every frame by default + execute(delta : number) { + // Iterate through all the entities on the query + this.queries.doors.results.forEach((entity: Entity) => { + //entity.getMutableComponent(Door).open = Math.random() > 0.5 //violently vibrate door + }) + } + + static queries = { + doors: { + components: [ Door ] + }, + } + queries: any; +} \ No newline at end of file diff --git a/Program/src/constants.ts b/Program/src/constants.ts new file mode 100644 index 0000000..36fdec1 --- /dev/null +++ b/Program/src/constants.ts @@ -0,0 +1,4 @@ +export const NUM_ELEMENTS = 60 +export const SPEED_MULTIPLIER = 1 +export const SHAPE_SIZE = 5 +export const SHAPE_HALF_SIZE = SHAPE_SIZE / 2 \ No newline at end of file diff --git a/Program/src/index.ts b/Program/src/index.ts new file mode 100644 index 0000000..2d8e57b --- /dev/null +++ b/Program/src/index.ts @@ -0,0 +1,65 @@ +import { loadResources } from "./Resources" +import { Door } from "./Components/door" +import { DoorSystem } from "./Systems/DoorSystem" +import { SpriteSystem } from "./Systems/SpriteSystem" +import { Application, Ticker, settings, SCALE_MODES, Sprite, Loader } from "pixi.js" +import { World } from "ecsy" +import { RenderSystem } from "./Systems/RenderSystem" +import { TestSystem } from "./Systems/TestSystem" + +// Initialize pixi +export let canvasWidth = 81 +export let canvasHeight = 81 +export const app = new Application({ + width: canvasWidth, + height: canvasHeight, + backgroundColor: 0xFFFFFF, + resolution: 1, + antialias: false, +}) +document.body.appendChild(app.view) + +settings.SCALE_MODE = SCALE_MODES.NEAREST +settings.ROUND_PIXELS = true + +recalculateSize() + +window.addEventListener( 'resize', recalculateSize, false ) + +function recalculateSize(){ + let multiplier = Math.min((window.innerWidth/canvasWidth)|0, (window.innerHeight/canvasHeight)|0) + app.view.style.width = canvasWidth * multiplier + "px" + app.view.style.height = canvasHeight * multiplier + "px" +} + +// Create world and register the systems on it +export let world = new World(); +world + .registerSystem(TestSystem) //prio -100 + .registerSystem(DoorSystem) //prio 0 + .registerSystem(SpriteSystem) //prio 90 + .registerSystem(RenderSystem) //prio 100 + + +loadResources(init) + +function init(){ + let resources = Loader.shared.resources; + + //base sprites without entity representation + const bgTex = new Sprite(resources["Background"].texture) + app.stage.addChild(bgTex) + + //start entities + world.createEntity() + .addComponent(Door, {open: false, + openPosition: {x:38, y:2}, openTex: resources["Door"].spritesheet.textures[0], + closedPosition: {x:38, y:2}, closedTex: resources["Door"].spritesheet.textures[1]}) + + // Run! + Ticker.shared.add((delta : number) => { + let time = performance.now() + // Run all the systems + world.execute(delta, time) + }); +} diff --git a/Program/src/random.ts b/Program/src/random.ts new file mode 100644 index 0000000..193be8a --- /dev/null +++ b/Program/src/random.ts @@ -0,0 +1,45 @@ +import { Velocity } from "./Components/velocity" +import { Position } from "./Components/position" + +import { Vector } from "./Datatypes/vector" + +import { canvasWidth, canvasHeight } from "." +import { Point } from "./Datatypes/point" +import { SHAPE_HALF_SIZE, SHAPE_SIZE } from "./constants" + +// Some helper functions when creating the components +function getRandomVelocity(speedMultiplier: number): Velocity { + return { + value: new Vector( + speedMultiplier * (2 * Math.random() - 1), + speedMultiplier * (2 * Math.random() - 1) + ) + } +} + +function getRandomPosition(): Position{ + return { + value: new Point( + Math.random() * canvasWidth, + Math.random() * canvasHeight + ) + } +} + + +function getRandomShape() { + let graphics = new PIXI.Graphics() + if(Math.random() >= 0.5) { + graphics.beginFill(0x888888) + graphics.lineStyle(1, 0x222222) + graphics.drawCircle(0, 0, SHAPE_HALF_SIZE) + } else { + graphics.beginFill(0xf28d89) + graphics.lineStyle(1, 0x800904) + graphics.drawRect(-SHAPE_HALF_SIZE, -SHAPE_HALF_SIZE, SHAPE_SIZE, SHAPE_SIZE) + } + + return { + shape: graphics + } +} \ No newline at end of file diff --git a/Program/src/resources.ts b/Program/src/resources.ts new file mode 100644 index 0000000..366ebe3 --- /dev/null +++ b/Program/src/resources.ts @@ -0,0 +1,13 @@ +import { Loader } from "pixi.js" + + +export function loadResources(init: Function){ + Loader.shared.add("Door", "assets/Door.json") + .add("Background", "assets/Background.png") + .add("Human", "assets/Human.png") + .load(setup) + + function setup(loader: Loader){ + init() + } +} \ No newline at end of file diff --git a/Program/src/util.ts b/Program/src/util.ts new file mode 100644 index 0000000..32f5e43 --- /dev/null +++ b/Program/src/util.ts @@ -0,0 +1,19 @@ +import { Entity, ComponentConstructor, Component } from "ecsy"; + + +export function addOrSetComponent(entity: Entity, Component: ComponentConstructor, values: object) { + if(entity.hasComponent(Component)){ + //component exists, copy values into it + let component: any = entity.getMutableComponent(Component) + if(component.copy){ + component.copy(values) + } else { + for (var name in values) { + component[name] = values[name]; + } + } + } else { + //component doesn't exist, add new one + entity.addComponent(Component, values) + } +} \ No newline at end of file diff --git a/Program/style.css b/Program/style.css new file mode 100644 index 0000000..5f6da28 --- /dev/null +++ b/Program/style.css @@ -0,0 +1,11 @@ +html, body { + margin: 0; + padding: 0; +} + +canvas { + image-rendering: -moz-crisp-edges; + image-rendering: -webkit-crisp-edges; + image-rendering: pixelated; + image-rendering: crisp-edges; +} \ No newline at end of file diff --git a/Program/tsconfig.json b/Program/tsconfig.json new file mode 100644 index 0000000..4e510b3 --- /dev/null +++ b/Program/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "sourceMap": true, + "target": "es6", + "moduleResolution": "Node" + } +} \ No newline at end of file diff --git a/Program/webpack.config.js b/Program/webpack.config.js new file mode 100644 index 0000000..9f4ff42 --- /dev/null +++ b/Program/webpack.config.js @@ -0,0 +1,26 @@ +const path = require('path'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); + +module.exports = { + context: __dirname, + entry: './src/index.ts', + mode: 'development', + module: { + rules: [ + { + test: /\.ts?$/, + exclude: /node_modules/, + use: 'ts-loader', + }, + ] + }, + resolve: { + extensions: ['.ts', '.js'] + }, + plugins: [ + new HtmlWebpackPlugin({ + template: "index.html", + title: "Cabin Game", + }), + ], +} \ No newline at end of file diff --git a/src/assets/Background.png b/src/assets/Background.png deleted file mode 100644 index 6b6d494..0000000 Binary files a/src/assets/Background.png and /dev/null differ diff --git a/src/game.ts b/src/game.ts deleted file mode 100644 index 7746f2e..0000000 --- a/src/game.ts +++ /dev/null @@ -1,182 +0,0 @@ -import * as PIXI from "pixi.js" -import * as ECSY from "ecsy" -import { Entity } from "ecsy"; - -const NUM_ELEMENTS = 60; -const SPEED_MULTIPLIER = 1; -const SHAPE_SIZE = 10; -const SHAPE_HALF_SIZE = SHAPE_SIZE / 2; - -// Initialize pixi -let canvasWidth = 81; -let canvasHeight = 144; -const app = new PIXI.Application({ - width: canvasWidth, - height: canvasHeight, - backgroundColor: 0xFFFFFF, - resolution: 1, - antialias: false, -}); -document.body.appendChild(app.view); - -PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST; -PIXI.settings.ROUND_PIXELS = true; - -recalculateSize(); - -window.addEventListener( 'resize', recalculateSize, false ); - -function recalculateSize(){ - let multiplier = Math.min(0, 0); - app.view.style.width = canvasWidth + "px"; - app.view.style.height = "720px"; -} - -const bgTex = PIXI.Sprite.from('../assets/Background.png'); -app.stage.addChild(bgTex); - -//---------------------- -// Components -//---------------------- - -// Velocity component -class Velocity { - x = 0; - y = 0; -} - -// Position component -class Position { - x = 0; - y = 0; -} - -// Shape component -class Shape { - onStage = false - shape: PIXI.Graphics -} - -// Renderable component -class Renderable extends ECSY.TagComponent {} - -//---------------------- -// Systems -//---------------------- - -// MovableSystem -class MovableSystem extends ECSY.System { - // This method will get called on every frame by default - execute(delta : number) { - // Iterate through all the entities on the query - MovableSystem.queries.moving.results.forEach((entity: Entity) => { - var velocity = entity.getComponent(Velocity); - var position = entity.getMutableComponent(Position); - position.x += velocity.x * delta; - position.y += velocity.y * delta; - - if (position.x > canvasWidth + SHAPE_HALF_SIZE) position.x = - SHAPE_HALF_SIZE; - if (position.x < - SHAPE_HALF_SIZE) position.x = canvasWidth + SHAPE_HALF_SIZE; - if (position.y > canvasHeight + SHAPE_HALF_SIZE) position.y = - SHAPE_HALF_SIZE; - if (position.y < - SHAPE_HALF_SIZE) position.y = canvasHeight + SHAPE_HALF_SIZE; - }); - } - - static queries = { - moving: { - components: [Velocity, Position], - results: [] - } - } -} - - -// RendererSystem -class RendererSystem extends ECSY.System { - // This method will get called on every frame by default - execute(delta : number) { - - // Iterate through all the entities on the query - RendererSystem.queries.renderables.results.forEach((entity: Entity) => { - var shape = entity.getComponent(Shape); - var position = entity.getComponent(Position); - this.drawShape(position, shape); - }); - - //app.renderer.render(app.stage); - } - - drawShape(position : Position, shape : Shape) { - if(!shape.onStage){ - app.stage.addChild(shape.shape); - shape.onStage = true; - } - - shape.shape.x = position.x; - shape.shape.y = position.y; - } - - static queries = { - renderables: { - components: [Renderable, Shape], - results: [] - } - } -} - - -// Create world and register the systems on it -var world = new ECSY.World(); -world - .registerSystem(MovableSystem) - .registerSystem(RendererSystem); - -// Some helper functions when creating the components -function getRandomVelocity() { - return { - x: SPEED_MULTIPLIER * (2 * Math.random() - 1), - y: SPEED_MULTIPLIER * (2 * Math.random() - 1) - }; -} - -function getRandomPosition(){ - return { - x: Math.random() * canvasWidth, - y: Math.random() * canvasHeight - }; -} - - -function getRandomShape() { - let graphics = new PIXI.Graphics(); - if(Math.random() >= 0.5) { - graphics.beginFill(0x888888); - graphics.lineStyle(1, 0x222222); - graphics.drawCircle(0, 0, SHAPE_HALF_SIZE); - } else { - graphics.beginFill(0xf28d89); - graphics.lineStyle(1, 0x800904); - graphics.drawRect(-SHAPE_HALF_SIZE, -SHAPE_HALF_SIZE, SHAPE_SIZE, SHAPE_SIZE); - } - - return { - shape: graphics - }; -} - -for (let i = 0; i < NUM_ELEMENTS; i++) { - world - .createEntity() - .addComponent(Velocity, getRandomVelocity()) - .addComponent(Shape, getRandomShape()) - .addComponent(Position, getRandomPosition()) - .addComponent(Renderable) -} - -let time = 0 -// Run! -PIXI.Ticker.shared.add((delta : number) => { - time += delta; - // Run all the systems - world.execute(delta, time); -}); \ No newline at end of file diff --git a/src/package.json b/src/package.json deleted file mode 100644 index d51fc54..0000000 --- a/src/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "devDependencies": { - "typescript": "^3.7.5" - }, - "dependencies": { - "ecsy": "^0.2.2", - "pixi.js": "^5.2.1" - } -} diff --git a/src/tsconfig.json b/src/tsconfig.json deleted file mode 100644 index c919fc6..0000000 --- a/src/tsconfig.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "ES6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation. */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "checkJs": true, /* Report errors in .js files. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "lib", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "composite": true, /* Enable project compilation */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - // "strict": true, /* Enable all strict type-checking options. */ - "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - "strictNullChecks": true, /* Enable strict null checks. */ - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - - /* Source Map Options */ - // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - - /* Advanced Options */ - // "declarationDir": "lib" /* Output directory for generated declaration files. */ - } -}