clicking, bug avoiding, removing cyclic dependencies, walk randomly

just.... lotsa stuff
This commit is contained in:
Ronja 2020-02-19 23:07:52 +01:00
parent 3259d9545a
commit 93c8bc77b0
31 changed files with 5103 additions and 92 deletions

View file

@ -13,6 +13,7 @@
"typescript": "^3.7.5", "typescript": "^3.7.5",
"webpack": "^4.41.5", "webpack": "^4.41.5",
"webpack-cli": "^3.3.10", "webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.10.2" "webpack-dev-server": "^3.10.2",
"circular-dependency-plugin": "^5.2.0"
} }
} }

View file

@ -0,0 +1,10 @@
import { Component } from "ecsy";
import { interaction } from "pixi.js";
export class Clickable extends Component {
actions: { [id: string] : (event: interaction.InteractionEvent) => void } = {}
reset(){
this.actions = {}
}
}

View file

@ -0,0 +1,3 @@
import { TagComponent } from "ecsy";
export class InitializedClickable extends TagComponent {}

View file

@ -4,8 +4,8 @@ import { Path } from "../Datatypes/path";
export class PathWalker extends Component { export class PathWalker extends Component {
path: Path path: Path
progress: number progress: number = 0
speed: number //speed in pixels per second speed: number = 10 //speed in pixels per second
reset(){ reset(){
this.path = null this.path = null

View file

@ -0,0 +1,13 @@
import { Component } from "ecsy";
import { Point } from "../../Datatypes/point";
export class DebugLine extends Component{
color = 0xFF0000
from: Point
to: Point
reset(){
this.color = 0xFF0000
}
}

View file

@ -1,5 +1,5 @@
import { Component } from "ecsy"; import { Component } from "ecsy";
import { AABB } from "../Datatypes/aabb"; import { AABB } from "../../Datatypes/aabb";
export class DebugRect extends Component{ export class DebugRect extends Component{

View file

@ -1,6 +1,6 @@
import { Texture } from "pixi.js"; import { Texture } from "pixi.js";
import { Component } from "ecsy"; import { Component } from "ecsy";
import { Vector } from "../Datatypes/vector"; import { Vector } from "../../Datatypes/vector";
//todo: consider making this a systemstatecomponent so system order isn't as critical for removing sprites //todo: consider making this a systemstatecomponent so system order isn't as critical for removing sprites
export class SpriteRenderer extends Component{ export class SpriteRenderer extends Component{

View file

@ -0,0 +1,4 @@
import { TagComponent } from "ecsy";
export class WalkRandomly extends TagComponent {}

View file

@ -0,0 +1,8 @@
export function clamp(value: number, min:number, max:number) {
return Math.min(Math.max(value, min), max)
};
export function lerp(from: number, to:number, at:number) {
return from + (to - from) * at;
};

View file

@ -1,11 +1,15 @@
import { Point } from "./point"; import { Point } from "./point";
import { clamp } from "../util"; import { clamp } from "./math";
//todo: consider caching some stuff for performance //todo: consider caching some stuff for performance
export class Path{ export class Path{
points: Point[] points: Point[]
constructor(...points : Point[]){
this.points = points
}
calculateLength(): number{ calculateLength(): number{
length = 0 length = 0
for(let i=1;i<this.points.length;i++){ for(let i=1;i<this.points.length;i++){

View file

@ -1,6 +1,6 @@
import { IPoint } from "pixi.js" import { IPoint } from "pixi.js"
import { Vector } from "./vector" import { Vector } from "./vector"
import { lerp } from "../util" import { lerp } from "./math"
// my own point I can extend however I want to, compatible with pixijs points // my own point I can extend however I want to, compatible with pixijs points
export class Point implements IPoint{ export class Point implements IPoint{
@ -17,7 +17,7 @@ export class Point implements IPoint{
} }
to(other: Point): Vector{ to(other: Point): Vector{
return new Vector(this.x - other.x, this.y - other.y) return new Vector(other.x - this.x, other.y - this.y)
} }
add(vec: Vector): Point{ add(vec: Vector): Point{

View file

@ -0,0 +1,52 @@
import { System, Entity, Not } from "ecsy"
import { PixiRepresentation } from "../Components/rendering/pixiRepresentation";
import { Clickable } from "../Components/clickable";
import { InitializedClickable } from "../Components/initializedClickable";
export class ClickableSystem extends System {
priority = 80
// This method will get called on every frame by default
execute(delta : number) {
// Iterate through all the entities on the query
this.queries.newClickables.results.forEach((entity: Entity) => {
let object = entity.getComponent(PixiRepresentation).value
let clickable = entity.getComponent(Clickable)
object.interactive = true
for(let action in clickable.actions){
object.on(action, clickable.actions[action])
}
entity.addComponent(InitializedClickable)
});
this.queries.changedClickables.changed.forEach((entity: Entity) => {
let object = entity.getComponent(PixiRepresentation).value
let clickable = entity.getComponent(Clickable)
object.removeAllListeners()
for(let action in clickable.actions){
object.on(action, clickable.actions[action])
}
});
this.queries.invisibleClickables.results.forEach((entity: Entity) => {
//remove init clickable tag so it gets initialized again as soon as a pixirepresentation exists again
entity.removeComponent(InitializedClickable)
});
}
static queries = {
newClickables: {
components: [ PixiRepresentation, Clickable, Not(InitializedClickable) ]
},
changedClickables: {
components: [ PixiRepresentation, Clickable, InitializedClickable ],
listen: {
changed: [Clickable]
}
},
invisibleClickables: {
components: [ Clickable, InitializedClickable, Not(PixiRepresentation) ],
}
}
queries: any
}

View file

@ -1,8 +1,8 @@
import { System, Entity, Not } from "ecsy" import { System, Entity, Not } from "ecsy"
import { DebugRect } from "../Components/debugRect"; import { DebugRect } from "../Components/rendering/debugRect";
import { PixiRepresentation } from "../Components/pixiRepresentation"; import { PixiRepresentation } from "../Components/rendering/pixiRepresentation";
import { Graphics, DisplayObject } from "pixi.js"; import { Graphics, DisplayObject } from "pixi.js";
import { app } from ".."; import globals from "../globals";
// MovableSystem // MovableSystem
export class DebugRenderSystem extends System { export class DebugRenderSystem extends System {
@ -16,7 +16,7 @@ export class DebugRenderSystem extends System {
let graphic = new Graphics() let graphic = new Graphics()
graphic.lineStyle(1, debugRect.color, 0.5) graphic.lineStyle(1, debugRect.color, 0.5)
graphic.drawRect(debugRect.rect.source.x, debugRect.rect.source.y, debugRect.rect.size.x, debugRect.rect.size.y) graphic.drawRect(debugRect.rect.source.x, debugRect.rect.source.y, debugRect.rect.size.x, debugRect.rect.size.y)
app.stage.addChild(graphic) globals.app.stage.addChild(graphic)
entity.addComponent(PixiRepresentation, <PixiRepresentation>{value: <DisplayObject>graphic}) entity.addComponent(PixiRepresentation, <PixiRepresentation>{value: <DisplayObject>graphic})
}) })

View file

@ -1,21 +1,20 @@
import { System, Entity } from "ecsy" import { System, Entity, Not } from "ecsy"
import { Position } from "../Components/position"; import { Position } from "../Components/position";
import { Door } from "../Components/door"; import { Door } from "../Components/door";
import { SpriteRenderer } from "../Components/spriteRenderer"; import { SpriteRenderer } from "../Components/rendering/spriteRenderer";
import { IPoint, Texture } from "pixi.js"; import { IPoint, Texture } from "pixi.js";
import { addOrSetComponent } from "../util";
// MovableSystem // MovableSystem
export class DoorSystem extends System { export class DoorSystem extends System {
// This method will get called on every frame by default // This method will get called on every frame by default
execute(delta : number) { execute(delta : number) {
// Iterate through all the entities on the query // Iterate through all the entities on the query
this.queries.newDoors.added.forEach((entity: Entity) => { this.queries.newDoors.results.forEach((entity: Entity) => {
let door = entity.getComponent(Door) let door = entity.getComponent(Door)
let doorOffset: IPoint = door.open ? door.openOffset : door.closedOffset let doorOffset: IPoint = door.open ? door.openOffset : door.closedOffset
let doorTex: Texture = door.open ? door.openTex : door.closedTex let doorTex: Texture = door.open ? door.openTex : door.closedTex
addOrSetComponent(entity, SpriteRenderer, <SpriteRenderer>{texture: doorTex, offset: doorOffset}) entity.addComponent(SpriteRenderer, <SpriteRenderer>{texture: doorTex, offset: doorOffset})
}) })
this.queries.changedDoors.changed.forEach((entity: Entity) => { this.queries.changedDoors.changed.forEach((entity: Entity) => {
@ -29,10 +28,7 @@ export class DoorSystem extends System {
static queries = { static queries = {
newDoors: { newDoors: {
components: [ Door ], components: [ Door, Not(SpriteRenderer)]
listen: {
added: true,
}
}, },
changedDoors: { changedDoors: {
components: [ Door, Position, SpriteRenderer ], components: [ Door, Position, SpriteRenderer ],

View file

@ -5,6 +5,7 @@ import { Position } from "../Components/position";
// MovableSystem // MovableSystem
export class PathWalkerSystem extends System { export class PathWalkerSystem extends System {
priority = 50
// This method will get called on every frame by default // This method will get called on every frame by default
execute(delta : number) { execute(delta : number) {
// Iterate through all the entities on the query // Iterate through all the entities on the query

View file

@ -1,8 +1,8 @@
import { PixiRepresentation } from "../Components/pixiRepresentation"; import { PixiRepresentation } from "../Components/rendering/pixiRepresentation";
import { Not, Entity, System } from "ecsy"; import { Not, Entity, System } from "ecsy";
import { DebugRect } from "../Components/debugRect"; import { DebugRect } from "../Components/rendering/debugRect";
import { SpriteRenderer } from "../Components/spriteRenderer"; import { SpriteRenderer } from "../Components/rendering/spriteRenderer";
import { app } from ".."; import globals from "../globals";
export class PixiCleanupSystem extends System { export class PixiCleanupSystem extends System {
@ -12,7 +12,7 @@ export class PixiCleanupSystem extends System {
// This method will get called on every frame by default // This method will get called on every frame by default
execute(delta : number) { execute(delta : number) {
this.queries.oldRepresentations.results.forEach((entity:Entity) => { this.queries.oldRepresentations.results.forEach((entity:Entity) => {
app.stage.removeChild(entity.getComponent(PixiRepresentation).value) globals.app.stage.removeChild(entity.getComponent(PixiRepresentation).value)
entity.removeComponent(PixiRepresentation) entity.removeComponent(PixiRepresentation)
entity.remove() entity.remove()
}); });

View file

@ -0,0 +1,28 @@
import { System, Entity, Not } from "ecsy"
import { PathWalker } from "../Components/pathWalker"
import { Position } from "../Components/position";
import { WalkRandomly } from "../Components/walkRandomly";
import { roomBounds } from "../constants";
import { Path } from "../Datatypes/path";
export class RandomWalkSystem extends System {
priority = 0
// This method will get called on every frame by default
execute(delta : number) {
// Iterate through all the entities on the query
this.queries.walkers.results.forEach((entity: Entity) => {
var pos = entity.getComponent(Position).value
var target = roomBounds.randomPoint()
var path = new Path(pos, target)
entity.addComponent(PathWalker, <PathWalker>{path: path, speed: 10})
});
}
static queries = {
walkers: {
components: [ WalkRandomly, Position, Not(PathWalker) ]
}
}
queries: any
}

View file

@ -1,5 +1,5 @@
import { System } from "ecsy" import { System } from "ecsy"
import { app } from ".."; import globals from "../globals";
// MovableSystem // MovableSystem
export class RenderSystem extends System { export class RenderSystem extends System {
@ -7,6 +7,6 @@ export class RenderSystem extends System {
// This method will get called on every frame by default // This method will get called on every frame by default
execute(_delta : number) { execute(_delta : number) {
app.renderer.render(app.stage); globals.app.renderer.render(globals.app.stage);
} }
} }

View file

@ -1,14 +1,14 @@
import { System, Entity } from "ecsy" import { System, Entity } from "ecsy";
import { Position } from "../Components/position"; import { Position } from "../Components/position";
import { SpriteRenderer } from "../Components/spriteRenderer"; import { SpriteRenderer } from "../Components/rendering/spriteRenderer";
import { app } from "..";
import { Sprite, DisplayObject } from "pixi.js"; import { Sprite, DisplayObject } from "pixi.js";
import { PixiRepresentation } from "../Components/pixiRepresentation"; import { PixiRepresentation } from "../Components/rendering/pixiRepresentation";
import { addOrSetComponent } from "../util"; import { addOrSetComponent } from "../util";
import globals from "../globals";
// MovableSystem // MovableSystem
export class SpriteSystem extends System { export class SpriteSystem extends System {
priority: 90 priority: 70
// This method will get called on every frame by default // This method will get called on every frame by default
execute(delta : number) { execute(delta : number) {
@ -21,11 +21,13 @@ export class SpriteSystem extends System {
let pos = entity.getComponent(Position) let pos = entity.getComponent(Position)
let sprite = new Sprite(renderer.texture) let sprite = new Sprite(renderer.texture)
sprite.position = pos.value.add(renderer.offset) sprite.position = pos.value.add(renderer.offset)
app.stage.addChild(sprite) globals.app.stage.addChild(sprite)
addOrSetComponent(entity, PixiRepresentation, <PixiRepresentation>{value: <DisplayObject>sprite}) addOrSetComponent(entity, PixiRepresentation, <PixiRepresentation>{value: <DisplayObject>sprite})
}) })
this.queries.sprites.changed.forEach((entity: Entity) => { this.queries.sprites.changed.forEach((entity: Entity) => {
if(!(entity as any).alive)
return
let renderer = entity.getComponent(SpriteRenderer) let renderer = entity.getComponent(SpriteRenderer)
let pos = entity.getComponent(Position) let pos = entity.getComponent(Position)
let object = entity.getComponent(PixiRepresentation).value as Sprite let object = entity.getComponent(PixiRepresentation).value as Sprite

View file

@ -1,29 +1,34 @@
import { System, Entity } from "ecsy"
import { world } from "..";
import { Human } from "../Components/human"; import { Human } from "../Components/human";
import { Name } from "../Components/name"; import { Name } from "../Components/name";
import { Appearance } from "../Components/appearance"; import { Appearance } from "../Components/appearance";
import { Loader } from "pixi.js"; import { Loader } from "pixi.js";
import { InCabin } from "../Components/inCabin"; import { InCabin } from "../Components/inCabin";
import { Position } from "../Components/position"; import { Position } from "../Components/position";
import { OrderZ } from "../Components/orderZ"; import { OrderZ } from "../Components/rendering/orderZ";
import { AABB } from "../Datatypes/aabb"; import { AABB } from "../Datatypes/aabb";
import { System, Entity } from "ecsy";
import globals from "../globals";
// MovableSystem // MovableSystem
export class TestSystem extends System { export class TestSystem extends System {
priority = -100 priority = -100
// This method will get called on every frame by default // This method will get called on every frame by default
execute(delta : number) { execute(delta : number) {
//this.removeHumans(this.queries.humans, 2)
//this.addHumans(2)
}
for(let i=0;i<1;i++){ removeHumans(query: {results: Entity[]}, amount: number): void{
let ent: Entity = this.queries.humans.results[i] for(let i=0;i<amount;i++){
let ent = query.results[i]
ent.remove() ent.remove()
} }
}
addHumans(amount: number): void{
let roomBounds = new AABB(10, 17, 62, 56) let roomBounds = new AABB(10, 17, 62, 56)
let resources = Loader.shared.resources; let resources = Loader.shared.resources
for(let i=0;i<1;i++){ for(let i=0;i<amount;i++){
world.createEntity() globals.world.createEntity()
.addComponent(Human) .addComponent(Human)
.addComponent(Name, <Name>{first: "Sarah", last:"Lee"}) .addComponent(Name, <Name>{first: "Sarah", last:"Lee"})
.addComponent(Appearance, <Appearance>{idleTexture: resources["Human"].texture}) //Todo: generate appearance from body traits instead? .addComponent(Appearance, <Appearance>{idleTexture: resources["Human"].texture}) //Todo: generate appearance from body traits instead?

View file

@ -3,7 +3,7 @@ import { Human } from "../Components/human"
import { Appearance } from "../Components/appearance" import { Appearance } from "../Components/appearance"
import { InCabin } from "../Components/inCabin" import { InCabin } from "../Components/inCabin"
import { Position } from "../Components/position" import { Position } from "../Components/position"
import { SpriteRenderer } from "../Components/spriteRenderer" import { SpriteRenderer } from "../Components/rendering/spriteRenderer"
import { Vector } from "../Datatypes/vector" import { Vector } from "../Datatypes/vector"
// MovableSystem // MovableSystem

View file

@ -1,7 +1,7 @@
import { PixiRepresentation } from "../Components/pixiRepresentation"; import { PixiRepresentation } from "../Components/rendering/pixiRepresentation";
import { Entity, System } from "ecsy"; import { Entity, System } from "ecsy";
import { Position } from "../Components/position"; import { Position } from "../Components/position";
import { OrderZ } from "../Components/orderZ"; import { OrderZ } from "../Components/rendering/orderZ";
export class ZOrderSystem extends System { export class ZOrderSystem extends System {
@ -17,6 +17,8 @@ export class ZOrderSystem extends System {
}); });
this.queries.objects.changed.forEach((entity:Entity) => { this.queries.objects.changed.forEach((entity:Entity) => {
if(!(entity as any).alive)
return
let representation = entity.getComponent(PixiRepresentation).value let representation = entity.getComponent(PixiRepresentation).value
let order = entity.getComponent(OrderZ) let order = entity.getComponent(OrderZ)
let pos = entity.getComponent(Position).value let pos = entity.getComponent(Position).value

View file

@ -1,4 +1,45 @@
export const NUM_ELEMENTS = 60 import { AABB } from "./Datatypes/aabb"
export const SPEED_MULTIPLIER = 1
export const SHAPE_SIZE = 5 export const canvasWidth = 81
export const SHAPE_HALF_SIZE = SHAPE_SIZE / 2 export const canvasHeight = 144
export const roomBounds = new AABB(10, 17, 62, 56)
export const FirstNames = [
"Jules",
"Levi",
"Sarah",
"Simon",
"Ronja",
"Marko",
"Wachter"
]
export const LastNames = [
"Adams",
"Baker",
"Clark",
"Davis",
"Evans",
"Frank",
"Ghosh",
"Hills",
"Irwin",
"Jones",
"Klein",
"Lopez",
"Mason",
"Nalty",
"Ochoa",
"Patel",
"Quinn",
"Reily",
"Smith",
"Trott",
"Usman",
"Valdo",
"White",
"Xiang",
"Yakub",
"Zafar",
]

7
Program/src/globals.ts Normal file
View file

@ -0,0 +1,7 @@
import { World } from "ecsy";
import { Application } from "pixi.js";
export default {
world: <World>null,
app: <Application>null,
}

View file

@ -1,5 +1,4 @@
import { Application, Ticker, settings, SCALE_MODES } from "pixi.js" import { Application, Ticker, settings, SCALE_MODES } from "pixi.js"
import { World } from "ecsy"
import { setup } from "./setup" import { setup } from "./setup"
import { loadResources } from "./Resources" import { loadResources } from "./Resources"
@ -13,18 +12,22 @@ import { VisibleHumanSystem } from "./Systems/VisibleHumanSystem"
import { DebugRenderSystem } from "./Systems/DebugRenderSystem" import { DebugRenderSystem } from "./Systems/DebugRenderSystem"
import { PixiCleanupSystem } from "./Systems/PixiCleanupSystem" import { PixiCleanupSystem } from "./Systems/PixiCleanupSystem"
import { ZOrderSystem } from "./Systems/ZOrderSystem" import { ZOrderSystem } from "./Systems/ZOrderSystem"
import { PathWalkerSystem } from "./Systems/PathWalkerSystem"
import { RandomWalkSystem } from "./Systems/RandomWalkSystem"
import { World } from "ecsy"
import globals from "./globals"
import { canvasWidth, canvasHeight } from "./constants"
import { ClickableSystem } from "./Systems/ClickableSystem"
// Initialize pixi // Initialize pixi
export let canvasWidth = 81 globals.app = new Application({
export let canvasHeight = 144
export const app = new Application({
width: canvasWidth, width: canvasWidth,
height: canvasHeight, height: canvasHeight,
backgroundColor: 0x000000, backgroundColor: 0x000000,
resolution: 1, resolution: 1,
antialias: false, antialias: false,
}) })
document.body.appendChild(app.view) document.body.appendChild(globals.app.view)
settings.SCALE_MODE = SCALE_MODES.NEAREST settings.SCALE_MODE = SCALE_MODES.NEAREST
settings.ROUND_PIXELS = true settings.ROUND_PIXELS = true
@ -35,19 +38,22 @@ window.addEventListener( 'resize', recalculateSize, false )
function recalculateSize(){ function recalculateSize(){
let multiplier = Math.min((window.innerWidth/canvasWidth)|0, (window.innerHeight/canvasHeight)|0) let multiplier = Math.min((window.innerWidth/canvasWidth)|0, (window.innerHeight/canvasHeight)|0)
app.view.style.width = canvasWidth * multiplier + "px" globals.app.view.style.width = canvasWidth * multiplier + "px"
app.view.style.height = canvasHeight * multiplier + "px" globals.app.view.style.height = canvasHeight * multiplier + "px"
} }
// Create world and register the systems on it // Create world and register the systems on it
//we could also register components here but they should get automatically registered once used for the first time //we could also register components here but they should get automatically registered once used for the first time
export let world = new World() globals.world = new World()
world globals.world
.registerSystem(TestSystem) //prio -100 .registerSystem(TestSystem) //prio -100
.registerSystem(AdventureReturnSystem) //prio -100 .registerSystem(AdventureReturnSystem) //prio -100
.registerSystem(DoorSystem) //prio 0 .registerSystem(DoorSystem) //prio 0
.registerSystem(RandomWalkSystem) //prio 0
.registerSystem(PathWalkerSystem) //prio 50
.registerSystem(VisibleHumanSystem) //prio 50 .registerSystem(VisibleHumanSystem) //prio 50
.registerSystem(SpriteSystem) //prio 90 .registerSystem(SpriteSystem) //prio 70
.registerSystem(ClickableSystem) //prio 80
.registerSystem(DebugRenderSystem) //prio 90 .registerSystem(DebugRenderSystem) //prio 90
.registerSystem(ZOrderSystem) //prio 98 .registerSystem(ZOrderSystem) //prio 98
.registerSystem(PixiCleanupSystem) //prio 99 .registerSystem(PixiCleanupSystem) //prio 99
@ -63,6 +69,6 @@ function init(){
Ticker.shared.add((delta : number) => { Ticker.shared.add((delta : number) => {
let time = performance.now() let time = performance.now()
// Run all the systems // Run all the systems
world.execute(delta, time) globals.world.execute(delta/100, time)
}); });
} }

View file

@ -1,14 +1,11 @@
import { Loader, Sprite } from "pixi.js"; import { Loader, Sprite } from "pixi.js";
import { app, world } from ".";
import { Door } from "./Components/door"; import { Door } from "./Components/door";
import { Human } from "./Components/human"; import { DebugRect } from "./Components/rendering/debugRect";
import { Name } from "./Components/name"; import { roomBounds } from "./constants";
import { InCabin } from "./Components/inCabin"; import globals from "./globals";
import { Appearance } from "./Components/appearance"; import { createRandomHuman } from "./util";
import { Position } from "./Components/position"; import { Position } from "./Components/position";
import { AABB } from "./Datatypes/aabb"; import { Point } from "./Datatypes/point";
import { DebugRect } from "./Components/debugRect";
import { OrderZ } from "./Components/orderZ";
export function setup(){ export function setup(){
@ -16,28 +13,23 @@ export function setup(){
//base sprites without entity representation //base sprites without entity representation
const bgTex = new Sprite(resources["Background"].texture) const bgTex = new Sprite(resources["Background"].texture)
app.stage.addChild(bgTex) globals.app.stage.addChild(bgTex)
//start entities //start entities
//door //door
world.createEntity() globals.world.createEntity()
.addComponent(Position, <Position>{value: new Point(38, 2)})
.addComponent(Door, <Door>{open: true, .addComponent(Door, <Door>{open: true,
openOffset: {x:38, y:2}, openTex: resources["Door"].spritesheet.textures[0], openOffset: {x:0, y:0}, openTex: resources["Door"].spritesheet.textures[0],
closedOffset: {x:38, y:2}, closedTex: resources["Door"].spritesheet.textures[1]}) closedOffset: {x:0, y:0}, closedTex: resources["Door"].spritesheet.textures[1]})
//debug room bounds
globals.world.createEntity()
.addComponent(DebugRect, <DebugRect>{color:0x0000FF, rect: roomBounds})
//example humans //example humans
//TODO delete those //TODO delete those
let roomBounds = new AABB(10, 17, 62, 56)
world.createEntity()
.addComponent(DebugRect, <DebugRect>{color:0x0000FF, rect: roomBounds})
for(let i=0;i<10;i++) for(let i=0;i<10;i++)
world.createEntity() createRandomHuman(globals.world)
.addComponent(Human)
.addComponent(Name, <Name>{first: "Sarah", last:"Lee"})
.addComponent(Appearance, <Appearance>{idleTexture: resources["Human"].texture}) //Todo: generate appearance from body traits instead?
.addComponent(InCabin)
.addComponent(Position, <Position>{value: roomBounds.randomPoint()})
.addComponent(OrderZ)
} }

View file

@ -1,4 +1,14 @@
import { Entity, ComponentConstructor, Component } from "ecsy" import { Entity, ComponentConstructor, Component, World } from "ecsy"
import { Loader, interaction } from "pixi.js"
import { Human } from "./Components/human"
import { Name } from "./Components/name"
import { Appearance } from "./Components/appearance"
import { InCabin } from "./Components/inCabin"
import { OrderZ } from "./Components/rendering/orderZ"
import { WalkRandomly } from "./Components/walkRandomly"
import { Position } from "./Components/position"
import { roomBounds } from "./constants"
import { Clickable } from "./Components/clickable"
export function addOrSetComponent(entity: Entity, Component: ComponentConstructor<Component>, values: any) { export function addOrSetComponent(entity: Entity, Component: ComponentConstructor<Component>, values: any) {
@ -8,7 +18,7 @@ export function addOrSetComponent(entity: Entity, Component: ComponentConstructo
if(component.copy){ if(component.copy){
component.copy(values) component.copy(values)
} else { } else {
for (var name in values) { for (let name in values) {
component[name]= values[name] component[name]= values[name]
} }
} }
@ -18,10 +28,22 @@ export function addOrSetComponent(entity: Entity, Component: ComponentConstructo
} }
} }
export function clamp(value: number, min:number, max:number) { export function randomArrayValue(array: any[]):any{
return Math.min(Math.max(value, min), max) let randomIndex = Math.random() * array.length
}; return array[randomIndex]
}
export function lerp(from: number, to:number, at:number) { export function createRandomHuman(world: World){
return from + (to - from) * at; let resources = Loader.shared.resources;
}; let entity = world.createEntity()
entity
.addComponent(Human)
.addComponent(Name, <Name>{first: "mary", last:"sue"})
.addComponent(Appearance, <Appearance>{idleTexture: resources["Human"].texture}) //Todo: generate appearance from body traits instead?
.addComponent(InCabin)
.addComponent(Position, <Position>{value: roomBounds.randomPoint()})
.addComponent(OrderZ)
.addComponent(WalkRandomly)
//todo: change this into selecing the human instead of killing it...
.addComponent(Clickable, { actions: { "click": (event: interaction.InteractionEvent) => {entity.remove();} }})
}

View file

@ -1,5 +1,6 @@
const path = require('path'); const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin');
const CircularDependencyPlugin = require('circular-dependency-plugin')
module.exports = { module.exports = {
context: __dirname, context: __dirname,
@ -22,5 +23,18 @@ module.exports = {
template: "index.html", template: "index.html",
title: "Cabin Game", title: "Cabin Game",
}), }),
new CircularDependencyPlugin({
// exclude detection of files based on a RegExp
exclude: /a\.js|node_modules/,
// include specific files based on a RegExp
include: /src/,
// add errors to webpack instead of warnings
failOnError: true,
// allow import cycles that include an asyncronous import,
// e.g. via import(/* webpackMode: "weak" */ './file.js')
allowAsyncCycles: false,
// set the current working directory for displaying module paths
cwd: process.cwd(),
})
], ],
} }

4800
Program/yarn.lock Normal file

File diff suppressed because it is too large Load diff