From 4f4fbfb2eb55a1f4c8c792f4820fe6e133318d5d Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Sat, 9 Dec 2023 16:27:19 +0300 Subject: [PATCH 01/41] [datastructures] New methods `IndexedList.get()` and `IndexedList.set()` #new --- .gitignore | 3 ++- src/dataStructures/indexedList.js | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index b29a32a4..dd59b87f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ res.json *.mp3 tests *.res.js -*.txt \ No newline at end of file +*.txt +demos \ No newline at end of file diff --git a/src/dataStructures/indexedList.js b/src/dataStructures/indexedList.js index b81487c2..67ef809b 100644 --- a/src/dataStructures/indexedList.js +++ b/src/dataStructures/indexedList.js @@ -4,7 +4,7 @@ export class IndexedList { get(name){ return this._list[this._keys.get(name)] } - push(name, value) { + set(name, value) { this._keys.set(name,this._list.length) this._list.push(value) } @@ -15,6 +15,9 @@ export class IndexedList { ) this._keys.delete(name) } + keys(){ + return this._keys.keys() + } values() { return this._list } From 85f57b0e8df025d485f31eb50f65b9ca92ca7b73 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Sat, 9 Dec 2023 17:33:26 +0300 Subject: [PATCH 02/41] [demos] refactored code#refactor --- .gitignore | 3 +-- demos/index.js | 11 ++++++----- demos/main.js | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index dd59b87f..b29a32a4 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,4 @@ res.json *.mp3 tests *.res.js -*.txt -demos \ No newline at end of file +*.txt \ No newline at end of file diff --git a/demos/index.js b/demos/index.js index 42bc5d29..bdf9c4a6 100644 --- a/demos/index.js +++ b/demos/index.js @@ -31,7 +31,8 @@ import { fpsDebugger, bodyDebugger, Entity, - Intergrator + Intergrator, + IndexedList } from "/src/index.js" function createBoundingBox(x, y, w, h, t = 20) { @@ -86,7 +87,7 @@ export const demos = { renderer: new Renderer2D(), world: new World(), tweenManager:new TweenManager(), - examples: {}, + examples: new IndexedList, init: function(selector) { this.manager.registerSystem("agent", new AgentManager()) this.manager.registerSystem("renderer", this.renderer) @@ -95,7 +96,7 @@ export const demos = { this.manager.registerSystem("movable",new Intergrator()) let renderer = this.renderer renderer.bindTo(selector) - renderer.setViewport(innerWidth, innerHeight / 1.5) + renderer.setViewport(innerWidth, innerHeight * 0.5) window.onresize = () => { renderer.setViewport(innerWidth, innerHeight) } @@ -108,13 +109,13 @@ export const demos = { setup: function(name) { this.manager.clear() createCanvasBounds(this.manager) - this.examples[name](this.manager) + this.examples.get(name)(this.manager) }, play(n) { this.setup(n) }, register(n, f) { - this.examples[n] = f + this.examples.set(n,f) } } //Physics diff --git a/demos/main.js b/demos/main.js index 573abc61..88358899 100644 --- a/demos/main.js +++ b/demos/main.js @@ -7,7 +7,7 @@ demos.setup("raycaster") let optionTab = document.querySelector("#options-checkbox") let demoOption = document.querySelector("#demos") -for (var n in demos.examples) { +for (let n of demos.examples.keys()) { let option = document.createElement("option") option.value = n option.innerHTML = n From 4092045ca951b84724c5f12f217706e9e4ebd8ac Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Sun, 10 Dec 2023 10:27:02 +0300 Subject: [PATCH 03/41] [Physics] Moved AABB module to math #refactor #internal --- src/intergrator/boundsComponent.js | 2 +- src/{physics => math}/AABB/boundingBox.js | 0 src/{physics => math}/AABB/boundingSphere.js | 0 src/{physics => math}/AABB/index.js | 0 src/{physics => math}/AABB/overlap.js | 0 src/math/index.js | 3 ++- src/physics/bodies/body.js | 2 +- src/physics/broadphases/AABBTree.js | 2 +- src/physics/broadphases/Quadtree.js | 2 +- src/physics/index.js | 2 -- 10 files changed, 6 insertions(+), 7 deletions(-) rename src/{physics => math}/AABB/boundingBox.js (100%) rename src/{physics => math}/AABB/boundingSphere.js (100%) rename src/{physics => math}/AABB/index.js (100%) rename src/{physics => math}/AABB/overlap.js (100%) diff --git a/src/intergrator/boundsComponent.js b/src/intergrator/boundsComponent.js index 2c4ae51a..c3415401 100644 --- a/src/intergrator/boundsComponent.js +++ b/src/intergrator/boundsComponent.js @@ -1,4 +1,4 @@ -import { BoundingBox } from "../physics/index.js" +import { BoundingBox } from "../math/index.js" import { Component } from "../ecs/index.js" diff --git a/src/physics/AABB/boundingBox.js b/src/math/AABB/boundingBox.js similarity index 100% rename from src/physics/AABB/boundingBox.js rename to src/math/AABB/boundingBox.js diff --git a/src/physics/AABB/boundingSphere.js b/src/math/AABB/boundingSphere.js similarity index 100% rename from src/physics/AABB/boundingSphere.js rename to src/math/AABB/boundingSphere.js diff --git a/src/physics/AABB/index.js b/src/math/AABB/index.js similarity index 100% rename from src/physics/AABB/index.js rename to src/math/AABB/index.js diff --git a/src/physics/AABB/overlap.js b/src/math/AABB/overlap.js similarity index 100% rename from src/physics/AABB/overlap.js rename to src/math/AABB/overlap.js diff --git a/src/math/index.js b/src/math/index.js index 16b70f54..71dfba85 100644 --- a/src/math/index.js +++ b/src/math/index.js @@ -3,4 +3,5 @@ export * from "./vector.js" export * from "./angle.js" export * from "./matrix.js" export * from "./functions.js" -export * from "./interpolation.js" \ No newline at end of file +export * from "./interpolation.js" +export * from "./AABB/index.js" \ No newline at end of file diff --git a/src/physics/bodies/body.js b/src/physics/bodies/body.js index 1debe376..ef51961b 100644 --- a/src/physics/bodies/body.js +++ b/src/physics/bodies/body.js @@ -1,7 +1,7 @@ import { Vector2, Angle,degToRad,radToDeg } from "../../math/index.js" import { Component } from "../../ecs/index.js" import { Utils } from "../../utils/index.js" -import { BoundingBox } from "../AABB/index.js" +import { BoundingBox } from "../../math/index.js" import { ObjType, Settings } from "../settings.js" import { Shape } from "../shapes/index.js" import { Movable, Transform } from "../../intergrator/index.js" diff --git a/src/physics/broadphases/AABBTree.js b/src/physics/broadphases/AABBTree.js index f4061e96..31e9c154 100644 --- a/src/physics/broadphases/AABBTree.js +++ b/src/physics/broadphases/AABBTree.js @@ -1,4 +1,4 @@ -//import { BoundingBox } from "../AABB/index.js" +//import { BoundingBox } from "../../math/index.js" import { Broadphase } from "./broadphase.js" //import { Utils }from "../../utils/index.js" diff --git a/src/physics/broadphases/Quadtree.js b/src/physics/broadphases/Quadtree.js index 80f6e265..a9b10e60 100644 --- a/src/physics/broadphases/Quadtree.js +++ b/src/physics/broadphases/Quadtree.js @@ -1,4 +1,4 @@ -import { Overlaps } from "../AABB/index.js" +import { Overlaps } from "../../math/index.js" import { Broadphase } from "./broadphase.js" import { Utils } from "../../utils/index.js" diff --git a/src/physics/index.js b/src/physics/index.js index 89d118fa..4f320105 100644 --- a/src/physics/index.js +++ b/src/physics/index.js @@ -1,5 +1,3 @@ -//export * from "./SAT/index.js" -export * from "./AABB/index.js" export * from "./shapes/index.js" export * from "./bodies/index.js" export * from "./constraints/index.js" From 1be7ec133a8af3ff459b3d10e7a4b86311ebead9 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Mon, 11 Dec 2023 11:18:08 +0300 Subject: [PATCH 04/41] [Demos] Fixed material example #fix --- .gitignore | 1 - demos/assets/warrior.png | Bin 0 -> 46361 bytes demos/marterial.js | 9 +++++---- 3 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 demos/assets/warrior.png diff --git a/.gitignore b/.gitignore index b29a32a4..37cb8973 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ node_modules debug.js *.jpg *.jpeg -*.png res.json *.mp3 tests diff --git a/demos/assets/warrior.png b/demos/assets/warrior.png new file mode 100644 index 0000000000000000000000000000000000000000..99af22b8aeeddd3d89bd82b69c36ffc8e013d4e0 GIT binary patch literal 46361 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 Uk|h@x0)JGmXefWUY~=mF0P^5F*Z=?k literal 0 HcmV?d00001 diff --git a/demos/marterial.js b/demos/marterial.js index e001f315..58ee9a48 100644 --- a/demos/marterial.js +++ b/demos/marterial.js @@ -8,7 +8,7 @@ import { createEntity } from "/src/index.js" const assets = { - static: "./assets/static2.jpeg" + static: "./assets/warrior.png" } @@ -32,16 +32,17 @@ export function materials(manager) { let material2 = new StaticImageMaterial(img) let sprite2 = createsprite(170, 60, geometry, material2) manager.add(sprite2) - + material2.offset.x = -material2.width / 2 + material2.offset.y = -material2.height / 2 //Sprite material let img2 = new Image() img2.src = assets.static let material3 = new SpriteMaterial(img) - let sprite3 = createsprite(290, 60,geometry, material3) + let sprite3 = createsprite(290, 60, geometry, material3) manager.add(sprite3) img2.onload = () => { - material3.setup(9, 6) + material3.setup(6, 16) material3.frameRate = 1 / 10 } } From 08e774e081285c0377acf39d4ec35437c9973518 Mon Sep 17 00:00:00 2001 From: waynemwashuma <94756970+waynemwashuma@users.noreply.github.com> Date: Mon, 11 Dec 2023 23:20:59 +0300 Subject: [PATCH 05/41] [config] vscode config added #new --- .vscode/launch.json | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..bc709d8d --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Attach to Chrome", + "port": 9222, + "request": "attach", + "type": "chrome", + "webRoot": "${workspaceFolder}", + }, + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:8080/demos/index.html", + "webRoot": "${workspaceFolder}", + "skipFiles": [ + "/**", + "node_modules/**" + ] + } + ] +} \ No newline at end of file From a1a34f54a42bae1fa6950f136715da80dcb02d82 Mon Sep 17 00:00:00 2001 From: waynemwashuma <94756970+waynemwashuma@users.noreply.github.com> Date: Mon, 11 Dec 2023 23:22:07 +0300 Subject: [PATCH 06/41] [Raycaster] Modified raycaster to have basic working #change --- src/raycaster/ray.js | 7 +++ src/raycaster/raycaster.js | 97 +++++++++++++++++++++++++++++++--- src/raycaster/raycastresult.js | 49 +++++++++++++++-- 3 files changed, 142 insertions(+), 11 deletions(-) diff --git a/src/raycaster/ray.js b/src/raycaster/ray.js index ba0f2cb5..e3339695 100644 --- a/src/raycaster/ray.js +++ b/src/raycaster/ray.js @@ -24,4 +24,11 @@ export class Ray { setDirection(x, y) { this._direction.set(x, y) } + lookAt(x, y) { + this._direction.set( + x - this._origin.x, + y - this._origin.y + ) + this._direction.normalize() + } } \ No newline at end of file diff --git a/src/raycaster/raycaster.js b/src/raycaster/raycaster.js index b312d962..8d2ebc45 100644 --- a/src/raycaster/raycaster.js +++ b/src/raycaster/raycaster.js @@ -1,14 +1,16 @@ import { Component } from "../ecs/index.js" import { Ray } from "./ray.js" import { Vector2 } from "../math/index.js" +import { RayCastModes, RayCollisionResult, RayPoint, RaycastResult } from "./raycastresult.js" export class Raycaster extends Component { rays = [] - initialDir = [] + collisionResults = [] _number = 0 _angle = 0 _transform = null _lastangle = 0 + mode = RayCastModes.ANY constructor(number = 1, angleSpace = 0) { super() this._angle = angleSpace @@ -21,39 +23,120 @@ export class Raycaster extends Component { const halfview = this._number * this._angle / 2 for (let a = -halfview; a <= halfview; a += this._angle) { this.rays.push(new Ray(new Vector2(), Vector2.fromRad(a))) - this.initialDir.push(Vector2.fromRad(a)) if (this._angle == 0) break } } update(bodies) { + this.collisionResults = [] const angle = this._transform.orientation.value const rotangle = angle - this._lastangle - + + this._transform.orientation.value += 0.01 for (var i = 0; i < this.rays.length; i++) { const ray = this.rays[i] ray.origin.copy(this._transform.position) ray.direction.rotate(rotangle) } this._lastangle = angle + for (let i = 0; i < bodies.length; i++) { + const shapes = bodies[i].shapes + + for (let i = 0; i < shapes.length; i++) { + const shape = shapes[i]; + + this.testVertices(shape.vertices, bodies[i]) + } + } + } + testVertices(vertices, body) { + let results = new RaycastResult() + for (let i = 0; i < this.rays.length; i++) { + const ray = this.rays[i]; + + results.collisions.push(testray(ray, vertices, body)) + } + this.collisionResults.push(results) } /** * @param {CanvasRenderingContext2D} ctx */ draw(ctx) { + ctx.save() + ctx.beginPath() ctx.translate(...this._transform.position) - this.rays.forEach(r => { ctx.moveTo(0, 0) ctx.lineTo( r.direction.x * r.maxLength, r.direction.y * r.maxLength ) + ctx.lineWidth = 2 }) - ctx.lineWidth = 2 ctx.strokeStyle = "rgba(255,255,255,0.5)" ctx.stroke() + ctx.closePath() + ctx.restore() + this.collisionResults.forEach(r => { + r.collisions.forEach(c => { + c.points.forEach(p => { + ctx.beginPath() + ctx.arc(...p.point, 3, 0, Math.PI * 2) + ctx.strokeStyle = "white" + ctx.stroke() + ctx.closePath() + }) + }) + }) } - add() { - throw "noooo" +} +function testray(ray, vertices, body) { + const origin = ray.origin + const direction = ray.direction + const results = new RayCollisionResult(ray, body) + + let res = testSingleEdge(vertices[vertices.length - 1], vertices[0], origin, direction) + if (res != void 0) + results.points.push( + new RayPoint( + res, + res.clone().sub(origin).magnitude() + ) + ) + for (let i = 0; i < vertices.length - 1; i++) { + let res = testSingleEdge(vertices[i], vertices[i + 1], origin, direction) + if (res != void 0) + results.points.push( + new RayPoint( + res, + res.clone().sub(origin).magnitude() + ) + ) + return results } +} +function testSingleEdge(v1, v2, or, dir) { + const x1 = v1.x + const y1 = v1.y + const x2 = v2.x + const y2 = v2.y + const x3 = or.x + const y3 = or.y + const x4 = dir.x + x3 + const y4 = dir.y + y3 + + const den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4) + + if (den === 0) return null + + const t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / den + const u = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / den + + if ( + t > 0 && t < 1 && + u > 0 + ) return new Vector2( + x1 + t * (x2 - x1), + y1 + t * (y2 - y1) + ) + return null } \ No newline at end of file diff --git a/src/raycaster/raycastresult.js b/src/raycaster/raycastresult.js index 38db3720..ec57dd89 100644 --- a/src/raycaster/raycastresult.js +++ b/src/raycaster/raycastresult.js @@ -1,18 +1,59 @@ +import { Vector2 } from "../math/index.js" + export class RaycastResult{ - ray = null + /** + * @type {RayCastModes} + */ mode = RayCastModes.NONE collisions = [] } export class RayCollisionResult{ - distance = 0 + /** + * @readonly + * @type {Body} + */ object = null + /** + * @readonly + * @type {RayPoint[]} + */ points = [ ] + /** + * @readonly + * @type {Ray} + */ ray = null + /** + * @param {Ray} ray + * @param {Body} object + */ + constructor(ray,object){ + this.ray = ray + this.object = object + } +} +export class RayPoint{ + /** + * @readonly + * @type {Vector2} + */ + point = null + /** + * @readonly + * @type {number} + */ + distance = 0 + constructor(point,distance){ + this.point = point + this.distance = distance + } } - /** * @enum {number} - * + * @property NONE + * @property NEAREST + * @property ANY + * @property FIRST */ export const RayCastModes = { NONE : 0, From 990891d8cc3605fbe6a55ad855971d2c779e80dd Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Mon, 11 Dec 2023 23:59:28 +0300 Subject: [PATCH 07/41] [render] `SpriteMaterial()` refactored #refactor #internal --- src/render/material/SpriteMaterial.js | 33 +++++++++++++++------------ src/render/utils/canvasfunc.js | 6 +++-- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/render/material/SpriteMaterial.js b/src/render/material/SpriteMaterial.js index 1f96e935..3a61c3e3 100644 --- a/src/render/material/SpriteMaterial.js +++ b/src/render/material/SpriteMaterial.js @@ -5,74 +5,76 @@ import { drawImage } from "../utils/canvasfunc.js" */ export class SpriteMaterial { /** - * @type HTMLImageElement + * @type {HTMLImageElement} */ img = null /** * The index of the current action. * * @private - * @type number + * @type {number} */ _index = 0 /** * The current action's max frame index. * * @private - * @type number + * @type {number} */ _maxFrame = 0 /** * The current frame of an action. * * @private - * @type number + * @type {number} */ _frame = 0 /** * Used with ImageSprite#frameRate to throttle the fps of the sprite. * * @private - * @type number + * @type {number} */ _accumulator = 0 /** * The maximum frames for each given action. * - * @type number + * @type {number} */ frameRate = 1 / 60 /** * The current action. * * @private - * @type number[] + * @type {number[]} */ _maxFrames = null + /** + * @type {Vector} /** * The width of the sprite. * - * @type number + * @type {number} */ width = 0 /** * The height of the sprite.. * - * @type number + * @type {number} */ height = 0 /** * The width of a frame. * * @private - * @type number + * @type {number} */ frameWidth = 0 /** * The height of a frame.. * * @private - * @type number + * @type {number} */ frameHeight = 0 /** @@ -91,10 +93,11 @@ export class SpriteMaterial { */ setup(frames, actions) { this._maxFrame = frames - 1 - this.width = this.img.width - this.height = this.img.height this.frameWidth = this.img.width / (frames || 1) this.frameHeight = this.img.height / actions + this.width |= this.frameWidth + this.height |= this.frameHeight + console.log(this.width); } /** * Sets max number of frames for a given action @@ -128,7 +131,9 @@ export class SpriteMaterial { this.frameWidth, this.frameHeight, this._frame, - this._index + this._index, + this.width, + this.height ) this._accumulator += dt if (this._accumulator < this.frameRate) return diff --git a/src/render/utils/canvasfunc.js b/src/render/utils/canvasfunc.js index b3ae438f..854a69bc 100644 --- a/src/render/utils/canvasfunc.js +++ b/src/render/utils/canvasfunc.js @@ -99,10 +99,12 @@ export function drawImage( w = img.width, h = img.height, ix = 0, - iy = 0 + iy = 0, + dw = w, + dh = h ) { ctx.drawImage(img, w * ix, h * iy, w, h, x, y, - w, h) + dw, dh) } \ No newline at end of file From b3f17e224e4482cf43afe6e5ec5f1766cecf5b48 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Tue, 12 Dec 2023 00:13:36 +0300 Subject: [PATCH 08/41] [Render] Fixed an error on `SpriteMaterial.setAction()` #fix --- .gitignore | 3 ++- src/render/material/SpriteMaterial.js | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 37cb8973..8e810f88 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ res.json *.mp3 tests *.res.js -*.txt \ No newline at end of file +*.txt +demos \ No newline at end of file diff --git a/src/render/material/SpriteMaterial.js b/src/render/material/SpriteMaterial.js index 3a61c3e3..3c827c4e 100644 --- a/src/render/material/SpriteMaterial.js +++ b/src/render/material/SpriteMaterial.js @@ -48,7 +48,7 @@ export class SpriteMaterial { * @private * @type {number[]} */ - _maxFrames = null + _maxFrames = [] /** * @type {Vector} /** @@ -97,7 +97,9 @@ export class SpriteMaterial { this.frameHeight = this.img.height / actions this.width |= this.frameWidth this.height |= this.frameHeight - console.log(this.width); + for (var i = 0; i < actions; i++) { + this._maxFrames.push(frames) + } } /** * Sets max number of frames for a given action From 0e90beb32181b87222b18db52bce431a282f3f9a Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Tue, 12 Dec 2023 00:15:55 +0300 Subject: [PATCH 09/41] [render] Fixed `SpriteMaterial.setMaxFrames()` to set up max frames correctly #fix --- src/render/material/SpriteMaterial.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/material/SpriteMaterial.js b/src/render/material/SpriteMaterial.js index 3c827c4e..25c8d788 100644 --- a/src/render/material/SpriteMaterial.js +++ b/src/render/material/SpriteMaterial.js @@ -108,7 +108,7 @@ export class SpriteMaterial { * @param {number} max */ setMaxFrames(action, max) { - this._maxFrames = max + this._maxFrames[action] = max } /** * Sets a given action to be rendered From 353ec820c2b13c76041a0cfe5f87fc156692f137 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Tue, 12 Dec 2023 01:03:08 +0300 Subject: [PATCH 10/41] [render] Fixed unwanted stretching of `SpriteMaterial()` --- src/render/material/SpriteMaterial.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/render/material/SpriteMaterial.js b/src/render/material/SpriteMaterial.js index 25c8d788..184c9eb2 100644 --- a/src/render/material/SpriteMaterial.js +++ b/src/render/material/SpriteMaterial.js @@ -95,8 +95,8 @@ export class SpriteMaterial { this._maxFrame = frames - 1 this.frameWidth = this.img.width / (frames || 1) this.frameHeight = this.img.height / actions - this.width |= this.frameWidth - this.height |= this.frameHeight + this.width ||= this.frameWidth + this.height ||= this.frameHeight for (var i = 0; i < actions; i++) { this._maxFrames.push(frames) } @@ -128,8 +128,8 @@ export class SpriteMaterial { drawImage( ctx, this.img, - -this.frameWidth / 2, - -this.frameHeight / 2, + -this.width / 2, + -this.width / 2, this.frameWidth, this.frameHeight, this._frame, From bea3f3d510b624f63a97e12017d2ff4dc9b40a11 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Tue, 12 Dec 2023 18:41:05 +0300 Subject: [PATCH 11/41] [Raycaster] Fixed issues with raycasting #fix --- .gitignore | 3 +- src/raycaster/raycaster.js | 80 +++++++++++++++++++++++++++++----- src/raycaster/raycastresult.js | 2 - 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 8e810f88..19a063f0 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ res.json tests *.res.js *.txt -demos \ No newline at end of file +demos +math \ No newline at end of file diff --git a/src/raycaster/raycaster.js b/src/raycaster/raycaster.js index 8d2ebc45..0a8573fe 100644 --- a/src/raycaster/raycaster.js +++ b/src/raycaster/raycaster.js @@ -1,4 +1,5 @@ import { Component } from "../ecs/index.js" +import { Shape } from "../physics/index.js" import { Ray } from "./ray.js" import { Vector2 } from "../math/index.js" import { RayCastModes, RayCollisionResult, RayPoint, RaycastResult } from "./raycastresult.js" @@ -30,8 +31,6 @@ export class Raycaster extends Component { this.collisionResults = [] const angle = this._transform.orientation.value const rotangle = angle - this._lastangle - - this._transform.orientation.value += 0.01 for (var i = 0; i < this.rays.length; i++) { const ray = this.rays[i] ray.origin.copy(this._transform.position) @@ -41,13 +40,24 @@ export class Raycaster extends Component { for (let i = 0; i < bodies.length; i++) { const shapes = bodies[i].shapes - for (let i = 0; i < shapes.length; i++) { - const shape = shapes[i]; - - this.testVertices(shape.vertices, bodies[i]) + for (let j = 0; j < shapes.length; j++) { + const shape = shapes[j]; + if (shape.type === Shape.POLYGON) + this.testVertices(shape.vertices, bodies[i]) + if (shape.type === Shape.CIRCLE) + this.testCircle(shape.position, shape.radius, bodies[i]) } } } + testCircle(position, radius, body) { + let results = new RaycastResult() + for (let i = 0; i < this.rays.length; i++) { + const ray = this.rays[i]; + + results.collisions.push(testraycircle(ray, position, radius, body)) + } + this.collisionResults.push(results) + } testVertices(vertices, body) { let results = new RaycastResult() for (let i = 0; i < this.rays.length; i++) { @@ -89,31 +99,41 @@ export class Raycaster extends Component { }) } } + function testray(ray, vertices, body) { const origin = ray.origin const direction = ray.direction const results = new RayCollisionResult(ray, body) - let res = testSingleEdge(vertices[vertices.length - 1], vertices[0], origin, direction) + let res = testSingleEdge( + vertices[vertices.length - 1], + vertices[0], origin, direction + ) if (res != void 0) results.points.push( new RayPoint( res, - res.clone().sub(origin).magnitude() + res.clone().sub(origin) + .magnitudeSquared() ) ) for (let i = 0; i < vertices.length - 1; i++) { - let res = testSingleEdge(vertices[i], vertices[i + 1], origin, direction) + let res = testSingleEdge( + vertices[i], vertices[i + 1], + origin, direction + ) if (res != void 0) results.points.push( new RayPoint( res, - res.clone().sub(origin).magnitude() + res.clone().sub(origin) + .magnitudeSquared() ) ) - return results } + return results } + function testSingleEdge(v1, v2, or, dir) { const x1 = v1.x const y1 = v1.y @@ -139,4 +159,42 @@ function testSingleEdge(v1, v2, or, dir) { y1 + t * (y2 - y1) ) return null +} + +function testraycircle(ray, center, radius, body) { + const results = new RayCollisionResult(ray, body) + + const x1 = ray.origin.x + const y1 = ray.origin.y + const x2 = ray.direction.x + const y2 = ray.direction.y + + const x3 = center.x + const y3 = center.y + const x4 = x3 - x1 + const y4 = y3 - y1 + const r = radius + + const proj = x2 * x4 + y2 * y4 + const delta = proj * proj - ((x4 * x4 + y4 * y4) - r * r) + const sqrtDelta = Math.sqrt(delta) + const distance1 = proj + sqrtDelta + const distance2 = proj - sqrtDelta + + if (delta < 0 || distance1 < 0) return results + results.points.push(new RayPoint( + new Vector2( + x1 + distance1 * x2, + y1 + distance1 * y2 + ), distance1 * distance1 + )) + if (delta === 0 || (distance2 < 0)) return results + results.points.push(new RayPoint( + new Vector2( + x1 + distance2 * x2, + y1 + distance2 * y2 + ), + distance2 * distance2 + )) + return results } \ No newline at end of file diff --git a/src/raycaster/raycastresult.js b/src/raycaster/raycastresult.js index ec57dd89..ceab60c5 100644 --- a/src/raycaster/raycastresult.js +++ b/src/raycaster/raycastresult.js @@ -9,7 +9,6 @@ export class RaycastResult{ } export class RayCollisionResult{ /** - * @readonly * @type {Body} */ object = null @@ -19,7 +18,6 @@ export class RayCollisionResult{ */ points = [ ] /** - * @readonly * @type {Ray} */ ray = null From 500b3dc2acdd5b7cdf8b1f58a1ac5114ee4a13ae Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Tue, 12 Dec 2023 18:49:44 +0300 Subject: [PATCH 12/41] [math] Fixed an error in `Angle()` constructor #fix --- .gitignore | 3 +-- src/math/angle.js | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 19a063f0..8e810f88 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,4 @@ res.json tests *.res.js *.txt -demos -math \ No newline at end of file +demos \ No newline at end of file diff --git a/src/math/angle.js b/src/math/angle.js index d9010a6b..59a6fe93 100644 --- a/src/math/angle.js +++ b/src/math/angle.js @@ -32,7 +32,7 @@ class Angle { //TODO - Change this to radians instead constructor(deg = 0) { - this.value = deg * Math.PI/2 + this.value = deg * Math.PI/180 } /** * @type string From 26ecddcff37a9405d25047c854db0b8954a48276 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Tue, 12 Dec 2023 19:32:34 +0300 Subject: [PATCH 13/41] [debugger] Added new debugger for raycasting `raycastDebugger()` #new #refactor --- .gitignore | 3 +- src/debuggers/index.js | 3 +- src/debuggers/raycastDebugger.js | 51 ++++++++++++++++++++++++++++++++ src/raycaster/manager.js | 11 +------ src/raycaster/raycaster.js | 31 ------------------- 5 files changed, 56 insertions(+), 43 deletions(-) create mode 100644 src/debuggers/raycastDebugger.js diff --git a/.gitignore b/.gitignore index 8e810f88..49ffed7f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ res.json tests *.res.js *.txt -demos \ No newline at end of file +demos +ecs \ No newline at end of file diff --git a/src/debuggers/index.js b/src/debuggers/index.js index 07fa7b31..e2aff32c 100644 --- a/src/debuggers/index.js +++ b/src/debuggers/index.js @@ -1,2 +1,3 @@ export * from "./fpsdebugger.js" -export * from "./bodydebugger.js" \ No newline at end of file +export * from "./bodydebugger.js" +export * from "./raycastDebugger.js" \ No newline at end of file diff --git a/src/debuggers/raycastDebugger.js b/src/debuggers/raycastDebugger.js new file mode 100644 index 00000000..ced2f464 --- /dev/null +++ b/src/debuggers/raycastDebugger.js @@ -0,0 +1,51 @@ +export function raycastDebugger(manager) { + manager.registerSystem("raycastDebugger", { + renderer: null, + raycaster: null, + init(manager) { + const that = this + this.renderer = manager.getSystem("renderer") + this.raycaster = manager.getSystem("raycaster") + setupDebugger(this) + manager.events.add("clear", e => { + setupDebugger(that) + }) + }, + update(dt) {} + }) +} + +function setupDebugger(debug) { + debug.renderer.add({ + render(ctx) { + debug.raycaster.objects.forEach(e => { + ctx.save() + ctx.beginPath() + ctx.translate(...e._transform.position) + e.rays.forEach(r => { + ctx.moveTo(0, 0) + ctx.lineTo( + r.direction.x * r.maxLength, + r.direction.y * r.maxLength + ) + ctx.lineWidth = 2 + }) + ctx.strokeStyle = "rgba(255,255,255,0.5)" + ctx.stroke() + ctx.closePath() + ctx.restore() + e.collisionResults.forEach(r => { + r.collisions.forEach(c => { + c.points.forEach(p => { + ctx.beginPath() + ctx.arc(...p.point, 3, 0, Math.PI * 2) + ctx.strokeStyle = "white" + ctx.stroke() + ctx.closePath() + }) + }) + }) + }) + } + }) +} \ No newline at end of file diff --git a/src/raycaster/manager.js b/src/raycaster/manager.js index 7c2a7cdd..a1e5f515 100644 --- a/src/raycaster/manager.js +++ b/src/raycaster/manager.js @@ -6,18 +6,9 @@ export class RaycastManager extends System { init(manager) { if (!manager.getSystem("world")) throw "World is required for running Raycast system." - - let renderer = manager.getSystem("renderer") manager.setComponentList("raycaster",this.objects) this.bodies = manager.getComponentList("body") - renderer.add({ - context:this, - render(ctx) { - this.context.objects.forEach(e=>{ - e.draw(ctx) - }) - } - }) + } update(){ for (let i = 0; i < this.objects.length; i++) { diff --git a/src/raycaster/raycaster.js b/src/raycaster/raycaster.js index 0a8573fe..48781be0 100644 --- a/src/raycaster/raycaster.js +++ b/src/raycaster/raycaster.js @@ -67,37 +67,6 @@ export class Raycaster extends Component { } this.collisionResults.push(results) } - /** - * @param {CanvasRenderingContext2D} ctx - */ - draw(ctx) { - ctx.save() - ctx.beginPath() - ctx.translate(...this._transform.position) - this.rays.forEach(r => { - ctx.moveTo(0, 0) - ctx.lineTo( - r.direction.x * r.maxLength, - r.direction.y * r.maxLength - ) - ctx.lineWidth = 2 - }) - ctx.strokeStyle = "rgba(255,255,255,0.5)" - ctx.stroke() - ctx.closePath() - ctx.restore() - this.collisionResults.forEach(r => { - r.collisions.forEach(c => { - c.points.forEach(p => { - ctx.beginPath() - ctx.arc(...p.point, 3, 0, Math.PI * 2) - ctx.strokeStyle = "white" - ctx.stroke() - ctx.closePath() - }) - }) - }) - } } function testray(ray, vertices, body) { From daa53ecdd2b0f5613ebb2ad9f86967f3cee8a6a7 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Tue, 12 Dec 2023 19:33:20 +0300 Subject: [PATCH 14/41] [ecs] Added new event `clear` onto manager #new --- src/ecs/manager.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ecs/manager.js b/src/ecs/manager.js index 573f6f00..b2229be3 100644 --- a/src/ecs/manager.js +++ b/src/ecs/manager.js @@ -245,6 +245,7 @@ export class Manager { for (let i = this.objects.length - 1; i >= 0; i--) { this.remove(this.objects[i]) } + this.events.trigger("clear") } /** * This method requests an animation frame from the browser From 8683a90964f7f007f7f204210aa5d1a2bf4d9ae7 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Thu, 14 Dec 2023 02:04:16 +0300 Subject: [PATCH 15/41] [render] Added new material `TextMaterial()` for text rendering #new --- .gitignore | 3 +- src/render/material/index.js | 3 +- src/render/material/textMaterial.js | 51 +++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 src/render/material/textMaterial.js diff --git a/.gitignore b/.gitignore index 49ffed7f..8e810f88 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,4 @@ res.json tests *.res.js *.txt -demos -ecs \ No newline at end of file +demos \ No newline at end of file diff --git a/src/render/material/index.js b/src/render/material/index.js index 84531320..fca09c0d 100644 --- a/src/render/material/index.js +++ b/src/render/material/index.js @@ -1,4 +1,5 @@ export * from "./material.js" export * from "./BasicMaterial.js" export * from "./StaticImageMaterial.js" -export * from "./SpriteMaterial.js" \ No newline at end of file +export * from "./SpriteMaterial.js" +export * from "./textMaterial.js" \ No newline at end of file diff --git a/src/render/material/textMaterial.js b/src/render/material/textMaterial.js new file mode 100644 index 00000000..1e3510ad --- /dev/null +++ b/src/render/material/textMaterial.js @@ -0,0 +1,51 @@ +import { Material } from "././material.js" + +/** + * Material for rendering text. + */ +export class TextMaterial extends Material { + /** + * @type {String} + */ + text = "" + /** + * @type {boolean} + */ + center = false + /** + * @type {String} + */ + color = "white" + /** + * @type {boolean} + */ + fill = true + /** + * @type {String} + */ + font = "16px sans-serif" + /** + * @param {String} text + */ + constructor(text) { + super() + this.text = text + } + /** + * @inheritdoc + * @param {CanvasRenderingContext2D} ctx + */ + render(ctx) { + /**@type {TextMetrics}*/ + const metrics = ctx.measureText(this.text) + const x = this.center ? -metrics.width / 2 : 0 + const y = 0 + ctx.strokeRect = this.color + ctx.fillStyle = this.color + ctx.font = this.font + if (this.fill) + ctx.fillText(this.text, x, y) + else + ctx.strokeText(this.text, x, y) + } +} \ No newline at end of file From 1cc6b429ea73011a7c2c892c566be86460732e8e Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Sat, 16 Dec 2023 10:34:18 +0300 Subject: [PATCH 16/41] [physics] Added `Body.addShape()` method to add shapes to a body #new --- src/physics/bodies/body.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/physics/bodies/body.js b/src/physics/bodies/body.js index ef51961b..42caaf21 100644 --- a/src/physics/bodies/body.js +++ b/src/physics/bodies/body.js @@ -484,7 +484,12 @@ export class Body extends Component { }) return obj } - //TODO - Add way to add shapes to body + /** + * @@param {Shape} shape + */ + addShape(shape){ + this.shapes.push(shape) + } fromJson(obj) { let shapes = [] obj.shapes.forEach((shape) => { From b66cdf64babf9fbc16a965d9331b87e500d1e6a5 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Wed, 13 Dec 2023 10:47:24 +0300 Subject: [PATCH 17/41] [math] New class `Color()` for color management #new --- src/math/color.js | 138 ++++++++++++++++++++++++++++++++++++++++++++++ src/math/index.js | 3 +- 2 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 src/math/color.js diff --git a/src/math/color.js b/src/math/color.js new file mode 100644 index 00000000..f90e48fa --- /dev/null +++ b/src/math/color.js @@ -0,0 +1,138 @@ +import { clamp, rand } from "./math.js" +/** + * A color manipulation class. + */ +export class Color { + + /** + * @param {number} [r=0] - red component [0 .. 255] + * @param {number} [g=0] - green component [0 .. 255] + * @param {number} [b=0] - blue component [0 .. 255] + * @param {number} [alpha=1.0] - alpha value [0.0 .. 1.0] + */ + constructor(r = 0, g = 0, b = 0, alpha = 1.0) { + this.set(r, g, b, alpha); + } + + /** + * Set this color to the specified value. + * @param {number} r - red component [0 .. 255] + * @param {number} g - green component [0 .. 255] + * @param {number} b - blue component [0 .. 255] + * @param {number} [alpha=1.0] - alpha value [0.0 .. 1.0] + * @returns {Color} Reference to this object for method chaining + */ + set(r, g, b, alpha = 1.0) { + this.r = r; + this.g = g; + this.b = b; + this.a = alpha; + return this; + } + + /** + * Create a new copy of this color object. + * @returns {Color} Reference to the newly cloned object + */ + clone() { + return new Color().copy(this); + } + + /** + * Copy a color object or CSS color into this one. + * @param {Color|string} color + * @returns {Color} Reference to this object for method chaining + */ + copy(color) { + this.set(color.r, color.g, color.b, color.a) + } + + /** + * Blend this color with the given one using addition. + * @param {Color} color + * @returns {Color} Reference to this object for method chaining + */ + add(color) { + this.r = clamp(this.r + color.r, 0, 255); + this.g = clamp(this.g + color.g, 0, 255); + this.b = clamp(this.b + color.b, 0, 255); + this.a = (this.a + color.a) / 2; + + return this; + } + + /** + * Darken this color value by 0..1 + * @param {number} scale + * @returns {Color} Reference to this object for method chaining + */ + darken(scale) { + scale = clamp(scale, 0, 1); + this.r *= scale; + this.g *= scale; + this.b *= scale; + + return this; + } + + /** + * Linearly interpolate between this color and the given one. + * @param {Color} color + * @param {number} alpha - with alpha = 0 being this color, and alpha = 1 being the given one. + * @returns {Color} Reference to this object for method chaining + */ + lerp(color, alpha) { + alpha = clamp(alpha, 0, 1); + this.r += (color.r - this.r) * alpha; + this.g += (color.g - this.g) * alpha; + this.b += (color.b - this.b) * alpha; + + return this; + } + + /** + * Lighten this color value by 0..1 + * @param {number} scale + * @returns {Color} Reference to this object for method chaining + */ + lighten(scale) { + scale = clamp(scale, 0, 1); + this.r = clamp(this.r + (1 - this.r) * scale, 0, 1); + this.g = clamp(this.g + (1 - this.g) * scale, 0, 1); + this.b = clamp(this.b + (1 - this.b) * scale, 0, 1); + + return this; + } + + /** + * Generate random r,g,b values for this color object + * @param {number} [min=0] - minimum value for the random range + * @param {number} [max=255] - maxmium value for the random range + * @returns {Color} Reference to this object for method chaining + */ + random(min = 0, max = 255) { + if (min < 0) { + min = 0; + } + if (max > 255) { + max = 255; + } + + return this.set( + rand(min, max), + rand(min, max), + rand(min, max), + this.a + ); + } + + + toArray(array, offset = 0) { + array[offset] = this.r + array[offset + 1] = this.g + array[offset + 2] = this.b + array[offset + 3] = this.a + + return array + } +} \ No newline at end of file diff --git a/src/math/index.js b/src/math/index.js index 71dfba85..f79045d8 100644 --- a/src/math/index.js +++ b/src/math/index.js @@ -4,4 +4,5 @@ export * from "./angle.js" export * from "./matrix.js" export * from "./functions.js" export * from "./interpolation.js" -export * from "./AABB/index.js" \ No newline at end of file +export * from "./AABB/index.js" +export * from "./color.js" \ No newline at end of file From 7fe1506cf752c72ebdd4458aff673a36a0dc1d86 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Thu, 14 Dec 2023 10:57:29 +0300 Subject: [PATCH 18/41] [Maths] Refactored mathematical functions #refactor #internal --- src/math/functions.js | 10 ---------- src/math/index.js | 1 - src/math/math.js | 46 +++++++++++++++++++++---------------------- 3 files changed, 23 insertions(+), 34 deletions(-) delete mode 100644 src/math/functions.js diff --git a/src/math/functions.js b/src/math/functions.js deleted file mode 100644 index b1f8ce85..00000000 --- a/src/math/functions.js +++ /dev/null @@ -1,10 +0,0 @@ -export function wrapAngle(x) { - let a = x - while (a > Math.PI * 2) { - a = a - Math.PI * 2 - } - while (a < 0) { - a = a + Math.PI * 2 - } - return a -} \ No newline at end of file diff --git a/src/math/index.js b/src/math/index.js index f79045d8..d792b077 100644 --- a/src/math/index.js +++ b/src/math/index.js @@ -2,7 +2,6 @@ export * from "./math.js" export * from "./vector.js" export * from "./angle.js" export * from "./matrix.js" -export * from "./functions.js" export * from "./interpolation.js" export * from "./AABB/index.js" export * from "./color.js" \ No newline at end of file diff --git a/src/math/math.js b/src/math/math.js index 3f6d7b49..3db60349 100644 --- a/src/math/math.js +++ b/src/math/math.js @@ -8,7 +8,7 @@ const RHI = Math.PI / 180, * @param {number} [max=1] The maximum bound of the random number * @returns {number} */ -function rand(min = 0, max = 1) { +export function rand(min = 0, max = 1) { return Math.random() * (max - min) + min } @@ -18,7 +18,7 @@ function rand(min = 0, max = 1) { * @param {number} x The number to square * @returns {number} */ -function sq(x) { +export function sq(x) { return x * x } /** @@ -28,7 +28,7 @@ function sq(x) { * @param {number} [e=2] The number to power by. * @returns {number} */ -function exp(x, e = 2) { +export function exp(x, e = 2) { return x ** e } /** @@ -37,7 +37,7 @@ function exp(x, e = 2) { * @param {number} x The number to root * @returns {number} */ -function sqrt(x) { +export function sqrt(x) { return Math.sqrt(x) } @@ -50,7 +50,7 @@ function sqrt(x) { * @param {number} t A number between 0 and 1 to interpopate by.Any other number greater than 1 or less than 0 will extapolate beyond b or a respectively. * @returns {number} */ -function lerp(a, b, t) { +export function lerp(a, b, t) { return a + t * (b - a) } @@ -61,7 +61,7 @@ function lerp(a, b, t) { * @param {number} [precision=4] How many decimal places there should be. * @returns {number} */ -function round(number, precision = 4) { +export function round(number, precision = 4) { precision = 10 ** precision return Math.round(number * precision) / precision } @@ -74,7 +74,7 @@ function round(number, precision = 4) { * @param {number} max The maximum bound of the clamped number. * @returns {number} */ -function clamp(value, min, max) { +export function clamp(value, min, max) { if (value < min) return min if (value > max) return max return value @@ -90,7 +90,7 @@ function clamp(value, min, max) { * @param {number} y2 * @returns {number} */ -function map(v, x1, y1, x2, y2) { +export function map(v, x1, y1, x2, y2) { return x2 + v * (y2 - x2) / (y1 - x1) } /** @@ -99,7 +99,7 @@ function map(v, x1, y1, x2, y2) { * @param {number} b * @returns {number} */ -function naturalizePair(a, b) { +export function naturalizePair(a, b) { if (a > b) return (a + b) * (a + b + 1) / 2 + a; return (a + b) * (a + b + 1) / 2 + b; @@ -111,7 +111,7 @@ function naturalizePair(a, b) { * @param {number} deg number to convert. * @returns {number} */ -function degToRad(deg) { +export function degToRad(deg) { return deg * RHI } @@ -121,19 +121,19 @@ function degToRad(deg) { * @param {number} rad number to convert. * @returns {number} */ -function radToDeg(rad) { +export function radToDeg(rad) { return rad * RHI_INV } -export { - rand, - round, - exp, - sq, - sqrt, - lerp, - clamp, - naturalizePair, - map, - degToRad, - radToDeg +/** + * @param {number} x +*/ +export function wrapAngle(x) { + let a = x + while (a > Math.PI * 2) { + a = a - Math.PI * 2 + } + while (a < 0) { + a = a + Math.PI * 2 + } + return a } \ No newline at end of file From 2395bf72dfb07bb989882ab54863af1f1109d001 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Thu, 14 Dec 2023 11:18:41 +0300 Subject: [PATCH 19/41] [Math] Constants have been added #new --- src/math/constants.js | 7 +++++++ src/math/index.js | 3 ++- src/math/math.js | 7 +++---- 3 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 src/math/constants.js diff --git a/src/math/constants.js b/src/math/constants.js new file mode 100644 index 00000000..32811903 --- /dev/null +++ b/src/math/constants.js @@ -0,0 +1,7 @@ +export const PI = Math.PI +export const TWO_PI = Math.PI * 2 +export const HALF_PI = Math.PI / 2 +export const DEG2RAD = Math.PI / 180 +export const epilson = Math.pow(2, -53) +export const RAD2DEG = 180 / Math.PI +export const SQRT2 = Math.sqrt(2) \ No newline at end of file diff --git a/src/math/index.js b/src/math/index.js index d792b077..4a784e93 100644 --- a/src/math/index.js +++ b/src/math/index.js @@ -4,4 +4,5 @@ export * from "./angle.js" export * from "./matrix.js" export * from "./interpolation.js" export * from "./AABB/index.js" -export * from "./color.js" \ No newline at end of file +export * from "./color.js" +export * from "./constants.js" \ No newline at end of file diff --git a/src/math/math.js b/src/math/math.js index 3db60349..1551d3f5 100644 --- a/src/math/math.js +++ b/src/math/math.js @@ -1,5 +1,4 @@ -const RHI = Math.PI / 180, - RHI_INV = 1 / RHI +import {DEG2RAD,RAD2DEG} from "./constants.js" /** * Creates a random number between the parameters @@ -112,7 +111,7 @@ export function naturalizePair(a, b) { * @returns {number} */ export function degToRad(deg) { - return deg * RHI + return deg * DEG2RAD } /** @@ -122,7 +121,7 @@ export function degToRad(deg) { * @returns {number} */ export function radToDeg(rad) { - return rad * RHI_INV + return rad * RAD2DEG } /** * @param {number} x From efc9dfc3b05cfca895f802d4d7edff4217d402ff Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Sun, 17 Dec 2023 18:47:23 +0300 Subject: [PATCH 20/41] [render] Added `LineGeometry()` , `BoxGeometry()` and `TriangleGeometru()` #new --- src/render/geometry/boxgeometry.js | 11 +++++++++++ src/render/geometry/index.js | 5 ++++- src/render/geometry/linegeometry.js | 9 +++++++++ src/render/geometry/trianglegeometry.js | 14 ++++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/render/geometry/boxgeometry.js create mode 100644 src/render/geometry/linegeometry.js create mode 100644 src/render/geometry/trianglegeometry.js diff --git a/src/render/geometry/boxgeometry.js b/src/render/geometry/boxgeometry.js new file mode 100644 index 00000000..b4be849a --- /dev/null +++ b/src/render/geometry/boxgeometry.js @@ -0,0 +1,11 @@ +import {BufferGeometry} from "./geometry.js" + +export class BoxGeometry extends BufferGeometry{ + constructor(width,hieght){ + let v1 = new Vector2(-width / 2, -height / 2) + let v2 = new Vector2(-width / 2, height / 2) + let v3 = new Vector2(width / 2, height / 2) + let v4 = new Vector2(width / 2, -height / 2) + super([v1, v2, v3, v4]) + } +} \ No newline at end of file diff --git a/src/render/geometry/index.js b/src/render/geometry/index.js index 62925f50..dfe18fc0 100644 --- a/src/render/geometry/index.js +++ b/src/render/geometry/index.js @@ -1,2 +1,5 @@ export * from "./geometry.js" -export * from "./circlegeometry.js" \ No newline at end of file +export * from "./circlegeometry.js" +export * from "./boxgeometry.js" +export * from "./trianglegeometry.js" +export * from "./linegeometry.js" \ No newline at end of file diff --git a/src/render/geometry/linegeometry.js b/src/render/geometry/linegeometry.js new file mode 100644 index 00000000..5871bf07 --- /dev/null +++ b/src/render/geometry/linegeometry.js @@ -0,0 +1,9 @@ +import { BufferGeometry } from "./geometry.js" + +export class LineGeometry extends BufferGeometry { + constructor(length) { + let start = new Vector2(1).multiply(length / 2), + end = new Vector2(1).multiply(-length / 2) + super([start, end]) + } +} \ No newline at end of file diff --git a/src/render/geometry/trianglegeometry.js b/src/render/geometry/trianglegeometry.js new file mode 100644 index 00000000..429ca131 --- /dev/null +++ b/src/render/geometry/trianglegeometry.js @@ -0,0 +1,14 @@ +import {BufferGeometry} from "./geometry.js" + +export class TriangleGeometry extends BufferGeometry{ + constructor(base, height, angle) { + let l1 = new Vector2(1).multiply(base) + let l2 = Vector2.fromRad(angle).multiply(height/Math.sin(angle)) + let center = tmp1.set((l1.x + l2.x) / 3, l2.y / 3) + super([ + new Vector2().sub(center), + l1.sub(center), + l2.sub(center) + ]) + } +} \ No newline at end of file From 2c41fb51f089b5da0df694326d167d5d90e2d728 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Thu, 28 Dec 2023 10:30:15 +0300 Subject: [PATCH 21/41] [Physics] Added `Body.applyImpulse()` method #new --- src/physics/bodies/body.js | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/physics/bodies/body.js b/src/physics/bodies/body.js index 42caaf21..d2d3f2d5 100644 --- a/src/physics/bodies/body.js +++ b/src/physics/bodies/body.js @@ -1,4 +1,4 @@ -import { Vector2, Angle,degToRad,radToDeg } from "../../math/index.js" +import { Vector2, Angle, degToRad, radToDeg } from "../../math/index.js" import { Component } from "../../ecs/index.js" import { Utils } from "../../utils/index.js" import { BoundingBox } from "../../math/index.js" @@ -397,15 +397,24 @@ export class Body extends Component { /** * Applies a force to a body affecting its direction of travel and rotation. * - * * @param { Vector2} force The force to be applied. - * @param { Vector2} [arm= Vector2] The collision arm. + * @param { Vector2} [arm = Vector2] The collision arm. */ applyForce(force, arm = Vector2.ZERO) { this.acceleration.add(force.multiply(this.inv_mass)) + //Todo - correct this to torque. this.rotation.value += arm.cross(force) * this.inv_inertia } - + /** + * Applies a force to a body affecting its direction of travel and rotation. + * + * @param { Vector2} force The force to be applied. + * @param { Vector2} [arm = Vector2] The collision arm. + */ + applyImpulse(impulse, arm = Vector2.ZERO) { + this.velocity.add(impulse.multiply(this.inv_mass)) + this.rotation.value += arm.cross(impulse) * this.inv_inertia + } /** * Initializes the body to its given.Called by the world or an entity manager. * @@ -418,8 +427,8 @@ export class Body extends Component { this.bounds = new BoundingBox() if (entity != void 0) { this._movable.transform = this._transform - entity.manager.addComponent("transform",this._transform) - entity.manager.addComponent("movable",this._movable) + entity.manager.addComponent("transform", this._transform) + entity.manager.addComponent("movable", this._movable) } this.update() return @@ -451,9 +460,9 @@ export class Body extends Component { this.bounds.update(this.position) //this.angle = this.angle > 360 ? this.angle - 360 : this.angle < 0 ? 360 + this.angle : this.angle } - - destroy(){ - this.entity.manager.removeComponent("movable",this._movable) + + destroy() { + this.entity.manager.removeComponent("movable", this._movable) } toJson() { let obj = { @@ -486,8 +495,8 @@ export class Body extends Component { } /** * @@param {Shape} shape - */ - addShape(shape){ + */ + addShape(shape) { this.shapes.push(shape) } fromJson(obj) { From de719a801eab549fd81c2a7d3e3d46c7ec094c28 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Thu, 28 Dec 2023 10:32:46 +0300 Subject: [PATCH 22/41] [Physics] Fixed the method `Body.applyForce()` #fix --- src/physics/bodies/body.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/physics/bodies/body.js b/src/physics/bodies/body.js index d2d3f2d5..9f1c754e 100644 --- a/src/physics/bodies/body.js +++ b/src/physics/bodies/body.js @@ -402,13 +402,12 @@ export class Body extends Component { */ applyForce(force, arm = Vector2.ZERO) { this.acceleration.add(force.multiply(this.inv_mass)) - //Todo - correct this to torque. - this.rotation.value += arm.cross(force) * this.inv_inertia + this.torque.value += arm.cross(force) * this.inv_inertia } /** * Applies a force to a body affecting its direction of travel and rotation. * - * @param { Vector2} force The force to be applied. + * @param { Vector2} impulse The force to be applied. * @param { Vector2} [arm = Vector2] The collision arm. */ applyImpulse(impulse, arm = Vector2.ZERO) { From 03d1e6fe580877a202761c9e160b4c8fc12e90dd Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Thu, 28 Dec 2023 14:11:30 +0300 Subject: [PATCH 23/41] [Documentation] Added docs to animation module #new --- src/animations/tween.js | 81 ++++++++++++++++++++++++++++++---- src/animations/tweenManager.js | 11 ++++- 2 files changed, 83 insertions(+), 9 deletions(-) diff --git a/src/animations/tween.js b/src/animations/tween.js index ee78cd8e..b3e66d24 100644 --- a/src/animations/tween.js +++ b/src/animations/tween.js @@ -2,32 +2,70 @@ import { Interpolation, Easing } from "../math/index.js" /** * Component responsible for animations. * - * @template {T} + * @template T */ -export class Tween { +export class Tween{ + /** + * @type {number} + */ _duration = 0 + /** + * @type {boolean} + */ _repeat = false + /** + * @type {boolean} + */ active = false /** * @type {T} + * @private */ _to = null + /** + * @type {T} + * @private + */ _from = null + /** + * @type {T} + * @private + */ _into = null + /** + * @type {LerpFunc} + * @private + */ _interpolationFunc = Interpolation.Linear + /** + * @type {EasingFunc} + * @private + */ _easingFunction = Easing.linear + /** + * @type {number} + * @private + */ _timeTaken = 0 + /** + * @type {TweenUpdate} + * @private + */ _updateFunc = NoUpdateThrow + /** + * @type {Tween} + * @private + */ _next = null /** - *@template {T} - *@param {T} to - *@param {T} from - *@param {number} duration + *@param {T} into */ constructor(into) { this._into = into } + /** + * @param {Entity} entity + */ init(entity) { this.play() } @@ -63,24 +101,36 @@ export class Tween { stop() { this.active = false } + /** + * @param {TweenUpdate} callback + */ onUpdate(callback) { this._updateFunc = callback return this } + /** + * @param {EasingFunc} callback + */ easing(func) { this._easingFunction = func return this } + /** + * @param {LerpFunc} callback + */ interpolant(func) { this._interpolationFunc = func return this } + /** + * @param {number} dt + */ update(dt) { if (!this.active) return this._timeTaken += dt if (this._timeTaken >= this._duration) { - if(this._next !== void 0){ + if (this._next !== void 0) { this.stop() this._next.play() } @@ -102,6 +152,9 @@ export class Tween { this._into ) } + /** + * @param {Tween} next + */ chain(next) { this._next = next return this @@ -110,6 +163,7 @@ export class Tween { /** * @type Tween + * Todo - remove this */ let t = new Tween() @@ -124,7 +178,18 @@ let t = new Tween() * * @returns {void} */ - +/** + * @callback LerpFunc + * @param {number} p0 + * @param {number} p1 + * @param {number} t + * @returns {number} + */ +/** + * @callback EasingFunc + * @param {number} t + * @returns {number} + */ /** * @type {TweenUpdate} */ diff --git a/src/animations/tweenManager.js b/src/animations/tweenManager.js index 43182823..878fd51c 100644 --- a/src/animations/tweenManager.js +++ b/src/animations/tweenManager.js @@ -1,11 +1,20 @@ import {System} from "../ecs/index.js" export class TweenManager extends System { + /** + * @type {Tween[]} + */ objects = [] + /** + * @inheritdoc + * @param {Manager} manager + */ init(manager) { manager.setComponentList("tween", this.objects) } - + /** + * @inheritdoc + */ update(dt) { for (var i = 0; i < this.objects.length; i++) { let tween = this.objects[i] From 8cf8ce05d3b1cf964058d168d59c4a17bbd1b131 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Thu, 28 Dec 2023 15:19:40 +0300 Subject: [PATCH 24/41] [Root] Refactored `Sprite()` to inherit `Component()` and `World()` and `Renderer()` to inherit `System()` #change #internal --- src/physics/world/index.js | 5 +++-- src/render/renderers/renderer.js | 6 ++++-- src/render/sprites/sprite.js | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/physics/world/index.js b/src/physics/world/index.js index 6bba4a55..98093acd 100644 --- a/src/physics/world/index.js +++ b/src/physics/world/index.js @@ -6,11 +6,11 @@ import { ObjType } from "../settings.js" import { NaiveBroadphase } from "../broadphases/index.js" import { SATNarrowPhase } from "../narrowphase/index.js" import { Settings } from "../settings.js" - +import { System } from "../../ecs/index.js" /** * Class responsible for updating bodies,constraints and composites. */ -export class World { +export class World extends System{ /** * Used to check if a manifold is persistent. * @@ -125,6 +125,7 @@ export class World { enableIntergrate = true constructor() { + super() this.broadphase = new NaiveBroadphase(this) this.narrowphase = new SATNarrowPhase() } diff --git a/src/render/renderers/renderer.js b/src/render/renderers/renderer.js index 29f7739a..09fb21df 100644 --- a/src/render/renderers/renderer.js +++ b/src/render/renderers/renderer.js @@ -1,5 +1,6 @@ import { Clock } from '../../utils/clock.js' import { Camera } from "../camera.js" +import { System } from "../../ecs/index.js" /** * This is an abstract class from which different types of renderers are implemented. @@ -9,10 +10,10 @@ import { Camera } from "../camera.js" * @see WebGLRenderer * @see WebGPURenderer */ -export class Renderer { +export class Renderer extends System { /** * @type number - */ + */ _rafID = 0 /** * Used to throttle the frame rate. @@ -51,6 +52,7 @@ export class Renderer { * @param {HTMLCanvasElement} canvas element to draw on */ constructor(canvas, context) { + super() this.domElement = canvas this.ctx = context this.camera = new Camera(this) diff --git a/src/render/sprites/sprite.js b/src/render/sprites/sprite.js index fe93bc86..5c1b60e5 100644 --- a/src/render/sprites/sprite.js +++ b/src/render/sprites/sprite.js @@ -5,10 +5,9 @@ import { Component } from "../../ecs/index.js" * This is the base class used to render images and paths onto the renderer. * Extend it to create your custom behaviour. * - * @implements Component * TODO - ADD id property to this class and Group class. */ -export class Sprite { +export class Sprite extends Component{ /** * @private */ @@ -38,6 +37,7 @@ export class Sprite { * @param {Material} material */ constructor(geometry, material) { + super() this.geometry = geometry this.material = material } From a7877fa2e4f5749ce2bc6d6c1fcd7ae79d934841 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Fri, 29 Dec 2023 12:23:14 +0300 Subject: [PATCH 25/41] [Documentation] `System()` documented properly #change --- src/ecs/system.js | 52 ++++++++++++++++++----------------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/src/ecs/system.js b/src/ecs/system.js index b124479e..66dd0eb5 100644 --- a/src/ecs/system.js +++ b/src/ecs/system.js @@ -2,50 +2,38 @@ import { mixin, Err, Utils } from "../utils/index.js" /** * Updates components assigned to it. - * - * @interface */ export class System { - init() { + /** + * @param {Manager} manager + */ + init(manager) { Err.warnOnce("Please override the init method in the system " + this.constructor.name) } - update() { + /** + * @param {number} dt + */ + update(dt) { Err.warnOnce("Please override the update method in the system " + this.constructor.name) - } + /** + * @param {Component} component + */ add(component) { this.objects.push(component) } + /** + * @param {Component} component + */ remove(component) { let index = this.objects.indexOf(component) Utils.removeElement(this.objects, index) } + //Todo - Fix this + /** + * @param {any} system + */ static implement(system) { - mixin(System,system) + mixin(System, system) } -} - -/** - * - * @function - * @name System#add - * @param {Component} component - */ -/** - * - * @function - * @name System#remove - * @param {Component} component - */ -/** - * - * @function - * @name System#init - * @param {Manager} manager - */ -/** - * - * @function - * @name System#update - * @param {number} dt - */ \ No newline at end of file +} \ No newline at end of file From aa85c73ffdfc83653e606b1312e6aad200afda49 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Sat, 30 Dec 2023 11:33:25 +0300 Subject: [PATCH 26/41] [Render] Fixed no import of `Vector2()` in all derived geometries #fix #internal --- src/render/geometry/boxgeometry.js | 3 ++- src/render/geometry/linegeometry.js | 1 + src/render/geometry/trianglegeometry.js | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/render/geometry/boxgeometry.js b/src/render/geometry/boxgeometry.js index b4be849a..fb817f53 100644 --- a/src/render/geometry/boxgeometry.js +++ b/src/render/geometry/boxgeometry.js @@ -1,7 +1,8 @@ import {BufferGeometry} from "./geometry.js" +import {Vector2} from "../../math/index.js" export class BoxGeometry extends BufferGeometry{ - constructor(width,hieght){ + constructor(width,height){ let v1 = new Vector2(-width / 2, -height / 2) let v2 = new Vector2(-width / 2, height / 2) let v3 = new Vector2(width / 2, height / 2) diff --git a/src/render/geometry/linegeometry.js b/src/render/geometry/linegeometry.js index 5871bf07..5bf65c7c 100644 --- a/src/render/geometry/linegeometry.js +++ b/src/render/geometry/linegeometry.js @@ -1,4 +1,5 @@ import { BufferGeometry } from "./geometry.js" +import {Vector2} from "../../math/index.js" export class LineGeometry extends BufferGeometry { constructor(length) { diff --git a/src/render/geometry/trianglegeometry.js b/src/render/geometry/trianglegeometry.js index 429ca131..e3c460c6 100644 --- a/src/render/geometry/trianglegeometry.js +++ b/src/render/geometry/trianglegeometry.js @@ -1,4 +1,5 @@ import {BufferGeometry} from "./geometry.js" +import {Vector2} from "../../math/index.js" export class TriangleGeometry extends BufferGeometry{ constructor(base, height, angle) { From 295ee993dddcb5e6f95f4c570cf385db28647f09 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Sat, 30 Dec 2023 11:39:35 +0300 Subject: [PATCH 27/41] [animation] Refactored tweens as thier own component #refactor #internal --- src/animations/index.js | 3 +-- src/animations/tween/index.js | 2 ++ src/animations/{ => tween}/tween.js | 2 +- src/animations/{ => tween}/tweenManager.js | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 src/animations/tween/index.js rename src/animations/{ => tween}/tween.js (98%) rename src/animations/{ => tween}/tweenManager.js (90%) diff --git a/src/animations/index.js b/src/animations/index.js index 71bd3d3d..615af51f 100644 --- a/src/animations/index.js +++ b/src/animations/index.js @@ -1,2 +1 @@ -export * from "./tweenManager.js" -export * from "./tween.js" \ No newline at end of file +export * from "./tween/index.js" \ No newline at end of file diff --git a/src/animations/tween/index.js b/src/animations/tween/index.js new file mode 100644 index 00000000..71bd3d3d --- /dev/null +++ b/src/animations/tween/index.js @@ -0,0 +1,2 @@ +export * from "./tweenManager.js" +export * from "./tween.js" \ No newline at end of file diff --git a/src/animations/tween.js b/src/animations/tween/tween.js similarity index 98% rename from src/animations/tween.js rename to src/animations/tween/tween.js index b3e66d24..7edc7426 100644 --- a/src/animations/tween.js +++ b/src/animations/tween/tween.js @@ -1,4 +1,4 @@ -import { Interpolation, Easing } from "../math/index.js" +import { Interpolation, Easing } from "../../math/index.js" /** * Component responsible for animations. * diff --git a/src/animations/tweenManager.js b/src/animations/tween/tweenManager.js similarity index 90% rename from src/animations/tweenManager.js rename to src/animations/tween/tweenManager.js index 878fd51c..cf235bad 100644 --- a/src/animations/tweenManager.js +++ b/src/animations/tween/tweenManager.js @@ -1,4 +1,4 @@ -import {System} from "../ecs/index.js" +import {System} from "../../ecs/index.js" export class TweenManager extends System { /** From c6b6555c71a7222ddc71d464e89c6fa34bc4a42b Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Sat, 30 Dec 2023 17:12:22 +0300 Subject: [PATCH 28/41] [Physics] Trying to improve stability of physics engine by intergrating force before solving #fix #internal --- src/physics/world/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/physics/world/index.js b/src/physics/world/index.js index 98093acd..05dac3c8 100644 --- a/src/physics/world/index.js +++ b/src/physics/world/index.js @@ -234,6 +234,8 @@ export class World extends System{ let a = this.objects[i] if (a.mass) a.acceleration.add(this.gravitationalAcceleration) + a.velocity.add(a.acceleration.multiply(dt)) + a.acceleration.set(0,0) } } /** From b08b1464808368d03239cedd1f537322f1572cb3 Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Mon, 1 Jan 2024 22:51:33 +0300 Subject: [PATCH 29/41] [Documentation] Added even more documentation to existing code and corrected some #change #new --- dist/chaos.module.d.ts | 2 +- src/AI/paths/path.js | 11 ++- src/animations/tween/tween.js | 76 +++++++++-------- src/dataStructures/indexedList.js | 33 +++++++- src/dataStructures/pools/objectPool.js | 12 +-- src/ecs/component.js | 15 ++-- src/ecs/entity.js | 13 ++- src/events/eventDispatcher.js | 11 ++- src/intergrator/intergrator.js | 21 ++++- src/intergrator/movableComponent.js | 8 +- src/loader/index.js | 50 +++++++++-- src/math/interpolation.js | 111 ++++++++++++++++++++++++- src/physics/broadphases/Quadtree.js | 12 ++- src/physics/constraints/constraint.js | 28 ++++++- src/physics/narrowphase/Narrowphase.js | 8 ++ src/physics/shapes/geometry.js | 4 +- src/physics/shapes/line.js | 2 +- src/raycaster/manager.js | 21 ++++- src/raycaster/ray.js | 37 ++++++++- src/raycaster/raycaster.js | 43 +++++++++- src/render/camController.js | 21 +++-- src/render/geometry/geometry.js | 3 + src/render/sprites/bodysprite.js | 9 +- src/typedef/EasingFunc.js | 5 ++ src/typedef/manifold.js | 2 +- 25 files changed, 462 insertions(+), 96 deletions(-) create mode 100644 src/typedef/EasingFunc.js diff --git a/dist/chaos.module.d.ts b/dist/chaos.module.d.ts index 785c21f8..adb1dde3 100644 --- a/dist/chaos.module.d.ts +++ b/dist/chaos.module.d.ts @@ -243,7 +243,7 @@ export class BodySprite extends Sprite { drawBounds: boolean; drawPosition: boolean; render(ctx: CanvasRenderingContext2D, dt: number): void; - _drawCenter(body: any, ctx: any): void; + _drawCenter(body: any, ctx: any): void; private _drawVelocity; private _drawBound; private _drawShapes; diff --git a/src/AI/paths/path.js b/src/AI/paths/path.js index cbc1f318..a380691c 100644 --- a/src/AI/paths/path.js +++ b/src/AI/paths/path.js @@ -68,7 +68,7 @@ export class Path { return this } /** - * private + * @private */ advance() { if (this._points.length < 2) return false @@ -108,15 +108,24 @@ export class Path { ) return this._lerpedPoint } + /** + * @returns {Vector2[]} + */ current() { return [ this._points[this._way[0]], this._points[this._way[1]] ] } + /** + * @returns {Vector2} + */ point() { return this._lerpedPoint } + /** + * @type {Vector2[]} + */ get path() { return this._points } diff --git a/src/animations/tween/tween.js b/src/animations/tween/tween.js index 7edc7426..cb617ab2 100644 --- a/src/animations/tween/tween.js +++ b/src/animations/tween/tween.js @@ -4,7 +4,7 @@ import { Interpolation, Easing } from "../../math/index.js" * * @template T */ -export class Tween{ +export class Tween { /** * @type {number} */ @@ -160,60 +160,66 @@ export class Tween{ return this } } - -/** - * @type Tween - * Todo - remove this - */ -let t = new Tween() - -/** - * @template {T} - * @callback TweenUpdate - * @param {Function} lerpFunc - * @param {T} to - * @param {T} from - * @param {number} t - * @param {T} into - * - * @returns {void} - */ -/** - * @callback LerpFunc - * @param {number} p0 - * @param {number} p1 - * @param {number} t - * @returns {number} - */ -/** - * @callback EasingFunc - * @param {number} t - * @returns {number} - */ /** + * @template T * @type {TweenUpdate} */ export function Vector2Update(lerpFunc, to, from, t, into) { into.x = lerpFunc(from.x, to.x, t) into.y = lerpFunc(from.y, to.y, t) } +/** + * @template T + * @type {TweenUpdate} + */ export function Vector3Update(lerpFunc, to, from, t, into) { into.x = lerpFunc(from.x, to.x, t) into.y = lerpFunc(from.y, to.y, t) into.z = lerpFunc(from.z, to.z, t) } +/** + * @template T + * @type {TweenUpdate} + */ export function ColorUpdate(lerpFunc, to, from, t, into) { into.r = lerpFunc(from.r, to.r, t) into.g = lerpFunc(from.g, to.g, t) into.b = lerpFunc(from.b, to.b, t) into.a = lerpFunc(from.a, to.a, t) } - +/** + * @template T + * @type {TweenUpdate} + */ export function AngleUpdate(lerpFunc, to, from, t, into) { into.rad = lerpFunc(from.rad, to.rad, t) } - -function NoUpdateThrow() { +/** + * @template T + * @type {TweenUpdate} + */ +function NoUpdateThrow(lerpFunc, to, from, t, into) { throw "The Tween does not have a valid onUpdate callback." -} \ No newline at end of file +} + +/** + * @template {T} + * @callback TweenUpdate + * @param {LerpFunc} lerpFunc + * @param {T} to + * @param {T} from + * @param {number} t + * @param {T} into + * + * @returns {void} + */ + +/** + * @callback LerpFunc + * @param {number} p0 + * @param {number} p1 + * @param {number} t + * @returns {number} + */ + \ No newline at end of file diff --git a/src/dataStructures/indexedList.js b/src/dataStructures/indexedList.js index 67ef809b..addf041e 100644 --- a/src/dataStructures/indexedList.js +++ b/src/dataStructures/indexedList.js @@ -1,13 +1,34 @@ +/** + * @template T + */ export class IndexedList { + /** + * @private + * @type {Map} + */ _keys = new Map() + /** + * @private + * @type {T[]} + */ _list = [] - get(name){ + /** + * @param {string} name + */ + get(name) { return this._list[this._keys.get(name)] } + /** + * @param {string} name + * @param {T} value + */ set(name, value) { - this._keys.set(name,this._list.length) + this._keys.set(name, this._list.length) this._list.push(value) } + /** + * @param {string} name + */ remove(name) { this._list.splice( this._keys.get(name), @@ -15,9 +36,15 @@ export class IndexedList { ) this._keys.delete(name) } - keys(){ + /** + * @returns {string[]} + */ + keys() { return this._keys.keys() } + /** + * @returns {T[]} + */ values() { return this._list } diff --git a/src/dataStructures/pools/objectPool.js b/src/dataStructures/pools/objectPool.js index 1db106e0..27029be5 100644 --- a/src/dataStructures/pools/objectPool.js +++ b/src/dataStructures/pools/objectPool.js @@ -7,7 +7,7 @@ export class Pool { /** * List of objects * - * @type any[] + * @type T[] */ _pool = [] /** @@ -20,6 +20,8 @@ export class Pool { } /** * The number of objects available in the pool. + * + * @type {number} */ get size() { return this._pool.length @@ -42,7 +44,7 @@ export class Pool { /** * Gives an object ownership. * - * @returns Object + * @returns {T} */ give() { if (this._pool.length) { @@ -54,7 +56,7 @@ export class Pool { * Takes an object's ownership. * Do not use the taken object and remove all references of it outside otherwise you will get some wierd behaviour. * - * @param {Object} obj + * @param {T} obj */ take(obj) { this._pool.push(this.destroy(obj)) @@ -63,7 +65,7 @@ export class Pool { * Does some cleanup on a taken object. * * @protected - * @param {Object} obj + * @param {T} obj */ destroy(obj) { for (var prop in obj) { @@ -75,7 +77,7 @@ export class Pool { * Creates a new object. * * @protected - * @returns object + * @returns T */ create() { return {} diff --git a/src/ecs/component.js b/src/ecs/component.js index 8c52497e..60039de5 100644 --- a/src/ecs/component.js +++ b/src/ecs/component.js @@ -28,7 +28,7 @@ export class Component { } /** * @param {Entity} entity - */ + */ init(entity) {} /** * @param {number} dt @@ -37,24 +37,29 @@ export class Component { Err.warnOnce("Please override the update function in the component " + proto.constructor.name) } /** + * @param {Entity} entity * @param {string} n */ - get(entity,n) { + get(entity, n) { return entity.getComponent(n); } /** + * @param {Entity} entity * @param {...string} names + * @rheows */ - requires(entity,...names) { + requires(entity, ...names) { for (var i = 0; i < names.length; i++) if (!entity.has(names[i])) Err.throws(`The component \`${this.CHOAS_CLASSNAME}\` requires another component \`${names[i]}\` but cannot find it in the Entity with id ${entity.id}`) } /** + * @param {Entity} entity * @param {CircleBounding | BoxBounding} bound - * @param {Entity} [target=[]] + * @param {Entity[]} [target=[]] + * @returns {Entity[]} */ - query(entity,bound, target = []) { + query(entity, bound, target = []) { return entity.query(bound, target) } static fromJson() { diff --git a/src/ecs/entity.js b/src/ecs/entity.js index e49c4844..a29a883c 100644 --- a/src/ecs/entity.js +++ b/src/ecs/entity.js @@ -39,10 +39,15 @@ export class Entity { * @type {boolean} */ active = false - + /** + * @type {string} + */ get CHAOS_OBJ_TYPE() { return "entity" } + /** + * @type {string} + */ get CHAOS_CLASSNAME() { return this.constructor.name.toLowerCase() } @@ -249,12 +254,6 @@ export class Entity { } return entity } - /** - * @returns {{ - deg: number, - type:string - }} - */ toJson() { let obj = { comps: {}, diff --git a/src/events/eventDispatcher.js b/src/events/eventDispatcher.js index 465ce8ef..edd9aa60 100644 --- a/src/events/eventDispatcher.js +++ b/src/events/eventDispatcher.js @@ -28,7 +28,7 @@ export class EventDispatcher { * Adds an event handler to an event dispatcher. * * @param {string} name name of the event. - * @param {function} handler Function to be called when the event is triggered. + * @param {EventHandlerFunc} handler Function to be called when the event is triggered. */ add(name, handler) { if (name in this.handlers) { @@ -37,4 +37,11 @@ export class EventDispatcher { } this.handlers[name] = [handler] } -} \ No newline at end of file +} + +/** + * @callback EventHandlerFunc + * @param {any} data + * + * @returns {void} +*/ \ No newline at end of file diff --git a/src/intergrator/intergrator.js b/src/intergrator/intergrator.js index 14b8e89d..391d3120 100644 --- a/src/intergrator/intergrator.js +++ b/src/intergrator/intergrator.js @@ -1,21 +1,36 @@ import { System } from "../ecs/index.js" import { Vector2 } from "../math/index.js" -import {Utils} from "../utils/index.js" +import { Utils } from "../utils/index.js" export class Intergrator extends System { + /** + * @type {boolean} + */ active = false + /** + * @type {typeof EulerSolver.solve} + */ solver = EulerSolver.solve + /** + * @type {Movable} + */ objects = [] constructor() { super() } + /** + * @inheritdoc + */ init(manager) { const world = manager.getSystem("world") if (world) world.enableIntergrate = false this.active = true - + manager.setComponentList("movable", this.objects) } + /** + * @inheritdoc + */ update(dt) { for (let i = 0; i < this.objects.length; i++) { if (this.objects[i] == void 0) return @@ -34,6 +49,8 @@ const a = new Vector2() */ export class EulerSolver { /** + * @param {Transform} transform + * @param {Movable} movable * @param {number} dt */ static solve(transform, movable, dt) { diff --git a/src/intergrator/movableComponent.js b/src/intergrator/movableComponent.js index cc5b543b..46fb0099 100644 --- a/src/intergrator/movableComponent.js +++ b/src/intergrator/movableComponent.js @@ -5,6 +5,10 @@ import { Vector2, Angle } from "../math/index.js" * */ export class Movable extends Component { + /** + * @type {Transform} + */ + transform = null /** * * @param {number} x * @param {number} y @@ -13,12 +17,14 @@ export class Movable extends Component { */ constructor(x, y, a) { super() - this.transform = null this.velocity = new Vector2(x, y) this.rotation = new Angle(a) this.acceleration = new Vector2() this.torque = new Angle() } + /** + * @inheritdoc + */ init(entity) { this.requires(entity, "transform") if (!this.transform) diff --git a/src/loader/index.js b/src/loader/index.js index 31e0d7ce..9ba08808 100644 --- a/src/loader/index.js +++ b/src/loader/index.js @@ -2,16 +2,42 @@ import { Err } from "../utils/index.js" export class Loader { + /** + * @private + */ + _toload = [] + imgs = {} + sfx = {} + json = {} + /** + * @type {number} + * @private + */ + _progressBytes = 0 + /** + * @private + * @type {number} + */ + _totalBytes = 0 + /** + * @peivatw + * @type {number} + */ + _filesErr = 0 + /** + * @private + * @type {number} + */ + _filesLoaded = 0 + /** + * @private + * @type {number} + */ + _totalFileNo = 0 + /** + * @param {Manager} manager + */ constructor(manager) { - this._toload = [] - this.imgs = {} - this.sfx = {} - this.json = {} - this._progressBytes = 0 - this._totalBytes = 0 - this._filesErr = 0 - this._filesLoaded = 0 - this._totalFileNo = 0 const that = this this.onfinish = null this._handlers = { @@ -58,6 +84,9 @@ export class Loader { } } } + /** + * @private + */ _getName(url) { if (url.includes("/")) { let tmp = url.split("/") @@ -65,6 +94,9 @@ export class Loader { } return url.split(".")[0] } + /** + * @private + */ _getType(url) { let ext if (url.includes("/")) { diff --git a/src/math/interpolation.js b/src/math/interpolation.js index e6a7bf43..65892e55 100644 --- a/src/math/interpolation.js +++ b/src/math/interpolation.js @@ -1,70 +1,127 @@ export const Easing = { + /** + * @type {EasingFunc} + */ linear: function(x) { return x; }, + /** + * @type {EasingFunc} + */ quadraticIn: function(x) { return x * x; }, + /** + * @type {EasingFunc} + */ quadraticOut: function(x) { return x * (2 - x); }, + /** + * @type {EasingFunc} + */ quadraticInOut: function(x) { if ((x *= 2) < 1) { return 0.5 * x * x; } return -0.5 * (--x * (x - 2) - 1); }, + /** + * @type {EasingFunc} + */ cubicIn: function(x) { return x * x * x; }, + /** + * @type {EasingFunc} + */ cubicOut: function(x) { return --x * x * x + 1; }, + /** + * @type {EasingFunc} + */ cubicInOut: function(x) { if ((x *= 2) < 1) { return 0.5 * x * x * x; } return 0.5 * ((x -= 2) * x * x + 2); }, + /** + * @type {EasingFunc} + */ quarticIn: function(x) { return x * x * x * x; }, + /** + * @type {EasingFunc} + */ quarticOut: function(x) { return 1 - --x * x * x * x; }, + /** + * @type {EasingFunc} + */ quarticInOut: function(x) { if ((x *= 2) < 1) { return 0.5 * x * x * x * x; } return -0.5 * ((x -= 2) * x * x * x - 2); }, + /** + * @type {EasingFunc} + */ quinticIn: function(x) { return x * x * x * x * x; }, + /** + * @type {EasingFunc} + */ quinticOut: function(x) { return --x * x * x * x * x + 1; }, + /** + * @type {EasingFunc} + */ quinticInOut: function(x) { if ((x *= 2) < 1) { return 0.5 * x * x * x * x * x; } return 0.5 * ((x -= 2) * x * x * x * x + 2); }, + /** + * @type {EasingFunc} + */ sinusoidalIn: function(x) { return 1 - Math.sin(((1.0 - x) * Math.PI) / 2); }, + /** + * @type {EasingFunc} + */ sinusoidalOut: function(x) { return Math.sin((x * Math.PI) / 2); }, + /** + * @type {EasingFunc} + */ sinusoidalInOut: function(x) { return 0.5 * (1 - Math.sin(Math.PI * (0.5 - x))); }, + /** + * @type {EasingFunc} + */ exponentialIn: function(x) { return x === 0 ? 0 : Math.pow(1024, x - 1); }, + /** + * @type {EasingFunc} + */ exponentialOut: function(x) { return x === 1 ? 1 : 1 - Math.pow(2, -10 * x); }, + /** + * @type {EasingFunc} + */ exponentialInOut: function(x) { if (x === 0) { return 0; @@ -77,18 +134,30 @@ export const Easing = { } return 0.5 * (-Math.pow(2, -10 * (x - 1)) + 2); }, + /** + * @type {EasingFunc} + */ circularIn: function(x) { return 1 - Math.sqrt(1 - x * x); }, + /** + * @type {EasingFunc} + */ circularOut: function(x) { return Math.sqrt(1 - --x * x); }, + /** + * @type {EasingFunc} + */ circularInOut: function(x) { if ((x *= 2) < 1) { return -0.5 * (Math.sqrt(1 - x * x) - 1); } return 0.5 * (Math.sqrt(1 - (x -= 2) * x) + 1); }, + /** + * @type {EasingFunc} + */ elasticIn: function(x) { if (x === 0) { return 0; @@ -98,6 +167,9 @@ export const Easing = { } return -Math.pow(2, 10 * (x - 1)) * Math.sin((x - 1.1) * 5 * Math.PI); }, + /** + * @type {EasingFunc} + */ elasticOut: function(x) { if (x === 0) { return 0; @@ -107,6 +179,9 @@ export const Easing = { } return Math.pow(2, -10 * x) * Math.sin((x - 0.1) * 5 * Math.PI) + 1; }, + /** + * @type {EasingFunc} + */ elasticInOut: function(x) { if (x === 0) { return 0; @@ -120,14 +195,23 @@ export const Easing = { } return 0.5 * Math.pow(2, -10 * (x - 1)) * Math.sin((x - 1.1) * 5 * Math.PI) + 1; }, + /** + * @type {EasingFunc} + */ backIn: function(x) { var s = 1.70158; return x === 1 ? 1 : x * x * ((s + 1) * x - s); }, + /** + * @type {EasingFunc} + */ backOut: function(x) { var s = 1.70158; return x === 0 ? 0 : --x * x * ((s + 1) * x + s) + 1; }, + /** + * @type {EasingFunc} + */ backInOut: function(x) { var s = 1.70158 * 1.525; if ((x *= 2) < 1) { @@ -135,9 +219,15 @@ export const Easing = { } return 0.5 * ((x -= 2) * x * ((s + 1) * x + s) + 2); }, + /** + * @type {EasingFunc} + */ bounceIn: function(x) { return 1 - Easing.bounceOut(1 - x); }, + /** + * @type {EasingFunc} + */ bounceOut: function(x) { if (x < 1 / 2.75) { return 7.5625 * x * x; @@ -152,6 +242,9 @@ export const Easing = { return 7.5625 * (x -= 2.625 / 2.75) * x + 0.984375; } }, + /** + * @type {EasingFunc} + */ bounceInOut: function(x) { if (x < 0.5) { return Easing.bounceIn(x * 2) * 0.5; @@ -161,9 +254,17 @@ export const Easing = { } export const Interpolation = { + /** + * @param {number} p0 + * @param {number} p1 + * @param {number} t + * + * @returns {number} + */ Linear: function(p0, p1, t) { return (p1 - p0) * t + p0 }, + //Todo - remove this Bernstein and Factorial. Bernstein: function(n, i) { const fc = Interpolation.Utils.Factorial @@ -187,7 +288,15 @@ export const Interpolation = { return s } })(), - + /** + * @param {number} p0 + * @param {number} p1 + * @param {number} p2 + * @param {number} p3 + * @param {number} t + * + * @returns {number} + */ CatmullRom: function(p0, p1, p2, p3, t) { const v0 = (p2 - p0) * 0.5 const v1 = (p3 - p1) * 0.5 diff --git a/src/physics/broadphases/Quadtree.js b/src/physics/broadphases/Quadtree.js index a9b10e60..98a7cd3d 100644 --- a/src/physics/broadphases/Quadtree.js +++ b/src/physics/broadphases/Quadtree.js @@ -368,6 +368,9 @@ export class QuadTreeBroadphase extends Broadphase { if (maxdepth) this._root.split(maxdepth) } + /** + * @private + */ _insert(client) { client.bounds.copy(client.body.bounds) if (!this._root.contains(obj.bounds)) @@ -385,6 +388,9 @@ export class QuadTreeBroadphase extends Broadphase { } this._insert(client) } + /** + * @private + */ _remove(client) { return this._root.removeObject(obj) } @@ -420,7 +426,7 @@ export class QuadTreeBroadphase extends Broadphase { /** * A depth first search of the quadtree that applies the given function to its nodes. * - * @param {Function} func The function that checks every node unless it returns true. + * @param {Traverser} func The function that checks every node unless it returns true. * */ traverse(func) { @@ -442,7 +448,7 @@ export class QuadTreeBroadphase extends Broadphase { * Resizes a quadtree to a new bound size. * This method should not be used without care. * - * @param {Bounds} bounds. + * @param {Bounds} bounds * */ recalculateBounds(bounds) { @@ -473,4 +479,4 @@ export class QuadTreeBroadphase extends Broadphase { * @callback Traverser * @param {Node} node * @returns {boolean} -*/ \ No newline at end of file + */ \ No newline at end of file diff --git a/src/physics/constraints/constraint.js b/src/physics/constraints/constraint.js index be37ef51..496315b2 100644 --- a/src/physics/constraints/constraint.js +++ b/src/physics/constraints/constraint.js @@ -9,6 +9,30 @@ import { Vector2 } from "../../math/index.js" * @see SpringConstraint */ export class Constraint { + /** + * @type {Vector2} + */ + localA = null + /** + * @type {Vector2} + */ + localB = null + /** + * @type {Body} + */ + body1 = null + /** + * @type {Body} + */ + body2 = null + /**: + * @type {number} + */ + stiffness = 50 + /** + * @type {number} + */ + dampening = 0.03 /** * @param {Body} body1 * @param {Body} body2 @@ -20,8 +44,6 @@ export class Constraint { this.body2 = body2 this.localA = localA || new Vector2() this.localB = localB || new Vector2() - this.stiffness = 50 - this.dampening = 0.03 } /** * Determine type of object this is in the world. @@ -71,7 +93,7 @@ export class Constraint { localB: this.localB.toJson(), stiffness: this.stiffness, dampening: this.dampening, - type:this.CHAOS_OBJ_TYPE + type: this.CHAOS_OBJ_TYPE } } fromJson(obj, world) { diff --git a/src/physics/narrowphase/Narrowphase.js b/src/physics/narrowphase/Narrowphase.js index 174174dc..bcb469c5 100644 --- a/src/physics/narrowphase/Narrowphase.js +++ b/src/physics/narrowphase/Narrowphase.js @@ -1,5 +1,13 @@ export class NarrowPhase{ + /** + * @type {Map} + */ records = new Map() + /** + * @param {CollisionPair[]} contactList + * @param {Manifold[]} clmds + * @returns {Manifold[]} + */ getCollisionPairs(contactList,clmds){ } } \ No newline at end of file diff --git a/src/physics/shapes/geometry.js b/src/physics/shapes/geometry.js index 1f2b4d33..026fe604 100644 --- a/src/physics/shapes/geometry.js +++ b/src/physics/shapes/geometry.js @@ -33,7 +33,7 @@ export class Geometry { } /** * @param {number} rad - * @param { Vector2[]} target + * @param {Vector2[]} target */ getNormals(rad, target) { target = target || [] @@ -68,7 +68,7 @@ export class Geometry { * @param {number} n * @param { Vector2[]} vertices * @param { Vector2} pos - * @patam {number} rad + * @param {number} rad */ transform(vertices, pos, rad, n) { for (let i = 0; i < this.vertices.length; i++) { diff --git a/src/physics/shapes/line.js b/src/physics/shapes/line.js index a35a17bc..ae38cc61 100644 --- a/src/physics/shapes/line.js +++ b/src/physics/shapes/line.js @@ -9,7 +9,7 @@ export class Line extends Shape { /** * @param {number} length * @param { Vector2} offset - * @param {number} pffsetAngle + * @param {number} offsetAngle */ constructor(length,offset,offsetAngle) { let start = new Vector2(1).multiply(length / 2), diff --git a/src/raycaster/manager.js b/src/raycaster/manager.js index a1e5f515..29bc6a6b 100644 --- a/src/raycaster/manager.js +++ b/src/raycaster/manager.js @@ -1,16 +1,31 @@ import { System } from "../ecs/index.js" export class RaycastManager extends System { + /** + * @private + * @type {Raycaster[]} + */ objects = [] + /** + * @private + * @type {Body[]} + */ bodies = null + /** + * @inheritdoc + * @param {Manager} manager + */ init(manager) { if (!manager.getSystem("world")) throw "World is required for running Raycast system." - manager.setComponentList("raycaster",this.objects) + manager.setComponentList("raycaster", this.objects) this.bodies = manager.getComponentList("body") - + } - update(){ + /** + * @inheritdoc + */ + update(dt) { for (let i = 0; i < this.objects.length; i++) { this.objects[i].update(this.bodies) } diff --git a/src/raycaster/ray.js b/src/raycaster/ray.js index e3339695..7740c02f 100644 --- a/src/raycaster/ray.js +++ b/src/raycaster/ray.js @@ -1,29 +1,64 @@ import { Vector2 } from "../math/index.js" export class Ray { + /** + * @type {number} + */ maxLength = 1000; - constructor(origin = new Vector2(), direction = new Vector2()) { + /** + * @private + * @type {Vector2} + */ + _origin = null; + /** + * @private + * @type {Vector2} + */ + _direction = null; + /** + * @param {Vector2} origin + * @param {Vector2} direction + */ + constructor(origin = new Vector2(0, 1), direction = new Vector2()) { this._origin = origin this._direction = direction } + /** + * @type {Vector2} + */ get direction() { return this._direction } set direction(x) { this._direction.copy(x) } + /** + * @type {Vector2} + */ get origin() { return this._origin } set origin(x) { this._origin.copy(x) } + /** + * @param {number} x + * @param {number} y + */ setOrigin(x, y) { this._origin.set(x, y) } + /** + * @param {number} x + * @param {number} y + */ setDirection(x, y) { this._direction.set(x, y) } + /** + * @param {number} x + * @param {number} y + */ lookAt(x, y) { this._direction.set( x - this._origin.x, diff --git a/src/raycaster/raycaster.js b/src/raycaster/raycaster.js index 48781be0..3e445e11 100644 --- a/src/raycaster/raycaster.js +++ b/src/raycaster/raycaster.js @@ -5,11 +5,33 @@ import { Vector2 } from "../math/index.js" import { RayCastModes, RayCollisionResult, RayPoint, RaycastResult } from "./raycastresult.js" export class Raycaster extends Component { + /** + * @type {Ray[]} + */ rays = [] + /** + * @type {Ray[]} + */ collisionResults = [] + /** + * @private + * @type {Ray[]} + */ _number = 0 + /** + * @private + * @type {Ray[]} + */ _angle = 0 + /** + * @private + * @type {Ray[]} + */ _transform = null + /** + * @private + * @type {number} + */ _lastangle = 0 mode = RayCastModes.ANY constructor(number = 1, angleSpace = 0) { @@ -27,6 +49,9 @@ export class Raycaster extends Component { if (this._angle == 0) break } } + /** + * + */ update(bodies) { this.collisionResults = [] const angle = this._transform.orientation.value @@ -49,6 +74,9 @@ export class Raycaster extends Component { } } } + /** + * @private + */ testCircle(position, radius, body) { let results = new RaycastResult() for (let i = 0; i < this.rays.length; i++) { @@ -58,6 +86,9 @@ export class Raycaster extends Component { } this.collisionResults.push(results) } + /** + * @private + */ testVertices(vertices, body) { let results = new RaycastResult() for (let i = 0; i < this.rays.length; i++) { @@ -68,7 +99,9 @@ export class Raycaster extends Component { this.collisionResults.push(results) } } - +/** + * @private + */ function testray(ray, vertices, body) { const origin = ray.origin const direction = ray.direction @@ -103,6 +136,9 @@ function testray(ray, vertices, body) { return results } +/** + * @private + */ function testSingleEdge(v1, v2, or, dir) { const x1 = v1.x const y1 = v1.y @@ -130,6 +166,9 @@ function testSingleEdge(v1, v2, or, dir) { return null } +/** + * @private + */ function testraycircle(ray, center, radius, body) { const results = new RayCollisionResult(ray, body) @@ -143,7 +182,7 @@ function testraycircle(ray, center, radius, body) { const x4 = x3 - x1 const y4 = y3 - y1 const r = radius - + const proj = x2 * x4 + y2 * y4 const delta = proj * proj - ((x4 * x4 + y4 * y4) - r * r) const sqrtDelta = Math.sqrt(delta) diff --git a/src/render/camController.js b/src/render/camController.js index 082dab5c..2f7ef117 100644 --- a/src/render/camController.js +++ b/src/render/camController.js @@ -2,21 +2,30 @@ import { Vector2 } from '../math/index.js' export class CamController { /** - * @readonly - * @type Vector2 + * @type {Vector2} */ offset = new Vector2() + /** + * @type {Transform} + */ + transform = null + /** + * @type {Vector2 | null} + */ + targetPosition = null + /** + * @type {Angle | null} + */ + targetOrientation = null /** * @param {Camera} camera */ + constructor(camera) { this.transform = camera.transform - this.offset = new Vector2() - this.targetPosition = null - this.targetOrientation = null } /** - * @param { Vector2} position + * @param {Vector2} position * @param {Angle} orientation */ follow(position, orientation = null) { diff --git a/src/render/geometry/geometry.js b/src/render/geometry/geometry.js index 45ada197..81c8fe03 100644 --- a/src/render/geometry/geometry.js +++ b/src/render/geometry/geometry.js @@ -25,6 +25,9 @@ export class BufferGeometry { init(ctx) { this.updateVertices(this.vertices) } + /** + * @param {Vector2[]} data + */ updateVertices(data){ const path = this.drawable = new Path2D() vertices(path, data, true) diff --git a/src/render/sprites/bodysprite.js b/src/render/sprites/bodysprite.js index 49d5ea34..f6fd350a 100644 --- a/src/render/sprites/bodysprite.js +++ b/src/render/sprites/bodysprite.js @@ -33,7 +33,7 @@ class BodySprite extends Sprite { * @type {boolean} */ drawBounds = false - /** + /** * Determine whether to draw the position of the body. * * @type {boolean} @@ -53,7 +53,7 @@ class BodySprite extends Sprite { * @inheritdoc * @param {CanvasRenderingContext2D} ctx * @param {number} dt - */ + */ render(ctx, dt) { if (this.body.physicsType == ObjType.COMPOSITE) { @@ -71,6 +71,11 @@ class BodySprite extends Sprite { if (this.drawPosition) this._drawCenter(this.body, ctx) } + /** + * @private + * @param {Body} body + * @param {CanvasRenderingContext2D} renderer + */ _drawCenter(body, ctx) { ctx.beginPath() circle( diff --git a/src/typedef/EasingFunc.js b/src/typedef/EasingFunc.js new file mode 100644 index 00000000..6fb2a3d5 --- /dev/null +++ b/src/typedef/EasingFunc.js @@ -0,0 +1,5 @@ +/** + * @callback EasingFunc + * @param {number} t + * @returns {number} + */ \ No newline at end of file diff --git a/src/typedef/manifold.js b/src/typedef/manifold.js index 9ed559e6..a09b1551 100644 --- a/src/typedef/manifold.js +++ b/src/typedef/manifold.js @@ -5,7 +5,7 @@ */ /** - * @typedef Manifold + * @typedef transform = null * @property {Body} bodyA * @property {Body} bodyB * @property {ContactManifold} contactData From c8e8a5081429a8aa1b93c64596cc66612c44050c Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:25:23 +0300 Subject: [PATCH 30/41] [Documentation] Refactored documentation of some modules #refactor --- .gitignore | 3 +- src/audio/audio.js | 5 +++- src/debuggers/fpsdebugger.js | 4 ++- src/debuggers/raycastDebugger.js | 3 ++ src/ecs/component.js | 16 +++++++++-- src/events/signals.js | 47 ++++++++++++++++++++++++++------ src/math/math.js | 24 ++++++++-------- src/math/vector.js | 25 +++++++++++------ src/physics/shapes/triangle.js | 7 ++++- src/raycaster/raycaster.js | 5 +++- src/raycaster/raycastresult.js | 37 +++++++++++++------------ src/render/sprites/sprite.js | 14 ++++++++++ 12 files changed, 137 insertions(+), 53 deletions(-) diff --git a/.gitignore b/.gitignore index 8e810f88..bee8cbcf 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ res.json tests *.res.js *.txt -demos \ No newline at end of file +demos +common.js \ No newline at end of file diff --git a/src/audio/audio.js b/src/audio/audio.js index 13f3fa7c..489d3d3c 100644 --- a/src/audio/audio.js +++ b/src/audio/audio.js @@ -12,9 +12,10 @@ export class Sfx { * @type {AudioBufferSourceNode} */ _source = null + //Todo - Check to see if this one works /** * @private - * @type {function} + * @type {Function} */ _onended = null /** @@ -66,6 +67,8 @@ export class Sfx { } /** * Set callback when the sound finishes playing. + * + * @type {Function} */ set onended(x) { this._onended = x diff --git a/src/debuggers/fpsdebugger.js b/src/debuggers/fpsdebugger.js index a4a51070..daed4f48 100644 --- a/src/debuggers/fpsdebugger.js +++ b/src/debuggers/fpsdebugger.js @@ -1,5 +1,7 @@ //import {System} from "../ecs/index.js" - +/** + * @param {Manager} manager + */ export function fpsDebugger(manager) { const container = document.body.appendChild(document.createElement("div")) diff --git a/src/debuggers/raycastDebugger.js b/src/debuggers/raycastDebugger.js index ced2f464..4d3ada0b 100644 --- a/src/debuggers/raycastDebugger.js +++ b/src/debuggers/raycastDebugger.js @@ -1,3 +1,6 @@ +/** + * @param {Manager} manager + */ export function raycastDebugger(manager) { manager.registerSystem("raycastDebugger", { renderer: null, diff --git a/src/ecs/component.js b/src/ecs/component.js index 60039de5..4956fcb3 100644 --- a/src/ecs/component.js +++ b/src/ecs/component.js @@ -62,12 +62,24 @@ export class Component { query(entity, bound, target = []) { return entity.query(bound, target) } - static fromJson() { + /** + * @template {System} T + * @param {*} obj + * @param {T} system + */ + fromJson(obj, system) { throw "Implement static method fromJson() in your component " + this.CHOAS_CLASSNAME + } - static toJson() { + /** + * @returns {*} + */ + toJson() { throw "Implement static method toJson() in your component " + this.CHOAS_CLASSNAME } + /** + * @param {*} component + */ static implement(component) { Utils.inheritComponent(component) } diff --git a/src/events/signals.js b/src/events/signals.js index 41df380f..de973c37 100644 --- a/src/events/signals.js +++ b/src/events/signals.js @@ -1,34 +1,63 @@ +/** + * @template T + */ export class Signal { _listeners = [] + /** + * @type {T} + */ _value = null - constructor(value){ + /** + * @param {T} value + */ + constructor(value) { this._value = value } + /** + * @type {T} + */ + get value() { + return this._value + } set value(x) { this._value = x for (var i = 0; i < this._listeners.length; i++) { let func = this._listeners[i] func.listener(this) - if(func.callOnce) - this.removeListener(func.listener) + if (func.callOnce) + this.removeListener(func.listener) } } - get value() { - return this._value - } - addListener(listener,callOnce=false) { + /** + * @param {signalListener} listener + * @param {boolean} callOnce + */ + addListener(listener, callOnce = false) { this._listeners.push({ listener, callOnce }) } + /** + * @param {signalListener} listener + */ removeListener(listener) { for (var i = 0; i < this._listeners.length; i++) { if (this._listeners[i].listener == listener) return this._detach(i) } } - _detach(bindingIndex){ + /** + * @private + * @param {number} bindingIndex + */ + _detach(bindingIndex) { this._listeners.splice(i, 1) } -} \ No newline at end of file +} + +/** + * @callback signalListener + * @param {Signal} value + * @returns {void} + */ \ No newline at end of file diff --git a/src/math/math.js b/src/math/math.js index 1551d3f5..71578c36 100644 --- a/src/math/math.js +++ b/src/math/math.js @@ -1,4 +1,4 @@ -import {DEG2RAD,RAD2DEG} from "./constants.js" +import { DEG2RAD, RAD2DEG } from "./constants.js" /** * Creates a random number between the parameters @@ -16,7 +16,7 @@ export function rand(min = 0, max = 1) { * * @param {number} x The number to square * @returns {number} -*/ + */ export function sq(x) { return x * x } @@ -26,7 +26,7 @@ export function sq(x) { * @param {number} x the number to power. * @param {number} [e=2] The number to power by. * @returns {number} -*/ + */ export function exp(x, e = 2) { return x ** e } @@ -35,7 +35,7 @@ export function exp(x, e = 2) { * * @param {number} x The number to root * @returns {number} -*/ + */ export function sqrt(x) { return Math.sqrt(x) } @@ -48,7 +48,7 @@ export function sqrt(x) { * @param {number} b The maximum bound of the interpolation. * @param {number} t A number between 0 and 1 to interpopate by.Any other number greater than 1 or less than 0 will extapolate beyond b or a respectively. * @returns {number} -*/ + */ export function lerp(a, b, t) { return a + t * (b - a) } @@ -59,7 +59,7 @@ export function lerp(a, b, t) { * @param {number} number The number to round. * @param {number} [precision=4] How many decimal places there should be. * @returns {number} -*/ + */ export function round(number, precision = 4) { precision = 10 ** precision return Math.round(number * precision) / precision @@ -72,7 +72,7 @@ export function round(number, precision = 4) { * @param {number} min The minimal bound of the clamped number. * @param {number} max The maximum bound of the clamped number. * @returns {number} -*/ + */ export function clamp(value, min, max) { if (value < min) return min if (value > max) return max @@ -88,7 +88,7 @@ export function clamp(value, min, max) { * @param {number} x2 * @param {number} y2 * @returns {number} -*/ + */ export function map(v, x1, y1, x2, y2) { return x2 + v * (y2 - x2) / (y1 - x1) } @@ -97,7 +97,7 @@ export function map(v, x1, y1, x2, y2) { * @param {number} a * @param {number} b * @returns {number} -*/ + */ export function naturalizePair(a, b) { if (a > b) return (a + b) * (a + b + 1) / 2 + a; @@ -109,7 +109,7 @@ export function naturalizePair(a, b) { * * @param {number} deg number to convert. * @returns {number} -*/ + */ export function degToRad(deg) { return deg * DEG2RAD } @@ -119,13 +119,13 @@ export function degToRad(deg) { * * @param {number} rad number to convert. * @returns {number} -*/ + */ export function radToDeg(rad) { return rad * RAD2DEG } /** * @param {number} x -*/ + */ export function wrapAngle(x) { let a = x while (a > Math.PI * 2) { diff --git a/src/math/vector.js b/src/math/vector.js index 9b257334..fe6e5c79 100644 --- a/src/math/vector.js +++ b/src/math/vector.js @@ -59,7 +59,7 @@ export class Vector2 { distanceTo(v) { obj.x = this.x - v.x obj.y = this.y - v.y - return Math.sqrt( Vector2.prototype.magnitudeSquared.call(obj)) + return Math.sqrt(Vector2.prototype.magnitudeSquared.call(obj)) } /** *Calculates length squared of this vector to another vector @@ -331,7 +331,7 @@ export class Vector2 { return this.multiply(min / length) return this } - + toJson() { return this } @@ -470,15 +470,24 @@ export class Vector2 { static ZERO = Object.freeze(new Vector2()) } -export class Vector extends Vector2{ - constructor(x,y){ - super(x,y) +export class Vector extends Vector2 { + /** + * @param {number} x the x coordinate of the vector + * @param {number} y the y coordinate of the vector + */ + constructor(x, y) { + super(x, y) console.error("The class `Vector` is depreciated since v0.4.13.Use Vector2 instead.") } } -export class Vec2 extends Vector2{ - constructor(x,y){ - super(x,y) + +export class Vec2 extends Vector2 { + /** + * @param {number} x the x coordinate of the vector + * @param {number} y the y coordinate of the vector + */ + constructor(x, y) { + super(x, y) console.error("The class `Vec2` is depreciated since v0.4.13.Use Vector2 instead.") } } \ No newline at end of file diff --git a/src/physics/shapes/triangle.js b/src/physics/shapes/triangle.js index 5aca6cec..f5eceea7 100644 --- a/src/physics/shapes/triangle.js +++ b/src/physics/shapes/triangle.js @@ -15,7 +15,6 @@ export class Triangle extends Shape { * @param {number} angle The angle between the two sides. * @param { Vector2} offset Positional offset from the body center. * @param {number} offsetAngle Angular offset from the body center. - * */ constructor(base, height, angle, offset, offsetAngle) { let l1 = new Vector2().set(1, 0).multiply(base) @@ -27,6 +26,12 @@ export class Triangle extends Shape { l2.sub(center) ], offset, offsetAngle) } + /** + * @param {number} mass + * @param {number} base + * @param {number} height + * @param {number} angle + */ static calcInertia(mass,base,height,angle){ return 0.5 * mass * base * height * (1 - 2/3 * (1 - (Math.cos(2 * angle * 180/Math.PI))/2)) } diff --git a/src/raycaster/raycaster.js b/src/raycaster/raycaster.js index 3e445e11..3794fc13 100644 --- a/src/raycaster/raycaster.js +++ b/src/raycaster/raycaster.js @@ -39,6 +39,9 @@ export class Raycaster extends Component { this._angle = angleSpace this._number = number } + /** + * @inheritdoc + */ init(entity) { this.requires(entity, "transform") this._transform = entity.get("transform") @@ -50,7 +53,7 @@ export class Raycaster extends Component { } } /** - * + * @param {Body[]} bodies */ update(bodies) { this.collisionResults = [] diff --git a/src/raycaster/raycastresult.js b/src/raycaster/raycastresult.js index ceab60c5..15da3350 100644 --- a/src/raycaster/raycastresult.js +++ b/src/raycaster/raycastresult.js @@ -1,13 +1,17 @@ import { Vector2 } from "../math/index.js" -export class RaycastResult{ +export class RaycastResult { + //TODO - Make this property work /** * @type {RayCastModes} */ mode = RayCastModes.NONE + /** + * @type {RayCollisionResult[]} + */ collisions = [] } -export class RayCollisionResult{ +export class RayCollisionResult { /** * @type {Body} */ @@ -16,7 +20,7 @@ export class RayCollisionResult{ * @readonly * @type {RayPoint[]} */ - points = [ ] + points = [] /** * @type {Ray} */ @@ -25,37 +29,36 @@ export class RayCollisionResult{ * @param {Ray} ray * @param {Body} object */ - constructor(ray,object){ + constructor(ray, object) { this.ray = ray this.object = object } } -export class RayPoint{ +export class RayPoint { /** - * @readonly * @type {Vector2} */ point = null /** - * @readonly * @type {number} */ distance = 0 - constructor(point,distance){ + /** + * @param {Vector2} point + * @param {number} distance + */ + constructor(point, distance) { this.point = point this.distance = distance } } /** + * @readonly * @enum {number} - * @property NONE - * @property NEAREST - * @property ANY - * @property FIRST -*/ + */ export const RayCastModes = { - NONE : 0, - NEAREST:1, - FIRST:2, - ANY:3 + NONE: 0, + NEAREST: 1, + FIRST: 2, + ANY: 3 } \ No newline at end of file diff --git a/src/render/sprites/sprite.js b/src/render/sprites/sprite.js index 5c1b60e5..3e16a973 100644 --- a/src/render/sprites/sprite.js +++ b/src/render/sprites/sprite.js @@ -74,6 +74,10 @@ export class Sprite extends Component{ set orientation(x) { this._orientation.copy(x) } + /** + * @param {CanvasRenderingContext2D} ctx + * @param {number} dt + */ render(ctx, dt) { ctx.save() ctx.beginPath() @@ -103,6 +107,10 @@ export class Sprite extends Component{ this._scale = new Vector2(1,1) return this } + /** + * @inheritdoc + * @returns {*} + */ toJson(){ let obj = { pos:this._position.toJson(), @@ -113,11 +121,17 @@ export class Sprite extends Component{ } return obj } + /** + * @inheritdoc + * + * @param {Renderer} renderer + */ fromJson(obj,renderer){ this.geometry?.fromJson(obj.geometry) this.material?.fromJson(obj.material) this.position.fromJson(obj.pos) this._orientation.fromJson(obj.angle) + //Todo - implement this renderer function this.parent = renderer.getById(obj.parent) } } From d02da9e0ae67e628db8ccbbf3f417e54729fed1b Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:27:08 +0300 Subject: [PATCH 31/41] [Utils] Refactored the `mixin()` function #change #fix --- .gitignore | 3 +-- src/utils/common.js | 22 ++++++++-------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index bee8cbcf..8e810f88 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,4 @@ res.json tests *.res.js *.txt -demos -common.js \ No newline at end of file +demos \ No newline at end of file diff --git a/src/utils/common.js b/src/utils/common.js index c623381a..77a462b2 100644 --- a/src/utils/common.js +++ b/src/utils/common.js @@ -109,7 +109,7 @@ export function inheritComponent(component, overrideInit = true, overrideUpdate proto.get = function(n) { return this.entity.getComponent(n); } - proto.requires = function(entity,...names) { + proto.requires = function(entity, ...names) { for (var i = 0; i < names.length; i++) if (!entity.has(names[i])) throws(`The component \`${this.CHOAS_CLASSNAME}\` requires another component \`${names[i]}\` but cannot find it in the Entity with id ${entity.id}`) @@ -140,21 +140,15 @@ export function inheritComponent(component, overrideInit = true, overrideUpdate }) } /** - * Mixes the functions required by an object into another object. + * Todo - Fix this function to add all props if no props param is given + * Mixes the properties and methods required by an object from another object. * - * @param {Object} from the object constructor function to add methods from. - * @param {Object} to the object constructor function to add methods to. + * @param {*} from the object constructor function to add methods from. + * @param {*} to the object constructor function to add methods to. + * @param {string[]} [props] */ -export function mixin(from, to,props = []) { - let proto = from.prototype - let proto2 = to.prototype - console.log(proto2); - Object.assign(proto,from) +export function mixin(from, to, props = []) { for (let name of props) { - //if(!(methodName in proto))continue - //if (methodName in proto2) continue - - proto2[name] = proto[name] + to[name] = from[name] } - //console.log(new to()); } \ No newline at end of file From 7bd9585aff9291873a4fea6571ffe89d31077dcb Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:33:23 +0300 Subject: [PATCH 32/41] [Physics] Formatted code to go well with deepscan #ignore --- src/physics/bodies/body.js | 2 +- src/physics/world/index.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/physics/bodies/body.js b/src/physics/bodies/body.js index 9f1c754e..26b36189 100644 --- a/src/physics/bodies/body.js +++ b/src/physics/bodies/body.js @@ -1,4 +1,4 @@ -import { Vector2, Angle, degToRad, radToDeg } from "../../math/index.js" +import { Vector2, degToRad, radToDeg } from "../../math/index.js" import { Component } from "../../ecs/index.js" import { Utils } from "../../utils/index.js" import { BoundingBox } from "../../math/index.js" diff --git a/src/physics/world/index.js b/src/physics/world/index.js index 05dac3c8..b2d1ad70 100644 --- a/src/physics/world/index.js +++ b/src/physics/world/index.js @@ -10,7 +10,7 @@ import { System } from "../../ecs/index.js" /** * Class responsible for updating bodies,constraints and composites. */ -export class World extends System{ +export class World extends System { /** * Used to check if a manifold is persistent. * @@ -234,8 +234,8 @@ export class World extends System{ let a = this.objects[i] if (a.mass) a.acceleration.add(this.gravitationalAcceleration) - a.velocity.add(a.acceleration.multiply(dt)) - a.acceleration.set(0,0) + a.velocity.add(a.acceleration.multiply(dt)) + a.acceleration.set(0, 0) } } /** From a460a2f872cc5c76644e7714ddcaee1d878dfc8a Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:20:26 +0300 Subject: [PATCH 33/41] [Documentation] Updated Readme #change --- README.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f7d2023f..0006c5a9 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ Import it into your project like this: ```javascript import * as CHAOS from "chaos-studio" ``` -#### OR: +#### OR Get the [umd file](https://github.com/waynemwashuma/chaos-engine/dist/chaos.umd.js) from the dist folder of the [repository](https://github.com/waynemwashuma/chaos-engine), @@ -66,13 +66,23 @@ put it in your root directory and add it to your html page like so: ```html - + Load Example - + ``` This way,the "CHAOS" module name will be available on the window object. +### OR +import the library from unpkg.com like this: + +```html + + + + +``` + ### Creating an example #### Setup game Now we can create a small demo. From 32f89b42d3db25a033c93ac0ea1e3094a84b7c03 Mon Sep 17 00:00:00 2001 From: waynemwashuma <94756970+waynemwashuma@users.noreply.github.com> Date: Sat, 6 Jan 2024 14:52:21 +0300 Subject: [PATCH 34/41] [Math] Imported `TWO_PI` to `Vector2()` #internal #refactor --- src/math/vector.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/math/vector.js b/src/math/vector.js index fe6e5c79..8b00f58d 100644 --- a/src/math/vector.js +++ b/src/math/vector.js @@ -1,8 +1,9 @@ -let obj = { +import { TWO_PI } from "./constants.js"; + +const obj = { x: 0, y: 0 } -let TWO_PI = Math.PI * 2 /** * This is a 2D vector class. * From 5223a10bdfffc25d183a967fa27c00a57966535b Mon Sep 17 00:00:00 2001 From: "94756970+waynemwashuma@users.noreply.github.com" <94756970+waynemwashuma@users.noreply.github.com> Date: Sun, 7 Jan 2024 19:04:24 +0300 Subject: [PATCH 35/41] [Demos] Modified demos #change --- .gitignore | 3 +- demos/animation.js | 79 +++++++++++++++++++++++++++++---------- demos/assets/warrior.png | Bin 46361 -> 31185 bytes demos/index.html | 24 ++++++------ demos/index.js | 42 +++++++++++---------- demos/main.js | 2 +- demos/marterial.js | 11 +++++- demos/raycaster.js | 50 +++++++++++++++---------- 8 files changed, 138 insertions(+), 73 deletions(-) diff --git a/.gitignore b/.gitignore index 8e810f88..37cb8973 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,4 @@ res.json *.mp3 tests *.res.js -*.txt -demos \ No newline at end of file +*.txt \ No newline at end of file diff --git a/demos/animation.js b/demos/animation.js index 87f50b07..f28758b3 100644 --- a/demos/animation.js +++ b/demos/animation.js @@ -6,23 +6,52 @@ import { Tween, createEntity, Vector2Update, - Easing + Easing, + TextMaterial, + BoxGeometry } from "/src/index.js" let path = [ - new Vector2(-25,-25), - new Vector2(-25,25), - new Vector2(25,25), - new Vector2(25,-25) + new Vector2(-25, -25), + new Vector2(-25, 25), + new Vector2(25, 25), + new Vector2(25, -25) ] -let geometry = new BufferGeometry(path) +let geometry = new BoxGeometry(25,25) let material = new BasicMaterial() material.fill = "blue" export function animation(manager) { - let tweener = manager.getSystem("tween") + const renderer = manager.getSystem("renderer") + const tweener = manager.getSystem("tween") + const offset = 100, + stride = 100 - let box = createEntity(200, 100) + const easings = Object.keys(Easing) + for (let i = offset; i < renderer.width - offset; i += stride) { + const easeName = easings[(i - offset) / stride] + const text = createText(i, 100, easeName) + + const entity = createAnimation( + Easing[easeName], + i, + renderer.height/2, + tweener + ) + const bounds = createEntity(i,renderer.height/4 + 100).attach("sprite",new Sprite( + new BoxGeometry(stride, renderer.height / 2), + new BasicMaterial() + )) + manager.add(bounds) + manager.add(text) + manager.add(entity) + + + } +} + +function createAnimation(easing, width, height, tweener, renderer) { + let box = createEntity(width, 100) let tween = new Tween( box.get("transform").position ) @@ -30,25 +59,37 @@ export function animation(manager) { box.get("transform").position ) tween - .from(new Vector2(200, 200)) - .to(new Vector2(200, 1200)) + .from(new Vector2(width, 200)) + .to(new Vector2(width, height)) .duration(4) .onUpdate(Vector2Update) - .easing(Easing.linear).play() - + .easing(easing).play() + tween2 - .from(new Vector2(200, 1200)) - .to(new Vector2(200, 200)) + .from(new Vector2(width, height)) + .to(new Vector2(width, 200)) .duration(4) .onUpdate(Vector2Update) - .easing(Easing.linear) + .easing(easing) tween.chain(tween2) tween2.chain(tween) + box.attach("sprite", new Sprite( - geometry, material - )) - manager.add(box) + geometry, material + )) + tweener.add(tween2) tweener.add(tween) - console.log(tweener); + return box +} + +function createText(x, y, text) { + const entity = createEntity(x, y) + const material = new TextMaterial(text) + entity.attach("sprite", new Sprite( + geometry, + material + )) + material.center = true + return entity } \ No newline at end of file diff --git a/demos/assets/warrior.png b/demos/assets/warrior.png index 99af22b8aeeddd3d89bd82b69c36ffc8e013d4e0..bce3a46985efa89d6f4d02a880c3bc3a8da44a4a 100644 GIT binary patch literal 31185 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 literal 46361 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 Uk|h@x0)JGmXefWUY~=mF0P^5F*Z=?k diff --git a/demos/index.html b/demos/index.html index d8ae959c..a217e263 100644 --- a/demos/index.html +++ b/demos/index.html @@ -2,6 +2,11 @@ + + + + + ES8 Project + - - - - - ES8 Project - +
@@ -36,11 +37,12 @@
- +
- +
+ \ No newline at end of file diff --git a/demos/index.js b/demos/index.js index bdf9c4a6..49a35d22 100644 --- a/demos/index.js +++ b/demos/index.js @@ -30,9 +30,10 @@ import { TweenManager, fpsDebugger, bodyDebugger, - Entity, + raycastDebugger, Intergrator, - IndexedList + IndexedList, + RaycastManager, } from "/src/index.js" function createBoundingBox(x, y, w, h, t = 20) { @@ -70,41 +71,44 @@ function createBoundingBox(x, y, w, h, t = 20) { } return [l1, l2, l3, l4] } -function createCanvasBounds(manager) { - let renderer = manager.getSystem("renderer") - let walls = createBoundingBox(30, 30, renderer.width - 60, renderer.height - 80, 1000) - walls.forEach(w => { - let bound = createEntity(w.pos.x, w.pos.y) - let body = new Box(w.w, w.h) - bound.attach("body", body) - .attach("sprite", new BodySprite()) - body.type = Body.STATIC - manager.add(bound) - }) - } + +function createCanvasBounds(manager) { + let renderer = manager.getSystem("renderer") + let walls = createBoundingBox(30, 30, renderer.width - 60, renderer.height - 80, 1000) + walls.forEach(w => { + let bound = createEntity(w.pos.x, w.pos.y) + let body = new Box(w.w, w.h) + bound.attach("body", body) + .attach("sprite", new BodySprite()) + body.type = Body.STATIC + manager.add(bound) + }) +} export const demos = { manager: new Manager(), renderer: new Renderer2D(), world: new World(), - tweenManager:new TweenManager(), + tweenManager: new TweenManager(), examples: new IndexedList, init: function(selector) { this.manager.registerSystem("agent", new AgentManager()) this.manager.registerSystem("renderer", this.renderer) this.manager.registerSystem("world", this.world) this.manager.registerSystem("tween", this.tweenManager) - this.manager.registerSystem("movable",new Intergrator()) + this.manager.registerSystem("movable", new Intergrator()) + this.manager.registerSystem("raycaster", new RaycastManager()) let renderer = this.renderer renderer.bindTo(selector) renderer.setViewport(innerWidth, innerHeight * 0.5) window.onresize = () => { renderer.setViewport(innerWidth, innerHeight) } - window.onorientationchange = ()=>{ - renderer.setViewport(innerWidth,innerHeight) + window.onorientationchange = () => { + renderer.setViewport(innerWidth, innerHeight) } fpsDebugger(this.manager) bodyDebugger(this.manager) + raycastDebugger(this.manager) }, setup: function(name) { this.manager.clear() @@ -115,7 +119,7 @@ export const demos = { this.setup(n) }, register(n, f) { - this.examples.set(n,f) + this.examples.set(n, f) } } //Physics diff --git a/demos/main.js b/demos/main.js index 88358899..1d31228a 100644 --- a/demos/main.js +++ b/demos/main.js @@ -3,7 +3,7 @@ import { demos } from "./index.js" demos.init("#can") -demos.setup("raycaster") +demos.setup("box") let optionTab = document.querySelector("#options-checkbox") let demoOption = document.querySelector("#demos") diff --git a/demos/marterial.js b/demos/marterial.js index 58ee9a48..70410b8e 100644 --- a/demos/marterial.js +++ b/demos/marterial.js @@ -40,11 +40,20 @@ export function materials(manager) { let material3 = new SpriteMaterial(img) let sprite3 = createsprite(290, 60, geometry, material3) + material3.width = 150 + material3.height = 100 manager.add(sprite3) img2.onload = () => { - material3.setup(6, 16) + material3.setup(7, 11) material3.frameRate = 1 / 10 + material3.setAction(1) + } + let r = 0 + setInterval(() => { + material3.setAction(r) + r += r < 9?1:-9 + },10000) } function createsprite(x, y, geometry, material) { diff --git a/demos/raycaster.js b/demos/raycaster.js index 1ff55ccc..93a9fa03 100644 --- a/demos/raycaster.js +++ b/demos/raycaster.js @@ -2,32 +2,42 @@ import { createEntity, Body, Box, - BodySprite, - RaycastManager, + Ball, + Trigon, + rand, Raycaster } from "/src/index.js" export function raycaster(manager) { let world = manager.getSystem("world") let renderer = manager.getSystem("renderer") - for (let x = 150; x < renderer.width - 100; x+= 80) { - for (var y = 100; y < renderer.height - 100; y += 80) { - const box = createBox(x, y) - manager.add(box) - } + for (let x = 150; x < renderer.width - 100; x += 80) { + for (var y = 100; y < renderer.height - 100; y += 80) { + const box = createBox(x, y) + manager.add(box) } - - manager.registerSystem("raycaster",new RaycastManager()) - let raycaster = createEntity(60,renderer.height/2,0) - .attach("raycaster",new Raycaster(1)) - world.gravity = 0 - manager.add(raycaster) } - function createBox(x, y) { - let box = createEntity(x, y) - let body = new Box(50, 50) + + let raycaster = createEntity(renderer.width/2 + 50, renderer.height / 2, -60) + .attach("raycaster", new Raycaster(10,Math.PI/20)) + world.gravity = 0 + manager.add(raycaster) - body.type = Body.STATIC - box.attach("body", body) - return box - } \ No newline at end of file + setInterval(() => { + raycaster.get("transform").orientation.value += 0.001 + }) +} + +function createBox(x, y) { + let box = createEntity(x, y), + body, probs = rand() + if (probs <= 0.33) + body = new Ball(20) + else if (probs > 0.33 && probs <= 0.67) + body = new Box(50, 50) + else + body = new Trigon(50, 50, Math.PI / 3) + body.type = Body.STATIC + box.attach("body", body) + return box +} \ No newline at end of file From efa0de3d10b4eb043d4be1d76ed04a5289e8010f Mon Sep 17 00:00:00 2001 From: waynemwashuma <94756970+waynemwashuma@users.noreply.github.com> Date: Sun, 7 Jan 2024 19:58:05 +0300 Subject: [PATCH 36/41] [scripts] Modified the changelog generator #ignore --- scripts/git/index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/git/index.js b/scripts/git/index.js index 85631dbf..4c868ecc 100644 --- a/scripts/git/index.js +++ b/scripts/git/index.js @@ -106,7 +106,7 @@ function parseMessage(raw) { element.includes('Author') || element.includes("Merge") )continue - message = message.concat(element).replace('\n', '') + message = message.concat(element.trim()).replace('\n', ' ') } return message } @@ -151,7 +151,9 @@ function getchangelog(log) { const scope = commit.message.scope const tags = commit.message.tags if ( - scope == 'documentation' || + scope === '' || + scope === 'documentation' || + scope === 'demos' || tags.includes("#ignore") || tags.includes("#internal") || tags.includes("#refactor") From 53b50616720b31e918496cfbd98036c5aa757163 Mon Sep 17 00:00:00 2001 From: waynemwashuma <94756970+waynemwashuma@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:37:27 +0300 Subject: [PATCH 37/41] [scripts] Fixed typedef script #fix #internal --- scripts/typedef.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/typedef.js b/scripts/typedef.js index 60d1e086..0eaedea8 100644 --- a/scripts/typedef.js +++ b/scripts/typedef.js @@ -1,8 +1,8 @@ import * as fs from "fs"; import * as path from "path"; -let inputDir1 = path.resolve(process.cwd(),"../src","typedef") -let inputDir2 = path.resolve(process.cwd(),"../dist") +let inputDir1 = path.resolve(process.cwd(),"src","typedef") +let inputDir2 = path.resolve(process.cwd(),"dist") let files = fs.readdirSync(inputDir1) let outputfiles = fs.readdirSync(inputDir2) From f34e09998c0862b5d5085a8e5010e8ece75420f3 Mon Sep 17 00:00:00 2001 From: waynemwashuma <94756970+waynemwashuma@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:53:04 +0300 Subject: [PATCH 38/41] [build] 0.7.0 --- dist/chaos.module.d.ts | 377 +- dist/chaos.module.js | 1867 +- dist/chaos.umd.js | 1885 +- doc-template/{publish.js => publish.cjs} | 0 docs/AABBBroadphase.html | 4 +- docs/AI_agent.js.html | 4 +- docs/AI_behaviourManager.js.html | 4 +- docs/AI_behaviours_arrive.js.html | 4 +- docs/AI_behaviours_behaviour.js.html | 4 +- docs/AI_behaviours_evade.js.html | 4 +- docs/AI_behaviours_flocking.js.html | 4 +- docs/AI_behaviours_path.js.html | 4 +- docs/AI_behaviours_pursuit.js.html | 4 +- docs/AI_behaviours_seek.js.html | 4 +- docs/AI_behaviours_wandering.js.html | 4 +- docs/AI_manager.js.html | 4 +- docs/AI_paths_path.js.html | 15 +- docs/Agent.html | 4 +- docs/AgentManager.html | 4 +- docs/AgentSprite.html | 258 +- docs/Angle.html | 4 +- docs/ArriveBehaviour.html | 4 +- docs/AudioHandler.html | 6 +- docs/Ball.html | 302 +- docs/BasicMaterial.html | 4 +- docs/Behaviour.html | 4 +- docs/BehaviourManager.html | 4 +- docs/Body.html | 292 +- docs/BodySprite.html | 260 +- docs/Bound.html | 4 +- docs/BoundingBox.html | 24 +- docs/BoundingCircle.html | 16 +- docs/Box.html | 302 +- docs/Broadphase.html | 4 +- docs/BufferGeometry_BufferGeometry.html | 4 +- docs/CamController_CamController.html | 6 +- docs/Circle.html | 4 +- docs/CircleGeometry_CircleGeometry.html | 4 +- docs/Clock.html | 4 +- docs/Color.html | 1797 ++ docs/Component.html | 516 +- docs/Composite.html | 4 +- docs/Constraint.html | 426 +- docs/DOMEventHandler.html | 4 +- docs/DistanceConstraint.html | 4 +- docs/Entity.html | 280 +- docs/EulerSolver.html | 106 +- docs/EvadeBehaviour.html | 4 +- docs/EventDispatcher.html | 6 +- docs/Flock.html | 4 +- docs/Geometry_Geometry.html | 4 +- docs/GridBroadphase.html | 4 +- docs/Group.html | 258 +- docs/IndexedList.html | 793 + docs/Input.html | 4 +- docs/Keyboard.html | 4 +- docs/Line_Line.html | 10 +- docs/Loader_Loader.html | 212 + docs/Manager.html | 32 +- docs/Material.html | 4 +- docs/Matrix2.html | 4 +- docs/Mouse.html | 4 +- docs/Movable.html | 164 +- docs/NaiveBroadphase.html | 4 +- docs/Node.html | 4 +- docs/Particle.html | 4 +- docs/ParticleSystemSprite.html | 260 +- docs/PathFollowing.html | 4 +- docs/Pool.html | 52 +- docs/Pursuit.html | 4 +- docs/QuadTreeBroadphase.html | 14 +- ...RayCollisionResult_RayCollisionResult.html | 235 + docs/RayPoint_RayPoint.html | 235 + docs/Ray_Ray.html | 235 + docs/Rectangle_Rectangle.html | 4 +- docs/Renderer.html | 42 +- docs/Renderer2D.html | 38 +- docs/RungeKuttaSolver.html | 4 +- docs/SATNarrowPhase.html | 6 +- docs/SeekBehaviour.html | 4 +- docs/Sfx.html | 34 +- docs/Shape.html | 4 +- docs/Signal.html | 664 + docs/SpringConstraint.html | 4 +- docs/Sprite.html | 410 +- docs/SpriteMaterial.html | 22 +- docs/StaticImageMaterial.html | 4 +- docs/System.html | 195 +- docs/TextMaterial.html | 704 + docs/Touch.html | 4 +- docs/Transform.html | 4 +- docs/Triangle.html | 206 +- docs/Trigon_Trigon.html | 4 +- docs/Tween.html | 976 +- docs/Vec2_Vec2.html | 235 + docs/Vector2.html | 86 +- docs/VectorPool.html | 4 +- docs/Vector_Vector.html | 235 + docs/VerletSolver.html | 4 +- docs/WanderBehaviour.html | 4 +- docs/WebGLRenderer.html | 40 +- docs/WebGPURenderer.html | 40 +- docs/World.html | 44 +- docs/animations_tween_tween.js.html | 272 + docs/animations_tween_tweenManager.js.html | 72 + docs/audio_audio.js.html | 9 +- docs/audio_manager.js.html | 4 +- docs/boilerplate_createEntity.js.html | 4 +- docs/boilerplate_createManager.js.html | 4 +- docs/dataStructures_indexedList.js.html | 98 + docs/dataStructures_pools_VectorPool.js.html | 4 +- docs/dataStructures_pools_objectPool.js.html | 16 +- docs/debuggers_bodydebugger.js.html | 4 +- docs/debuggers_fpsdebugger.js.html | 78 + docs/debuggers_raycastDebugger.js.html | 101 + docs/device_index.js.html | 4 +- docs/ecs_component.js.html | 35 +- docs/ecs_entity.js.html | 17 +- docs/ecs_manager.js.html | 5 +- docs/ecs_system.js.html | 56 +- docs/events_DOMEventHandler.js.html | 4 +- docs/events_eventDispatcher.js.html | 15 +- docs/events_eventHandlers.js.html | 4 +- docs/events_events.js.html | 4 +- docs/events_signals.js.html | 110 + docs/global.html | 19662 +++++++++------- docs/index.html | 17 +- docs/inputs_input.js.html | 4 +- docs/inputs_keyboard.js.html | 4 +- docs/inputs_mouse.js.html | 4 +- docs/inputs_touch.js.html | 4 +- docs/intergrator_boundsComponent.js.html | 6 +- docs/intergrator_intergrator.js.html | 25 +- docs/intergrator_movableComponent.js.html | 12 +- docs/intergrator_transformComponent.js.html | 4 +- docs/loader_index.js.html | 205 + docs/math_AABB_boundingBox.js.html | 225 + docs/math_AABB_boundingSphere.js.html | 136 + docs/math_AABB_overlap.js.html | 92 + docs/math_angle.js.html | 6 +- docs/math_color.js.html | 185 + docs/math_interpolation.js.html | 355 + docs/math_math.js.html | 77 +- docs/math_matrix.js.html | 4 +- docs/math_vector.js.html | 34 +- docs/module-Cookie.html | 4 +- docs/module-Session.html | 4 +- docs/module-utils_index.html | 4 +- docs/physics_SAT_index.js.html | 4 +- docs/physics_bodies_ball.js.html | 4 +- docs/physics_bodies_body.js.html | 41 +- docs/physics_bodies_box.js.html | 4 +- docs/physics_bodies_composite.js.html | 4 +- docs/physics_bodies_trigon.js.html | 4 +- docs/physics_broadphases_AABBTree.js.html | 6 +- docs/physics_broadphases_Naive.js.html | 4 +- docs/physics_broadphases_Quadtree.js.html | 18 +- docs/physics_broadphases_SpartialHash.js.html | 4 +- docs/physics_broadphases_broadphase.js.html | 4 +- docs/physics_constraints_constraint.js.html | 32 +- ...ics_constraints_distanceConstraint.js.html | 4 +- ...ysics_constraints_springConstraint.js.html | 4 +- docs/physics_integrators_euler.js.html | 4 +- docs/physics_integrators_rungeKutter.js.html | 4 +- docs/physics_integrators_verlet.js.html | 4 +- docs/physics_narrowphase_Narrowphase.js.html | 60 + ...physics_narrowphase_SATNarrowphase.js.html | 4 +- docs/physics_settings.js.html | 4 +- docs/physics_shapes_circle.js.html | 4 +- docs/physics_shapes_geometry.js.html | 8 +- docs/physics_shapes_line.js.html | 6 +- docs/physics_shapes_rectangle.js.html | 4 +- docs/physics_shapes_shape.js.html | 4 +- docs/physics_shapes_triangle.js.html | 11 +- docs/physics_solvers_contactSolver.js.html | 4 +- docs/physics_solvers_frictionSolver.js.html | 4 +- docs/physics_solvers_impulseSolver.js.html | 4 +- .../physics_solvers_penetrationSolver.js.html | 4 +- docs/physics_world_index.js.html | 11 +- docs/raycaster_manager.js.html | 80 + docs/raycaster_ray.js.html | 116 + docs/raycaster_raycaster.js.html | 196 +- docs/raycaster_raycastresult.js.html | 70 +- docs/render_camController.js.html | 25 +- docs/render_camera.js.html | 4 +- docs/render_geometry_circlegeometry.js.html | 4 +- docs/render_geometry_geometry.js.html | 7 +- docs/render_material_BasicMaterial.js.html | 4 +- docs/render_material_SpriteMaterial.js.html | 47 +- ...ender_material_StaticImageMaterial.js.html | 4 +- docs/render_material_material.js.html | 4 +- docs/render_material_textMaterial.js.html | 98 + docs/render_renderers_canvas.js.html | 4 +- docs/render_renderers_renderer.js.html | 10 +- docs/render_renderers_webgpurenderer.js.html | 4 +- docs/render_renderers_weglrenderer.js.html | 4 +- docs/render_sprites_AgentSprite.js.html | 4 +- docs/render_sprites_bodysprite.js.html | 13 +- docs/render_sprites_group.js.html | 4 +- docs/render_sprites_particleSystem.js.html | 4 +- docs/render_sprites_sprite.js.html | 22 +- docs/render_utils_canvasfunc.js.html | 10 +- docs/storage_cookie.js.html | 4 +- docs/storage_localStorage.js.html | 4 +- docs/storage_sessionStorage.js.html | 4 +- docs/typedef_EasingFunc.js.html | 52 + docs/typedef_bounds.js.html | 4 +- docs/typedef_manifold.js.html | 6 +- docs/typedef_vectorlike.js.html | 4 +- docs/utils_clock.js.html | 4 +- docs/utils_common.js.html | 26 +- docs/utils_error.js.html | 4 +- docs/utils_index.js.html | 4 +- 213 files changed, 27310 insertions(+), 11252 deletions(-) rename doc-template/{publish.js => publish.cjs} (100%) create mode 100644 docs/Color.html create mode 100644 docs/IndexedList.html create mode 100644 docs/Loader_Loader.html create mode 100644 docs/RayCollisionResult_RayCollisionResult.html create mode 100644 docs/RayPoint_RayPoint.html create mode 100644 docs/Ray_Ray.html create mode 100644 docs/Signal.html create mode 100644 docs/TextMaterial.html create mode 100644 docs/Vec2_Vec2.html create mode 100644 docs/Vector_Vector.html create mode 100644 docs/animations_tween_tween.js.html create mode 100644 docs/animations_tween_tweenManager.js.html create mode 100644 docs/dataStructures_indexedList.js.html create mode 100644 docs/debuggers_fpsdebugger.js.html create mode 100644 docs/debuggers_raycastDebugger.js.html create mode 100644 docs/events_signals.js.html create mode 100644 docs/loader_index.js.html create mode 100644 docs/math_AABB_boundingBox.js.html create mode 100644 docs/math_AABB_boundingSphere.js.html create mode 100644 docs/math_AABB_overlap.js.html create mode 100644 docs/math_color.js.html create mode 100644 docs/math_interpolation.js.html create mode 100644 docs/physics_narrowphase_Narrowphase.js.html create mode 100644 docs/raycaster_manager.js.html create mode 100644 docs/raycaster_ray.js.html create mode 100644 docs/render_material_textMaterial.js.html create mode 100644 docs/typedef_EasingFunc.js.html diff --git a/dist/chaos.module.d.ts b/dist/chaos.module.d.ts index adb1dde3..85d19819 100644 --- a/dist/chaos.module.d.ts +++ b/dist/chaos.module.d.ts @@ -1,14 +1,18 @@ -export type TweenUpdate = (lerpFunc: Function, to: T, from: T, t: number, into: T) => void; +export type EventHandlerFunc = (data: any) => void; +export type signalListener = (value: Signal) => void; +export type TweenUpdate = (lerpFunc: LerpFunc, to: T, from: T, t: number, into: T) => void; +export type LerpFunc = (p0: number, p1: number, t: number) => number; export type Traverser = (node: Node) => boolean; export type Bounds = { max: Vector_like; min: Vector_like; }; +export type EasingFunc = (t: number) => number; export type CollisionPair = { a: Body; b: Body; }; -export type Manifold = { +export type transform = { bodyA: Body; bodyB: Body; contactData: ContactManifold; @@ -57,8 +61,6 @@ export class Agent extends Component { } export class AgentManager extends System { objects: Agent[]; - init(manager: Manager): void; - update(dt: number): void; } export class AgentSprite extends Sprite { constructor(); @@ -92,7 +94,7 @@ export class Angle { type: string | number; }; } -export function AngleUpdate(lerpFunc: any, to: any, from: any, t: any, into: any): void; +export function AngleUpdate(lerpFunc: LerpFunc, to: T, from: T, t: number, into: T): void; export class ArriveBehaviour extends Behaviour { constructor(target: Vector2); radius: number; @@ -203,6 +205,7 @@ export class Body extends Component { getAnchor(index: number): Vector2; getLocalAnchor(index: number, target?: Vector2): Vector2; applyForce(force: Vector2, arm?: Vector2): void; + applyImpulse(impulse: Vector2, arm?: Vector2): void; init(entity?: Entity, composited?: boolean): void; update(): void; toJson(): { @@ -234,6 +237,7 @@ export class Body extends Component { group: number; }; }; + addShape(shape: Shape): void; fromJson(obj: any): void; } export class BodySprite extends Sprite { @@ -242,8 +246,7 @@ export class BodySprite extends Sprite { drawVelocity: boolean; drawBounds: boolean; drawPosition: boolean; - render(ctx: CanvasRenderingContext2D, dt: number): void; - _drawCenter(body: any, ctx: any): void; + private _drawCenter; private _drawVelocity; private _drawBound; private _drawShapes; @@ -305,19 +308,22 @@ export class BoundingCircle { export class Box extends Body { constructor(w: number, h: number); } +export class BoxGeometry extends BufferGeometry { + constructor(width: any, height: any); +} export class BufferGeometry { constructor(vertices: Vector2[]); readonly vertices: Vector2[]; drawable: Path2D | WebGLVertexArrayObject; init(ctx: CanvasRenderingContext2D): void; - updateVertices(data: any): void; + updateVertices(data: Vector2[]): void; } export class CamController { constructor(camera: Camera); - readonly offset: Vector2; + offset: Vector2; transform: Transform; - targetPosition: any; - targetOrientation: Angle; + targetPosition: Vector2 | null; + targetOrientation: Angle | null; follow(position: Vector2, orientation?: Angle): void; followEntity(entity: Entity): void; setOffset(x: number, y: number): void; @@ -358,19 +364,35 @@ export class Clock { dt: number; update(accumulate: number): number; } -export function ColorUpdate(lerpFunc: any, to: any, from: any, t: any, into: any): void; +export class Color { + constructor(r?: number, g?: number, b?: number, alpha?: number); + set(r: number, g: number, b: number, alpha?: number): Color; + r: any; + g: any; + b: any; + a: any; + clone(): Color; + copy(color: Color | string): Color; + add(color: Color): Color; + darken(scale: number): Color; + lerp(color: Color, alpha: number): Color; + lighten(scale: number): Color; + random(min?: number, max?: number): Color; + toArray(array: any, offset?: number): any; +} +export function ColorUpdate(lerpFunc: LerpFunc, to: T, from: T, t: number, into: T): void; export class Component { - static fromJson(): void; - static toJson(): void; static implement(component: any): void; destroy(): void; get CHOAS_CLASSNAME(): string; get CHAOS_OBJ_TYPE(): string; init(entity: Entity): void; update(dt: number): void; - get(entity: any, n: string): any; - requires(entity: any, ...names: string[]): void; - query(entity: any, bound: CircleBounding | BoxBounding, target?: Entity): any; + get(entity: Entity, n: string): any; + requires(entity: Entity, ...names: string[]): void; + query(entity: Entity, bound: CircleBounding | BoxBounding, target?: Entity[]): Entity[]; + fromJson(obj: any, system: T): void; + toJson(): any; } export class Composite extends Component { entity: Entity | null; @@ -400,10 +422,10 @@ export class Composite extends Component { } export class Constraint { constructor(body1: Body, body2: Body, localA: Vector2, localB: Vector2); + localA: Vector2; + localB: Vector2; body1: Body; body2: Body; - localA: any; - localB: any; stiffness: number; dampening: number; get physicsType(): number; @@ -429,6 +451,7 @@ export namespace Cookies { export { _delete as delete }; export function clear(): void; } +export const DEG2RAD: number; export namespace DEVICE { let audio: boolean; let canvas: boolean; @@ -448,37 +471,37 @@ export class DistanceConstraint extends Constraint { maxDistance: number; } export namespace Easing { - function linear(x: any): any; - function quadraticIn(x: any): number; - function quadraticOut(x: any): number; - function quadraticInOut(x: any): number; - function cubicIn(x: any): number; - function cubicOut(x: any): number; - function cubicInOut(x: any): number; - function quarticIn(x: any): number; - function quarticOut(x: any): number; - function quarticInOut(x: any): number; - function quinticIn(x: any): number; - function quinticOut(x: any): number; - function quinticInOut(x: any): number; - function sinusoidalIn(x: any): number; - function sinusoidalOut(x: any): number; - function sinusoidalInOut(x: any): number; - function exponentialIn(x: any): number; - function exponentialOut(x: any): number; - function exponentialInOut(x: any): number; - function circularIn(x: any): number; - function circularOut(x: any): number; - function circularInOut(x: any): number; - function elasticIn(x: any): number; - function elasticOut(x: any): number; - function elasticInOut(x: any): number; - function backIn(x: any): number; - function backOut(x: any): number; - function backInOut(x: any): number; - function bounceIn(x: any): number; - function bounceOut(x: any): number; - function bounceInOut(x: any): number; + let linear: EasingFunc; + let quadraticIn: EasingFunc; + let quadraticOut: EasingFunc; + let quadraticInOut: EasingFunc; + let cubicIn: EasingFunc; + let cubicOut: EasingFunc; + let cubicInOut: EasingFunc; + let quarticIn: EasingFunc; + let quarticOut: EasingFunc; + let quarticInOut: EasingFunc; + let quinticIn: EasingFunc; + let quinticOut: EasingFunc; + let quinticInOut: EasingFunc; + let sinusoidalIn: EasingFunc; + let sinusoidalOut: EasingFunc; + let sinusoidalInOut: EasingFunc; + let exponentialIn: EasingFunc; + let exponentialOut: EasingFunc; + let exponentialInOut: EasingFunc; + let circularIn: EasingFunc; + let circularOut: EasingFunc; + let circularInOut: EasingFunc; + let elasticIn: EasingFunc; + let elasticOut: EasingFunc; + let elasticInOut: EasingFunc; + let backIn: EasingFunc; + let backOut: EasingFunc; + let backInOut: EasingFunc; + let bounceIn: EasingFunc; + let bounceOut: EasingFunc; + let bounceInOut: EasingFunc; } export class Entity { static Default(x: number, y: number, a: number): Entity; @@ -488,7 +511,7 @@ export class Entity { private _global; active: boolean; get CHAOS_OBJ_TYPE(): string; - get CHAOS_CLASSNAME(): any; + get CHAOS_CLASSNAME(): string; destroy(): void; removeSelf(): void; reset(): void; @@ -508,8 +531,8 @@ export class Entity { query(bound: Bounds, target?: Entity[]): Entity[]; fromJSON(obj: {}, compList: Map): this; toJson(): { - deg: number; - type: string; + comps: {}; + tags: any[]; }; } declare var error$1: Readonly<{ @@ -523,7 +546,7 @@ declare var error$1: Readonly<{ deprecate: typeof deprecate; }>; export class EulerSolver { - static solve(transform: any, movable: any, dt: number): void; + static solve(transform: Transform, movable: Movable, dt: number): void; } export class EvadeBehaviour extends Behaviour { constructor(pursuer: Vector2); @@ -534,7 +557,7 @@ export class EventDispatcher { private handlers; trigger(n: string, data: any): void; init(): void; - add(name: string, handler: Function): void; + add(name: string, handler: EventHandlerFunc): void; } export type Events = string; export namespace Events { @@ -561,7 +584,7 @@ export class Geometry { get CHAOS_OBJ_TYPE(): string; getNormals(rad: number, target: Vector2[]): Vector2[]; private calcFaceNormals; - transform(vertices: Vector2[], pos: Vector2, rad: any, n: number): void; + transform(vertices: Vector2[], pos: Vector2, rad: number, n: number): void; toJson(): { vertices: any[]; }; @@ -570,19 +593,18 @@ export class Geometry { export class Group extends Sprite { constructor(sprites?: Sprite[]); private _children; - get CHOAS_CLASSNAME(): string; - get CHAOS_OBJ_TYPE(): string; add(sprite: Sprite | Group): void; remove(sprite: Sprite | Group, recursive?: boolean, index?: number): boolean; - render(ctx: CanvasRenderingContext2D, dt: number): void; } -export class IndexedList { - _keys: any; - _list: any[]; - get(name: any): any; - push(name: any, value: any): void; - remove(name: any): void; - values(): any[]; +export const HALF_PI: number; +export class IndexedList { + private _keys; + private _list; + get(name: string): T; + set(name: string, value: T): void; + remove(name: string): void; + keys(): string[]; + values(): T[]; } export class Input { constructor(eventHandler: DOMEventHandler); @@ -596,15 +618,15 @@ export class Input { export class Intergrator extends System { active: boolean; solver: typeof EulerSolver.solve; - objects: any[]; + objects: Movable; init(manager: any): void; update(dt: any): void; } export namespace Interpolation { - function Linear(p0: any, p1: any, t: any): any; + function Linear(p0: number, p1: number, t: number): number; function Bernstein(n: any, i: any): any; function Factorial(n: any): number; - function CatmullRom(p0: any, p1: any, p2: any, p3: any, t: any): any; + function CatmullRom(p0: number, p1: number, p2: number, p3: number, t: number): number; } export class Keyboard { constructor(eh: DOMEventHandler); @@ -617,28 +639,31 @@ export class Keyboard { private _onUp; } export class Line extends Shape { - constructor(length: number, offset: Vector2, offsetAngle: any); + constructor(length: number, offset: Vector2, offsetAngle: number); length: number; } +export class LineGeometry extends BufferGeometry { + constructor(length: any); +} export class Loader { - constructor(manager: any); - _toload: any[]; + constructor(manager: Manager); + private _toload; imgs: {}; sfx: {}; json: {}; - _progressBytes: number; - _totalBytes: number; + private _progressBytes; + private _totalBytes; _filesErr: number; - _filesLoaded: number; - _totalFileNo: number; + private _filesLoaded; + private _totalFileNo; onfinish: any; _handlers: { onload: (xhr: any, e: any) => void; onheadload: (e: any) => void; onerror: (e: any) => void; }; - _getName(url: any): any; - _getType(url: any): "audio" | "image" | "json"; + private _getName; + private _getType; loadAll(files?: {}): void; } export class Manager { @@ -729,7 +754,7 @@ export class Mouse { } declare class Movable$1 extends Component { constructor(x: number, y: number, a: number); - transform: any; + transform: Transform; velocity: Vector2$1; rotation: Angle; acceleration: Vector2$1; @@ -750,14 +775,15 @@ export class NaiveBroadphase extends Broadphase { private bodies; } export class NarrowPhase { - records: any; - getCollisionPairs(contactList: any, clmds: any): void; + records: Map; + getCollisionPairs(contactList: CollisionPair[], clmds: Manifold[]): Manifold[]; } export namespace Overlaps { function AABBColliding(a: BoundingBox, b: BoundingBox): boolean; function boundSpheresColliding(a: BoundingCircle, b: BoundingCircle): boolean; function AABBvsSphere(a: BoundingBox, b: BoundingCircle): boolean; } +export const PI: number; export class Particle { constructor(pos: Vector2, radius: number, lifespan?: number); readonly position: Vector2; @@ -785,7 +811,6 @@ export class ParticleSystemSprite extends Sprite { protected create(): Particle; init(entity: Entity): void; protected behavior(p: Particle, dt: number): void; - render(ctx: CanvasRenderingContext2D, dt: number): void; } export class Path { private _points; @@ -800,11 +825,11 @@ export class Path { loop: boolean; add(point: Vector2): this; clear(): this; - advance(): boolean; + private advance; update(lerpdist?: number): Vector2$1; - current(): any[]; - point(): Vector2$1; - get path(): any[]; + current(): Vector2[]; + point(): Vector2; + get path(): Vector2[]; draw(ctx: CanvasRenderingContext2D): void; } export class PathFollowing extends Behaviour { @@ -834,24 +859,26 @@ export class QuadTreeBroadphase extends Broadphase { _root: Node; maxDepth: number; bounds: Bounds; - _insert(client: any): void; - _remove(client: any): boolean; + private _insert; + private _remove; remove(obj: Body): boolean; - traverse(func: Function): any[]; + traverse(func: Traverser): any[]; draw(ctx: CanvasRenderingContext2D): void; - recalculateBounds(bounds: any): void; + recalculateBounds(bounds: Bounds): void; } +export const RAD2DEG: number; export class Ray { - constructor(origin?: Vector2$1, direction?: Vector2$1); + constructor(origin?: Vector2, direction?: Vector2); maxLength: number; - _origin: Vector2$1; - _direction: Vector2$1; - set direction(arg: Vector2$1); - get direction(): Vector2$1; - set origin(arg: Vector2$1); - get origin(): Vector2$1; - setOrigin(x: any, y: any): void; - setDirection(x: any, y: any): void; + private _origin; + private _direction; + set direction(arg: Vector2); + get direction(): Vector2; + set origin(arg: Vector2); + get origin(): Vector2; + setOrigin(x: number, y: number): void; + setDirection(x: number, y: number): void; + lookAt(x: number, y: number): void; } export type RayCastModes = number; export namespace RayCastModes { @@ -861,33 +888,38 @@ export namespace RayCastModes { let ANY: number; } export class RayCollisionResult { + constructor(ray: Ray, object: Body); + object: Body; + readonly points: RayPoint[]; + ray: Ray; +} +export class RayPoint { + constructor(point: Vector2, distance: number); + point: Vector2; distance: number; - object: any; - points: any[]; - ray: any; } export class RaycastManager extends System { - objects: any[]; - bodies: any; - init(manager: any): void; + private objects; + private bodies; + update(dt: any): void; } export class RaycastResult { - ray: any; - mode: number; - collisions: any[]; + mode: RayCastModes; + collisions: RayCollisionResult[]; } export class Raycaster extends Component { constructor(number?: number, angleSpace?: number); - rays: any[]; - initialDir: any[]; - _number: number; - _angle: number; - _transform: any; - _lastangle: number; + rays: Ray[]; + collisionResults: Ray[]; + private _number; + private _angle; + private _transform; + private _lastangle; + mode: number; init(entity: any): void; - update(bodies: any): void; - draw(ctx: CanvasRenderingContext2D): void; - add(): void; + update(bodies: Body[]): void; + private testCircle; + private testVertices; } export class Rectangle extends Shape { static calcInertia(mass: number, width: number, height: number): number; @@ -895,7 +927,7 @@ export class Rectangle extends Shape { height: number; width: number; } -export class Renderer { +export class Renderer extends System { constructor(canvas: HTMLCanvasElement, context: CanvasRenderingContext2D | WebGLRenderingContext | WebGL2RenderingContext); _rafID: number; private _accumulator; @@ -908,9 +940,7 @@ export class Renderer { ctx: CanvasRenderingContext2D | WebGLRenderingContext | WebGL2RenderingContext; camera: Camera; clock: Clock; - init(manager: Manager): void; clear(): void; - update(dt: number): void; protected RAF(): void; play(): void; pause(): void; @@ -934,6 +964,7 @@ export class Renderer2D extends Renderer { export class SATNarrowPhase extends NarrowPhase { getCollisionPairs(contactList: CollisionPair[], clmds?: Manifold[]): Manifold[]; } +export const SQRT2: number; export class SeekBehaviour extends Behaviour { constructor(target: Vector2); radius: number; @@ -995,15 +1026,15 @@ export class Shape { }; fromJson(obj: any): void; } -export class Signal { - constructor(value: any); +export class Signal { + constructor(value: T); _listeners: any[]; - _value: any; - set value(arg: any); - get value(): any; - addListener(listener: any, callOnce?: boolean): void; - removeListener(listener: any): void; - _detach(bindingIndex: any): void; + _value: T; + set value(arg: T); + get value(): T; + addListener(listener: signalListener, callOnce?: boolean): void; + removeListener(listener: signalListener): void; + private _detach; } export class SpringConstraint extends Constraint { localA: Vector2$1; @@ -1011,7 +1042,7 @@ export class SpringConstraint extends Constraint { fixed: boolean; maxDistance: number; } -export class Sprite implements Component { +export class Sprite extends Component { constructor(geometry: BufferGeometry, material: Material); private _position; private _orientation; @@ -1025,17 +1056,10 @@ export class Sprite implements Component { get position(): Vector2; set orientation(arg: Angle); get orientation(): Angle; - render(ctx: any, dt: any): void; + render(ctx: CanvasRenderingContext2D, dt: number): void; init(entity: Entity): this; entity: Entity; - toJson(): { - pos: any; - angle: any; - geometry: any; - material: any; - parent: any; - }; - fromJson(obj: any, renderer: any): void; + fromJson(obj: any, renderer: Renderer): void; } export class SpriteMaterial implements Material { constructor(img: HTMLImageElement, frames?: number, actions?: number); @@ -1046,7 +1070,7 @@ export class SpriteMaterial implements Material { private _accumulator; frameRate: number; private _maxFrames; - width: number; + width: Vector; height: number; private frameWidth; private frameHeight; @@ -1070,10 +1094,20 @@ export namespace Storage { } export class System { static implement(system: any): void; - init(): void; - update(): void; - add(component: any): void; - remove(component: any): void; + init(manager: Manager): void; + update(dt: number): void; + add(component: Component): void; + remove(component: Component): void; +} +export const TWO_PI: number; +export class TextMaterial extends Material { + constructor(text: string); + text: string; + center: boolean; + color: string; + fill: boolean; + font: string; + render(ctx: CanvasRenderingContext2D): void; } export class Touch { constructor(eh: DOMEventHandler); @@ -1101,44 +1135,46 @@ declare class Transform$1 extends Component { fromJson(obj: any): void; } export class Triangle extends Shape { - static calcInertia(mass: any, base: any, height: any, angle: any): number; + static calcInertia(mass: number, base: number, height: number, angle: number): number; constructor(base: number, height: number, angle: number, offset: Vector2, offsetAngle: number); } +export class TriangleGeometry extends BufferGeometry { + constructor(base: any, height: any, angle: any); +} export class Trigon extends Body { constructor(base: number, height: number, angle?: number); base: number; height: number; bangle: number; } -export class Tween { - constructor(into: any); +export class Tween { + constructor(into: T); _duration: number; _repeat: boolean; active: boolean; - _to: T; - _from: any; - _into: any; - _interpolationFunc: (p0: any, p1: any, t: any) => any; - _easingFunction: (x: any) => any; - _timeTaken: number; - _updateFunc: typeof NoUpdateThrow; - _next: any; - init(entity: any): void; + private _to; + private _from; + private _into; + private _interpolationFunc; + private _easingFunction; + private _timeTaken; + private _updateFunc; + private _next; + init(entity: Entity): void; to(x: T): this; from(x: T): this; duration(t: T): this; repeat(): this; play(): void; stop(): void; - onUpdate(callback: any): this; + onUpdate(callback: TweenUpdate): this; easing(func: any): this; interpolant(func: any): this; - update(dt: any): void; - chain(next: any): this; + update(dt: number): void; + chain(next: Tween): this; } export class TweenManager extends System { - objects: any[]; - init(manager: any): void; + objects: Tween[]; update(dt: any): void; } declare var common: Readonly<{ @@ -1152,10 +1188,8 @@ declare var common: Readonly<{ mixin: typeof mixin; }>; export class Vec2 extends Vector2$1 { - constructor(x: any, y: any); } export class Vector extends Vector2$1 { - constructor(x: any, y: any); } declare class Vector2$1 { static getAbsDegBtwn(v1: Vector2, v2: Vector2): number; @@ -1204,8 +1238,8 @@ declare class Vector2$1 { toJson(): this; fromJson(obj: any): void; } -export function Vector2Update(lerpFunc: Function, to: T, from: T, t: number, into: T): void; -export function Vector3Update(lerpFunc: any, to: any, from: any, t: any, into: any): void; +export function Vector2Update(lerpFunc: LerpFunc, to: T, from: T, t: number, into: T): void; +export function Vector3Update(lerpFunc: LerpFunc, to: T, from: T, t: number, into: T): void; export class WanderBehaviour extends Behaviour { _theta: number; dtheta: number; @@ -1217,7 +1251,7 @@ export class WebGLRenderer extends Renderer { export class WebGPURenderer extends Renderer { constructor(); } -export class World { +export class World extends System { private count; protected records: Map; private objects; @@ -1248,8 +1282,6 @@ export class World { private applyGravity; private updateConstraints; private updateBodies; - update(delta: number): void; - init(manager: Manager): void; add(object: Body | Composite | Constraint): void; addBody(body: Body): void; remove(object: Body | Composite | Constraint): void; @@ -1275,25 +1307,27 @@ export function createManager(options?: { export function defaultCollisionHandler(clmds: CollisionPair[]): void; export function defaultPrecollisionHandler(clmds: Manifold[]): void; export function degToRad(deg: number): number; -export function drawImage(ctx: CanvasRenderingContext2D, img: HTMLImageElement, x: number, y: number, w?: number, h?: number, ix?: number, iy?: number): void; +export function drawImage(ctx: CanvasRenderingContext2D, img: HTMLImageElement, x: number, y: number, w?: number, h?: number, ix?: number, iy?: number, dw?: number, dh?: number): void; +export const epilson: number; export function exp(x: number, e?: number): number; export function fill(ctx: CanvasRenderingContext2D, color?: string, fillRule?: string): void; export function fillText(ctx: CanvasRenderingContext2D, text: string, x: number, y: number): void; -export function fpsDebugger(manager: any): void; +export function fpsDebugger(manager: Manager): void; export function lerp(a: number, b: number, t: number): number; export function line(ctx: CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number): void; export function map(v: number, x1: number, y1: number, x2: number, y2: number): number; -export function mixin(from: any, to: any, props?: any[]): void; +export function mixin(from: any, to: any, props?: string[]): void; export function naturalizePair(a: number, b: number): number; export function radToDeg(rad: number): number; export function rand(min?: number, max?: number): number; +export function raycastDebugger(manager: Manager): void; export function rect(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number): void; export function round(number: number, precision?: number): number; export function sq(x: number): number; export function sqrt(x: number): number; export function stroke(ctx: CanvasRenderingContext2D, color?: string, width?: number): void; export function vertices(ctx: CanvasRenderingContext2D, vertices: Vector2[], close?: boolean): void; -export function wrapAngle(x: any): any; +export function wrapAngle(x: number): number; declare class Node { constructor(bounds: { max: Vector_like; @@ -1347,7 +1381,6 @@ declare class Broadphase { } declare let r: Vector2$1; declare const a: Vector2$1; -declare function NoUpdateThrow(): void; declare function appendArr(arr1: T[], arr2: T[]): void; declare function clearArr(arr: T[]): void; declare function popArr(arr: T[], number: number): void; diff --git a/dist/chaos.module.js b/dist/chaos.module.js index b8be47c9..2b7592c6 100644 --- a/dist/chaos.module.js +++ b/dist/chaos.module.js @@ -1,7 +1,7 @@ /* * @author Wayne Mwashuma * {@link https://github.com/waynemwashuma/chaos-engine.git} - * @copyright 2023-2023 Wayne Mwashuma + * @copyright 2023-2024 Wayne Mwashuma * @license MIT * * @@ -220,7 +220,7 @@ function inheritComponent(component, overrideInit = true, overrideUpdate = true) proto.get = function(n) { return this.entity.getComponent(n); }; - proto.requires = function(entity,...names) { + proto.requires = function(entity, ...names) { for (var i = 0; i < names.length; i++) if (!entity.has(names[i])) throws(`The component \`${this.CHOAS_CLASSNAME}\` requires another component \`${names[i]}\` but cannot find it in the Entity with id ${entity.id}`); @@ -251,23 +251,17 @@ function inheritComponent(component, overrideInit = true, overrideUpdate = true) }); } /** - * Mixes the functions required by an object into another object. + * Todo - Fix this function to add all props if no props param is given + * Mixes the properties and methods required by an object from another object. * - * @param {Object} from the object constructor function to add methods from. - * @param {Object} to the object constructor function to add methods to. + * @param {*} from the object constructor function to add methods from. + * @param {*} to the object constructor function to add methods to. + * @param {string[]} [props] */ -function mixin(from, to,props = []) { - let proto = from.prototype; - let proto2 = to.prototype; - console.log(proto2); - Object.assign(proto,from); +function mixin(from, to, props = []) { for (let name of props) { - //if(!(methodName in proto))continue - //if (methodName in proto2) continue - - proto2[name] = proto[name]; + to[name] = from[name]; } - //console.log(new to()); } var common = /*#__PURE__*/Object.freeze({ @@ -336,16 +330,42 @@ class Perf{ //import { DEVICE } from "../device/index.js" class Loader { + /** + * @private + */ + _toload = [] + imgs = {} + sfx = {} + json = {} + /** + * @type {number} + * @private + */ + _progressBytes = 0 + /** + * @private + * @type {number} + */ + _totalBytes = 0 + /** + * @peivatw + * @type {number} + */ + _filesErr = 0 + /** + * @private + * @type {number} + */ + _filesLoaded = 0 + /** + * @private + * @type {number} + */ + _totalFileNo = 0 + /** + * @param {Manager} manager + */ constructor(manager) { - this._toload = []; - this.imgs = {}; - this.sfx = {}; - this.json = {}; - this._progressBytes = 0; - this._totalBytes = 0; - this._filesErr = 0; - this._filesLoaded = 0; - this._totalFileNo = 0; const that = this; this.onfinish = null; this._handlers = { @@ -392,6 +412,9 @@ class Loader { } }; } + /** + * @private + */ _getName(url) { if (url.includes("/")) { let tmp = url.split("/"); @@ -399,6 +422,9 @@ class Loader { } return url.split(".")[0] } + /** + * @private + */ _getType(url) { let ext; if (url.includes("/")) { @@ -489,7 +515,7 @@ class EventDispatcher { * Adds an event handler to an event dispatcher. * * @param {string} name name of the event. - * @param {function} handler Function to be called when the event is triggered. + * @param {EventHandlerFunc} handler Function to be called when the event is triggered. */ add(name, handler) { if (name in this.handlers) { @@ -498,7 +524,14 @@ class EventDispatcher { } this.handlers[name] = [handler]; } -} +} + +/** + * @callback EventHandlerFunc + * @param {any} data + * + * @returns {void} +*/ /** * This handles events created by the DOM. @@ -636,40 +669,69 @@ const Events = { PLAY : "play" }; +/** + * @template T + */ class Signal { _listeners = [] + /** + * @type {T} + */ _value = null - constructor(value){ + /** + * @param {T} value + */ + constructor(value) { this._value = value; } + /** + * @type {T} + */ + get value() { + return this._value + } set value(x) { this._value = x; for (var i = 0; i < this._listeners.length; i++) { let func = this._listeners[i]; func.listener(this); - if(func.callOnce) - this.removeListener(func.listener); + if (func.callOnce) + this.removeListener(func.listener); } } - get value() { - return this._value - } - addListener(listener,callOnce=false) { + /** + * @param {signalListener} listener + * @param {boolean} callOnce + */ + addListener(listener, callOnce = false) { this._listeners.push({ listener, callOnce }); } + /** + * @param {signalListener} listener + */ removeListener(listener) { for (var i = 0; i < this._listeners.length; i++) { if (this._listeners[i].listener == listener) return this._detach(i) } } - _detach(bindingIndex){ + /** + * @private + * @param {number} bindingIndex + */ + _detach(bindingIndex) { this._listeners.splice(i, 1); } -} +} + +/** + * @callback signalListener + * @param {Signal} value + * @returns {void} + */ /** * This class is responsible for managing all @@ -914,6 +976,7 @@ class Manager { for (let i = this.objects.length - 1; i >= 0; i--) { this.remove(this.objects[i]); } + this.events.trigger("clear"); } /** * This method requests an animation frame from the browser @@ -1183,7 +1246,7 @@ class Component { } /** * @param {Entity} entity - */ + */ init(entity) {} /** * @param {number} dt @@ -1192,32 +1255,49 @@ class Component { warnOnce("Please override the update function in the component " + proto.constructor.name); } /** + * @param {Entity} entity * @param {string} n */ - get(entity,n) { + get(entity, n) { return entity.getComponent(n); } /** + * @param {Entity} entity * @param {...string} names + * @rheows */ - requires(entity,...names) { + requires(entity, ...names) { for (var i = 0; i < names.length; i++) if (!entity.has(names[i])) throws(`The component \`${this.CHOAS_CLASSNAME}\` requires another component \`${names[i]}\` but cannot find it in the Entity with id ${entity.id}`); } /** + * @param {Entity} entity * @param {CircleBounding | BoxBounding} bound - * @param {Entity} [target=[]] + * @param {Entity[]} [target=[]] + * @returns {Entity[]} */ - query(entity,bound, target = []) { + query(entity, bound, target = []) { return entity.query(bound, target) } - static fromJson() { + /** + * @template {System} T + * @param {*} obj + * @param {T} system + */ + fromJson(obj, system) { throw "Implement static method fromJson() in your component " + this.CHOAS_CLASSNAME + } - static toJson() { + /** + * @returns {*} + */ + toJson() { throw "Implement static method toJson() in your component " + this.CHOAS_CLASSNAME } + /** + * @param {*} component + */ static implement(component) { inheritComponent(component); } @@ -1225,53 +1305,41 @@ class Component { /** * Updates components assigned to it. - * - * @interface */ class System { - init() { + /** + * @param {Manager} manager + */ + init(manager) { warnOnce("Please override the init method in the system " + this.constructor.name); } - update() { + /** + * @param {number} dt + */ + update(dt) { warnOnce("Please override the update method in the system " + this.constructor.name); - } + /** + * @param {Component} component + */ add(component) { this.objects.push(component); } + /** + * @param {Component} component + */ remove(component) { let index = this.objects.indexOf(component); removeElement(this.objects, index); } + //Todo - Fix this + /** + * @param {any} system + */ static implement(system) { - mixin(System,system); + mixin(System, system); } -} - -/** - * - * @function - * @name System#add - * @param {Component} component - */ -/** - * - * @function - * @name System#remove - * @param {Component} component - */ -/** - * - * @function - * @name System#init - * @param {Manager} manager - */ -/** - * - * @function - * @name System#update - * @param {number} dt - */ +} /** * This is a container to hold components,tags and event handlers. @@ -1314,10 +1382,15 @@ class Entity { * @type {boolean} */ active = false - + /** + * @type {string} + */ get CHAOS_OBJ_TYPE() { return "entity" } + /** + * @type {string} + */ get CHAOS_CLASSNAME() { return this.constructor.name.toLowerCase() } @@ -1524,12 +1597,6 @@ class Entity { } return entity } - /** - * @returns {{ - deg: number, - type:string - }} - */ toJson() { let obj = { comps: {}, @@ -1547,11 +1614,20 @@ class Entity { } class TweenManager extends System { + /** + * @type {Tween[]} + */ objects = [] + /** + * @inheritdoc + * @param {Manager} manager + */ init(manager) { manager.setComponentList("tween", this.objects); } - + /** + * @inheritdoc + */ update(dt) { for (var i = 0; i < this.objects.length; i++) { let tween = this.objects[i]; @@ -1561,9 +1637,14 @@ class TweenManager extends System { } } -const RHI = Math.PI / 180, - RHI_INV = 1 / RHI; - +const PI = Math.PI; +const TWO_PI = Math.PI * 2; +const HALF_PI = Math.PI / 2; +const DEG2RAD = Math.PI / 180; +const epilson = Math.pow(2, -53); +const RAD2DEG = 180 / Math.PI; +const SQRT2 = Math.sqrt(2); + /** * Creates a random number between the parameters * @@ -1580,7 +1661,7 @@ function rand(min = 0, max = 1) { * * @param {number} x The number to square * @returns {number} -*/ + */ function sq(x) { return x * x } @@ -1590,7 +1671,7 @@ function sq(x) { * @param {number} x the number to power. * @param {number} [e=2] The number to power by. * @returns {number} -*/ + */ function exp(x, e = 2) { return x ** e } @@ -1599,7 +1680,7 @@ function exp(x, e = 2) { * * @param {number} x The number to root * @returns {number} -*/ + */ function sqrt(x) { return Math.sqrt(x) } @@ -1612,7 +1693,7 @@ function sqrt(x) { * @param {number} b The maximum bound of the interpolation. * @param {number} t A number between 0 and 1 to interpopate by.Any other number greater than 1 or less than 0 will extapolate beyond b or a respectively. * @returns {number} -*/ + */ function lerp(a, b, t) { return a + t * (b - a) } @@ -1623,7 +1704,7 @@ function lerp(a, b, t) { * @param {number} number The number to round. * @param {number} [precision=4] How many decimal places there should be. * @returns {number} -*/ + */ function round(number, precision = 4) { precision = 10 ** precision; return Math.round(number * precision) / precision @@ -1636,7 +1717,7 @@ function round(number, precision = 4) { * @param {number} min The minimal bound of the clamped number. * @param {number} max The maximum bound of the clamped number. * @returns {number} -*/ + */ function clamp(value, min, max) { if (value < min) return min if (value > max) return max @@ -1652,7 +1733,7 @@ function clamp(value, min, max) { * @param {number} x2 * @param {number} y2 * @returns {number} -*/ + */ function map(v, x1, y1, x2, y2) { return x2 + v * (y2 - x2) / (y1 - x1) } @@ -1661,7 +1742,7 @@ function map(v, x1, y1, x2, y2) { * @param {number} a * @param {number} b * @returns {number} -*/ + */ function naturalizePair(a, b) { if (a > b) return (a + b) * (a + b + 1) / 2 + a; @@ -1673,9 +1754,9 @@ function naturalizePair(a, b) { * * @param {number} deg number to convert. * @returns {number} -*/ + */ function degToRad(deg) { - return deg * RHI + return deg * DEG2RAD } /** @@ -1683,16 +1764,28 @@ function degToRad(deg) { * * @param {number} rad number to convert. * @returns {number} -*/ + */ function radToDeg(rad) { - return rad * RHI_INV + return rad * RAD2DEG +} +/** + * @param {number} x + */ +function wrapAngle(x) { + let a = x; + while (a > Math.PI * 2) { + a = a - Math.PI * 2; + } + while (a < 0) { + a = a + Math.PI * 2; + } + return a } -let obj$1 = { +const obj$1 = { x: 0, y: 0 }; -let TWO_PI = Math.PI * 2; /** * This is a 2D vector class. * @@ -1749,7 +1842,7 @@ class Vector2$1 { distanceTo(v) { obj$1.x = this.x - v.x; obj$1.y = this.y - v.y; - return Math.sqrt( Vector2$1.prototype.magnitudeSquared.call(obj$1)) + return Math.sqrt(Vector2$1.prototype.magnitudeSquared.call(obj$1)) } /** *Calculates length squared of this vector to another vector @@ -2021,7 +2114,7 @@ class Vector2$1 { return this.multiply(min / length) return this } - + toJson() { return this } @@ -2160,15 +2253,24 @@ class Vector2$1 { static ZERO = Object.freeze(new Vector2$1()) } -class Vector extends Vector2$1{ - constructor(x,y){ - super(x,y); +class Vector extends Vector2$1 { + /** + * @param {number} x the x coordinate of the vector + * @param {number} y the y coordinate of the vector + */ + constructor(x, y) { + super(x, y); console.error("The class `Vector` is depreciated since v0.4.13.Use Vector2 instead."); } } -class Vec2 extends Vector2$1{ - constructor(x,y){ - super(x,y); + +class Vec2 extends Vector2$1 { + /** + * @param {number} x the x coordinate of the vector + * @param {number} y the y coordinate of the vector + */ + constructor(x, y) { + super(x, y); console.error("The class `Vec2` is depreciated since v0.4.13.Use Vector2 instead."); } } @@ -2206,7 +2308,7 @@ class Angle { //TODO - Change this to radians instead constructor(deg = 0) { - this.value = deg * Math.PI/2; + this.value = deg * Math.PI/180; } /** * @type string @@ -2522,84 +2624,130 @@ class Matrix2 { } } -function wrapAngle(x) { - let a = x; - while (a > Math.PI * 2) { - a = a - Math.PI * 2; - } - while (a < 0) { - a = a + Math.PI * 2; - } - return a -} - const Easing = { + /** + * @type {EasingFunc} + */ linear: function(x) { return x; }, + /** + * @type {EasingFunc} + */ quadraticIn: function(x) { return x * x; }, + /** + * @type {EasingFunc} + */ quadraticOut: function(x) { return x * (2 - x); }, + /** + * @type {EasingFunc} + */ quadraticInOut: function(x) { if ((x *= 2) < 1) { return 0.5 * x * x; } return -0.5 * (--x * (x - 2) - 1); }, + /** + * @type {EasingFunc} + */ cubicIn: function(x) { return x * x * x; }, + /** + * @type {EasingFunc} + */ cubicOut: function(x) { return --x * x * x + 1; }, + /** + * @type {EasingFunc} + */ cubicInOut: function(x) { if ((x *= 2) < 1) { return 0.5 * x * x * x; } return 0.5 * ((x -= 2) * x * x + 2); }, + /** + * @type {EasingFunc} + */ quarticIn: function(x) { return x * x * x * x; }, + /** + * @type {EasingFunc} + */ quarticOut: function(x) { return 1 - --x * x * x * x; }, + /** + * @type {EasingFunc} + */ quarticInOut: function(x) { if ((x *= 2) < 1) { return 0.5 * x * x * x * x; } return -0.5 * ((x -= 2) * x * x * x - 2); }, + /** + * @type {EasingFunc} + */ quinticIn: function(x) { return x * x * x * x * x; }, + /** + * @type {EasingFunc} + */ quinticOut: function(x) { return --x * x * x * x * x + 1; }, + /** + * @type {EasingFunc} + */ quinticInOut: function(x) { if ((x *= 2) < 1) { return 0.5 * x * x * x * x * x; } return 0.5 * ((x -= 2) * x * x * x * x + 2); }, + /** + * @type {EasingFunc} + */ sinusoidalIn: function(x) { return 1 - Math.sin(((1.0 - x) * Math.PI) / 2); }, + /** + * @type {EasingFunc} + */ sinusoidalOut: function(x) { return Math.sin((x * Math.PI) / 2); }, + /** + * @type {EasingFunc} + */ sinusoidalInOut: function(x) { return 0.5 * (1 - Math.sin(Math.PI * (0.5 - x))); }, + /** + * @type {EasingFunc} + */ exponentialIn: function(x) { return x === 0 ? 0 : Math.pow(1024, x - 1); }, + /** + * @type {EasingFunc} + */ exponentialOut: function(x) { return x === 1 ? 1 : 1 - Math.pow(2, -10 * x); }, + /** + * @type {EasingFunc} + */ exponentialInOut: function(x) { if (x === 0) { return 0; @@ -2612,18 +2760,30 @@ const Easing = { } return 0.5 * (-Math.pow(2, -10 * (x - 1)) + 2); }, + /** + * @type {EasingFunc} + */ circularIn: function(x) { return 1 - Math.sqrt(1 - x * x); }, + /** + * @type {EasingFunc} + */ circularOut: function(x) { return Math.sqrt(1 - --x * x); }, + /** + * @type {EasingFunc} + */ circularInOut: function(x) { if ((x *= 2) < 1) { return -0.5 * (Math.sqrt(1 - x * x) - 1); } return 0.5 * (Math.sqrt(1 - (x -= 2) * x) + 1); }, + /** + * @type {EasingFunc} + */ elasticIn: function(x) { if (x === 0) { return 0; @@ -2633,6 +2793,9 @@ const Easing = { } return -Math.pow(2, 10 * (x - 1)) * Math.sin((x - 1.1) * 5 * Math.PI); }, + /** + * @type {EasingFunc} + */ elasticOut: function(x) { if (x === 0) { return 0; @@ -2642,6 +2805,9 @@ const Easing = { } return Math.pow(2, -10 * x) * Math.sin((x - 0.1) * 5 * Math.PI) + 1; }, + /** + * @type {EasingFunc} + */ elasticInOut: function(x) { if (x === 0) { return 0; @@ -2655,14 +2821,23 @@ const Easing = { } return 0.5 * Math.pow(2, -10 * (x - 1)) * Math.sin((x - 1.1) * 5 * Math.PI) + 1; }, + /** + * @type {EasingFunc} + */ backIn: function(x) { var s = 1.70158; return x === 1 ? 1 : x * x * ((s + 1) * x - s); }, + /** + * @type {EasingFunc} + */ backOut: function(x) { var s = 1.70158; return x === 0 ? 0 : --x * x * ((s + 1) * x + s) + 1; }, + /** + * @type {EasingFunc} + */ backInOut: function(x) { var s = 1.70158 * 1.525; if ((x *= 2) < 1) { @@ -2670,10 +2845,16 @@ const Easing = { } return 0.5 * ((x -= 2) * x * ((s + 1) * x + s) + 2); }, + /** + * @type {EasingFunc} + */ bounceIn: function(x) { return 1 - Easing.bounceOut(1 - x); }, - bounceOut: function(x) { + /** + * @type {EasingFunc} + */ + bounceOut: function(x) { if (x < 1 / 2.75) { return 7.5625 * x * x; } @@ -2687,6 +2868,9 @@ const Easing = { return 7.5625 * (x -= 2.625 / 2.75) * x + 0.984375; } }, + /** + * @type {EasingFunc} + */ bounceInOut: function(x) { if (x < 0.5) { return Easing.bounceIn(x * 2) * 0.5; @@ -2696,9 +2880,17 @@ const Easing = { }; const Interpolation = { + /** + * @param {number} p0 + * @param {number} p1 + * @param {number} t + * + * @returns {number} + */ Linear: function(p0, p1, t) { return (p1 - p0) * t + p0 }, + //Todo - remove this Bernstein and Factorial. Bernstein: function(n, i) { const fc = Interpolation.Utils.Factorial; @@ -2722,7 +2914,15 @@ const Interpolation = { return s } })(), - + /** + * @param {number} p0 + * @param {number} p1 + * @param {number} p2 + * @param {number} p3 + * @param {number} t + * + * @returns {number} + */ CatmullRom: function(p0, p1, p2, p3, t) { const v0 = (p2 - p0) * 0.5; const v1 = (p3 - p1) * 0.5; @@ -2733,160 +2933,6 @@ const Interpolation = { }, }; -/** - * Component responsible for animations. - * - * @template {T} - */ -class Tween { - _duration = 0 - _repeat = false - active = false - /** - * @type {T} - */ - _to = null - _from = null - _into = null - _interpolationFunc = Interpolation.Linear - _easingFunction = Easing.linear - _timeTaken = 0 - _updateFunc = NoUpdateThrow - _next = null - /** - *@template {T} - *@param {T} to - *@param {T} from - *@param {number} duration - */ - constructor(into) { - this._into = into; - } - init(entity) { - this.play(); - } - /** - * @param {T} x - */ - to(x) { - this._to = x; - return this - } - /** - * @param {T} x - */ - from(x) { - this._from = x; - return this - } - /** - * @param {T} t - */ - duration(t) { - this._duration = t; - return this - } - repeat() { - this._repeat = true; - return this - } - play() { - this._timeTaken = 0; - this.active = true; - } - stop() { - this.active = false; - } - onUpdate(callback) { - this._updateFunc = callback; - return this - } - easing(func) { - this._easingFunction = func; - return this - } - interpolant(func) { - this._interpolationFunc = func; - return this - } - update(dt) { - if (!this.active) return - - this._timeTaken += dt; - if (this._timeTaken >= this._duration) { - if(this._next !== void 0){ - this.stop(); - this._next.play(); - } - if (this._repeat) { - this._timeTaken = 0; - } else { - this._timeTaken = this._duration; - this.active = false; - } - } - let t = this._easingFunction( - this._timeTaken / this._duration - ); - this._updateFunc( - this._interpolationFunc, - this._to, - this._from, - t, - this._into - ); - } - chain(next) { - this._next = next; - return this - } -} - -/** - * @type Tween - */ -new Tween(); - -/** - * @template {T} - * @callback TweenUpdate - * @param {Function} lerpFunc - * @param {T} to - * @param {T} from - * @param {number} t - * @param {T} into - * - * @returns {void} - */ - -/** - * @type {TweenUpdate} - */ -function Vector2Update(lerpFunc, to, from, t, into) { - into.x = lerpFunc(from.x, to.x, t); - into.y = lerpFunc(from.y, to.y, t); -} -function Vector3Update(lerpFunc, to, from, t, into) { - into.x = lerpFunc(from.x, to.x, t); - into.y = lerpFunc(from.y, to.y, t); - into.z = lerpFunc(from.z, to.z, t); -} - -function ColorUpdate(lerpFunc, to, from, t, into) { - into.r = lerpFunc(from.r, to.r, t); - into.g = lerpFunc(from.g, to.g, t); - into.b = lerpFunc(from.b, to.b, t); - into.a = lerpFunc(from.a, to.a, t); -} - -function AngleUpdate(lerpFunc, to, from, t, into) { - into.rad = lerpFunc(from.rad, to.rad, t); -} - -function NoUpdateThrow() { - throw "The Tween does not have a valid onUpdate callback." -} - /** * This module is used to check if bounds of a body overlap */ @@ -3167,35 +3213,397 @@ class BoundingCircle { } } - this.pos.x = body.position.x; - this.pos.y = body.position.y; - this.r = Math.sqrt(radsq); + this.pos.x = body.position.x; + this.pos.y = body.position.y; + this.r = Math.sqrt(radsq); + } + /** + * Translates this bound to the given position. + * + * @param {Vector_like} pos + */ + update(pos) { + //let dx = pos.x - this.pos.x + //let dy = pos.y - this.pos.y + + this.pos.x = pos.x; + this.pos.y = pos.y; + } + toJson(){ + return { + posX:this.pos.x, + posY:this.pos.y, + r:this.r + } + } + fromJson(obj){ + this.pos.x = obj.posX; + this.pos.y = obj.posY; + this.r = obj.r; + } +} + +/** + * A color manipulation class. + */ +class Color { + + /** + * @param {number} [r=0] - red component [0 .. 255] + * @param {number} [g=0] - green component [0 .. 255] + * @param {number} [b=0] - blue component [0 .. 255] + * @param {number} [alpha=1.0] - alpha value [0.0 .. 1.0] + */ + constructor(r = 0, g = 0, b = 0, alpha = 1.0) { + this.set(r, g, b, alpha); + } + + /** + * Set this color to the specified value. + * @param {number} r - red component [0 .. 255] + * @param {number} g - green component [0 .. 255] + * @param {number} b - blue component [0 .. 255] + * @param {number} [alpha=1.0] - alpha value [0.0 .. 1.0] + * @returns {Color} Reference to this object for method chaining + */ + set(r, g, b, alpha = 1.0) { + this.r = r; + this.g = g; + this.b = b; + this.a = alpha; + return this; + } + + /** + * Create a new copy of this color object. + * @returns {Color} Reference to the newly cloned object + */ + clone() { + return new Color().copy(this); + } + + /** + * Copy a color object or CSS color into this one. + * @param {Color|string} color + * @returns {Color} Reference to this object for method chaining + */ + copy(color) { + this.set(color.r, color.g, color.b, color.a); + } + + /** + * Blend this color with the given one using addition. + * @param {Color} color + * @returns {Color} Reference to this object for method chaining + */ + add(color) { + this.r = clamp(this.r + color.r, 0, 255); + this.g = clamp(this.g + color.g, 0, 255); + this.b = clamp(this.b + color.b, 0, 255); + this.a = (this.a + color.a) / 2; + + return this; + } + + /** + * Darken this color value by 0..1 + * @param {number} scale + * @returns {Color} Reference to this object for method chaining + */ + darken(scale) { + scale = clamp(scale, 0, 1); + this.r *= scale; + this.g *= scale; + this.b *= scale; + + return this; + } + + /** + * Linearly interpolate between this color and the given one. + * @param {Color} color + * @param {number} alpha - with alpha = 0 being this color, and alpha = 1 being the given one. + * @returns {Color} Reference to this object for method chaining + */ + lerp(color, alpha) { + alpha = clamp(alpha, 0, 1); + this.r += (color.r - this.r) * alpha; + this.g += (color.g - this.g) * alpha; + this.b += (color.b - this.b) * alpha; + + return this; + } + + /** + * Lighten this color value by 0..1 + * @param {number} scale + * @returns {Color} Reference to this object for method chaining + */ + lighten(scale) { + scale = clamp(scale, 0, 1); + this.r = clamp(this.r + (1 - this.r) * scale, 0, 1); + this.g = clamp(this.g + (1 - this.g) * scale, 0, 1); + this.b = clamp(this.b + (1 - this.b) * scale, 0, 1); + + return this; + } + + /** + * Generate random r,g,b values for this color object + * @param {number} [min=0] - minimum value for the random range + * @param {number} [max=255] - maxmium value for the random range + * @returns {Color} Reference to this object for method chaining + */ + random(min = 0, max = 255) { + if (min < 0) { + min = 0; + } + if (max > 255) { + max = 255; + } + + return this.set( + rand(min, max), + rand(min, max), + rand(min, max), + this.a + ); + } + + + toArray(array, offset = 0) { + array[offset] = this.r; + array[offset + 1] = this.g; + array[offset + 2] = this.b; + array[offset + 3] = this.a; + + return array + } +} + +/** + * Component responsible for animations. + * + * @template T + */ +class Tween { + /** + * @type {number} + */ + _duration = 0 + /** + * @type {boolean} + */ + _repeat = false + /** + * @type {boolean} + */ + active = false + /** + * @type {T} + * @private + */ + _to = null + /** + * @type {T} + * @private + */ + _from = null + /** + * @type {T} + * @private + */ + _into = null + /** + * @type {LerpFunc} + * @private + */ + _interpolationFunc = Interpolation.Linear + /** + * @type {EasingFunc} + * @private + */ + _easingFunction = Easing.linear + /** + * @type {number} + * @private + */ + _timeTaken = 0 + /** + * @type {TweenUpdate} + * @private + */ + _updateFunc = NoUpdateThrow + /** + * @type {Tween} + * @private + */ + _next = null + /** + *@param {T} into + */ + constructor(into) { + this._into = into; + } + /** + * @param {Entity} entity + */ + init(entity) { + this.play(); + } + /** + * @param {T} x + */ + to(x) { + this._to = x; + return this + } + /** + * @param {T} x + */ + from(x) { + this._from = x; + return this + } + /** + * @param {T} t + */ + duration(t) { + this._duration = t; + return this + } + repeat() { + this._repeat = true; + return this + } + play() { + this._timeTaken = 0; + this.active = true; + } + stop() { + this.active = false; + } + /** + * @param {TweenUpdate} callback + */ + onUpdate(callback) { + this._updateFunc = callback; + return this + } + /** + * @param {EasingFunc} callback + */ + easing(func) { + this._easingFunction = func; + return this + } + /** + * @param {LerpFunc} callback + */ + interpolant(func) { + this._interpolationFunc = func; + return this + } + /** + * @param {number} dt + */ + update(dt) { + if (!this.active) return + + this._timeTaken += dt; + if (this._timeTaken >= this._duration) { + if (this._next !== void 0) { + this.stop(); + this._next.play(); + } + if (this._repeat) { + this._timeTaken = 0; + } else { + this._timeTaken = this._duration; + this.active = false; + } + } + let t = this._easingFunction( + this._timeTaken / this._duration + ); + this._updateFunc( + this._interpolationFunc, + this._to, + this._from, + t, + this._into + ); } /** - * Translates this bound to the given position. - * - * @param {Vector_like} pos + * @param {Tween} next */ - update(pos) { - //let dx = pos.x - this.pos.x - //let dy = pos.y - this.pos.y - - this.pos.x = pos.x; - this.pos.y = pos.y; - } - toJson(){ - return { - posX:this.pos.x, - posY:this.pos.y, - r:this.r - } - } - fromJson(obj){ - this.pos.x = obj.posX; - this.pos.y = obj.posY; - this.r = obj.r; + chain(next) { + this._next = next; + return this } -} +} +/** + * @template T + * @type {TweenUpdate} + */ +function Vector2Update(lerpFunc, to, from, t, into) { + into.x = lerpFunc(from.x, to.x, t); + into.y = lerpFunc(from.y, to.y, t); +} +/** + * @template T + * @type {TweenUpdate} + */ +function Vector3Update(lerpFunc, to, from, t, into) { + into.x = lerpFunc(from.x, to.x, t); + into.y = lerpFunc(from.y, to.y, t); + into.z = lerpFunc(from.z, to.z, t); +} + +/** + * @template T + * @type {TweenUpdate} + */ +function ColorUpdate(lerpFunc, to, from, t, into) { + into.r = lerpFunc(from.r, to.r, t); + into.g = lerpFunc(from.g, to.g, t); + into.b = lerpFunc(from.b, to.b, t); + into.a = lerpFunc(from.a, to.a, t); +} +/** + * @template T + * @type {TweenUpdate} + */ +function AngleUpdate(lerpFunc, to, from, t, into) { + into.rad = lerpFunc(from.rad, to.rad, t); +} +/** + * @template T + * @type {TweenUpdate} + */ +function NoUpdateThrow(lerpFunc, to, from, t, into) { + throw "The Tween does not have a valid onUpdate callback." +} + +/** + * @template {T} + * @callback TweenUpdate + * @param {LerpFunc} lerpFunc + * @param {T} to + * @param {T} from + * @param {number} t + * @param {T} into + * + * @returns {void} + */ + +/** + * @callback LerpFunc + * @param {number} p0 + * @param {number} p1 + * @param {number} t + * @returns {number} + */ class Geometry { /** @@ -3232,7 +3640,7 @@ class Geometry { } /** * @param {number} rad - * @param { Vector2[]} target + * @param {Vector2[]} target */ getNormals(rad, target) { target = target || []; @@ -3267,7 +3675,7 @@ class Geometry { * @param {number} n * @param { Vector2[]} vertices * @param { Vector2} pos - * @patam {number} rad + * @param {number} rad */ transform(vertices, pos, rad, n) { for (let i = 0; i < this.vertices.length; i++) { @@ -3331,7 +3739,7 @@ const Settings = { type:BodyType.DYNAMIC }; -let tmp1$c = new Vector2$1(); +let tmp1$d = new Vector2$1(); /** * This class makes a body tangible @@ -3419,7 +3827,7 @@ class Shape { */ update(position, angle, scale) { this.angle = this.offAngle + angle; - this.geometry.transform(this.vertices, tmp1$c.copy(position).add(this.offPosition), this.angle, 1 , position); + this.geometry.transform(this.vertices, tmp1$d.copy(position).add(this.offPosition), this.angle, 1 , position); } /** @@ -3470,7 +3878,7 @@ class Line extends Shape { /** * @param {number} length * @param { Vector2} offset - * @param {number} pffsetAngle + * @param {number} offsetAngle */ constructor(length,offset,offsetAngle) { let start = new Vector2$1(1).multiply(length / 2), @@ -3624,7 +4032,7 @@ class Rectangle extends Shape { } -let tmp1$b = new Vector2$1(); +let tmp1$c = new Vector2$1(); /** * A triangular shape. @@ -3638,18 +4046,23 @@ class Triangle extends Shape { * @param {number} angle The angle between the two sides. * @param { Vector2} offset Positional offset from the body center. * @param {number} offsetAngle Angular offset from the body center. - * */ constructor(base, height, angle, offset, offsetAngle) { let l1 = new Vector2$1().set(1, 0).multiply(base); let l2 = Vector2$1.fromRad(angle).multiply(height/Math.sin(angle)); - let center = tmp1$b.set((l1.x + l2.x) / 3, l2.y / 3); + let center = tmp1$c.set((l1.x + l2.x) / 3, l2.y / 3); super([ new Vector2$1().sub(center), l1.sub(center), l2.sub(center) ], offset, offsetAngle); } + /** + * @param {number} mass + * @param {number} base + * @param {number} height + * @param {number} angle + */ static calcInertia(mass,base,height,angle){ return 0.5 * mass * base * height * (1 - 2/3 * (1 - (Math.cos(2 * angle * 180/Math.PI))/2)) } @@ -3710,6 +4123,10 @@ class Transform$1 extends Component{ * */ class Movable$1 extends Component { + /** + * @type {Transform} + */ + transform = null /** * * @param {number} x * @param {number} y @@ -3718,12 +4135,14 @@ class Movable$1 extends Component { */ constructor(x, y, a) { super(); - this.transform = null; this.velocity = new Vector2$1(x, y); this.rotation = new Angle(a); this.acceleration = new Vector2$1(); this.torque = new Angle(); } + /** + * @inheritdoc + */ init(entity) { this.requires(entity, "transform"); if (!this.transform) @@ -3744,19 +4163,34 @@ class Movable$1 extends Component { } class Intergrator extends System { + /** + * @type {boolean} + */ active = false + /** + * @type {typeof EulerSolver.solve} + */ solver = EulerSolver.solve + /** + * @type {Movable} + */ objects = [] constructor() { super(); } + /** + * @inheritdoc + */ init(manager) { const world = manager.getSystem("world"); if (world) world.enableIntergrate = false; this.active = true; - + manager.setComponentList("movable", this.objects); } + /** + * @inheritdoc + */ update(dt) { for (let i = 0; i < this.objects.length; i++) { if (this.objects[i] == void 0) return @@ -3775,6 +4209,8 @@ const a = new Vector2$1(); */ class EulerSolver { /** + * @param {Transform} transform + * @param {Movable} movable * @param {number} dt */ static solve(transform, movable, dt) { @@ -4187,15 +4623,23 @@ class Body extends Component { /** * Applies a force to a body affecting its direction of travel and rotation. * - * * @param { Vector2} force The force to be applied. - * @param { Vector2} [arm= Vector2] The collision arm. + * @param { Vector2} [arm = Vector2] The collision arm. */ applyForce(force, arm = Vector2$1.ZERO) { this.acceleration.add(force.multiply(this.inv_mass)); - this.rotation.value += arm.cross(force) * this.inv_inertia; + this.torque.value += arm.cross(force) * this.inv_inertia; + } + /** + * Applies a force to a body affecting its direction of travel and rotation. + * + * @param { Vector2} impulse The force to be applied. + * @param { Vector2} [arm = Vector2] The collision arm. + */ + applyImpulse(impulse, arm = Vector2$1.ZERO) { + this.velocity.add(impulse.multiply(this.inv_mass)); + this.rotation.value += arm.cross(impulse) * this.inv_inertia; } - /** * Initializes the body to its given.Called by the world or an entity manager. * @@ -4208,8 +4652,8 @@ class Body extends Component { this.bounds = new BoundingBox(); if (entity != void 0) { this._movable.transform = this._transform; - entity.manager.addComponent("transform",this._transform); - entity.manager.addComponent("movable",this._movable); + entity.manager.addComponent("transform", this._transform); + entity.manager.addComponent("movable", this._movable); } this.update(); return @@ -4241,9 +4685,9 @@ class Body extends Component { this.bounds.update(this.position); //this.angle = this.angle > 360 ? this.angle - 360 : this.angle < 0 ? 360 + this.angle : this.angle } - - destroy(){ - this.entity.manager.removeComponent("movable",this._movable); + + destroy() { + this.entity.manager.removeComponent("movable", this._movable); } toJson() { let obj = { @@ -4274,7 +4718,12 @@ class Body extends Component { }); return obj } - //TODO - Add way to add shapes to body + /** + * @@param {Shape} shape + */ + addShape(shape) { + this.shapes.push(shape); + } fromJson(obj) { let shapes = []; obj.shapes.forEach((shape) => { @@ -4626,6 +5075,30 @@ class Trigon extends Body { * @see SpringConstraint */ class Constraint { + /** + * @type {Vector2} + */ + localA = null + /** + * @type {Vector2} + */ + localB = null + /** + * @type {Body} + */ + body1 = null + /** + * @type {Body} + */ + body2 = null + /**: + * @type {number} + */ + stiffness = 50 + /** + * @type {number} + */ + dampening = 0.03 /** * @param {Body} body1 * @param {Body} body2 @@ -4637,8 +5110,6 @@ class Constraint { this.body2 = body2; this.localA = localA || new Vector2$1(); this.localB = localB || new Vector2$1(); - this.stiffness = 50; - this.dampening = 0.03; } /** * Determine type of object this is in the world. @@ -4688,7 +5159,7 @@ class Constraint { localB: this.localB.toJson(), stiffness: this.stiffness, dampening: this.dampening, - type:this.CHAOS_OBJ_TYPE + type: this.CHAOS_OBJ_TYPE } } fromJson(obj, world) { @@ -4707,7 +5178,7 @@ class Constraint { } } -let tmp1$a = new Vector2$1(), +let tmp1$b = new Vector2$1(), tmp2$8 = new Vector2$1(), tmp3$4 = new Vector2$1(), tmp4$4 = new Vector2$1(), @@ -4738,7 +5209,7 @@ class DistanceConstraint extends Constraint { * @param {number} dt */ behavior(body1, body2,dt) { - let arm1 = tmp1$a.copy(this.localA), + let arm1 = tmp1$b.copy(this.localA), arm2 = tmp2$8.copy(this.localB), pos1 = tmp3$4.copy(body1.position).add(arm1), pos2 = tmp4$4.copy(body2.position).add(arm2), @@ -4766,7 +5237,7 @@ class DistanceConstraint extends Constraint { } } -let tmp1$9 = new Vector2$1(), +let tmp1$a = new Vector2$1(), tmp2$7 = new Vector2$1(), tmp3$3 = new Vector2$1(), tmp4$3 = new Vector2$1(), @@ -4799,7 +5270,7 @@ class SpringConstraint extends Constraint { * @param {number} dt */ behavior(body1, body2, dt) { - let arm1 = tmp1$9.copy(this.localA), + let arm1 = tmp1$a.copy(this.localA), arm2 = tmp2$7.copy(this.localB), pos1 = tmp3$3.copy(body1.position).add(arm1), pos2 = tmp4$3.copy(body2.position).add(arm2), @@ -4853,7 +5324,7 @@ class VerletSolver { } } -let tmp1$8 = new Vector2$1(), +let tmp1$9 = new Vector2$1(), tmp2$6 = new Vector2$1(), tmp3$2 = new Vector2$1(), tmp4$2 = new Vector2$1(), @@ -4868,7 +5339,7 @@ const FrictionSolver = { let { bodyA: a, bodyB: b, ca1, ca2, impulse } = manifold; let { axis } = manifold.contactData; if (impulse <= 0) return - let a$va = tmp1$8.set(ca1.y * -a.rotation.value, ca1.x * a.rotation.value); + let a$va = tmp1$9.set(ca1.y * -a.rotation.value, ca1.x * a.rotation.value); let a$vb = tmp2$6.set(ca2.y * -b.rotation.value, ca2.x * b.rotation.value); let va = tmp3$2.copy(a.velocity).add(a$va); let vb = tmp4$2.copy(b.velocity).add(a$vb); @@ -4933,7 +5404,7 @@ const ContactSolver = { } }; -const tmp1$7 = new Vector2$1(), +const tmp1$8 = new Vector2$1(), tmp2$5 = new Vector2$1(); let dampen = Settings.posDampen; @@ -4948,15 +5419,15 @@ const PenetrationSolver = { const dampened = overlap * dampen; const a = dampened / (bodyA.inv_mass + bodyB.inv_mass + sq(ca1.cross(axis)) * bodyA.inv_inertia + sq(ca2.cross(axis)) * bodyB.inv_inertia); let jp = tmp2$5.copy(axis).multiply(a); - bodyA.velocity.add(tmp1$7.copy(jp).multiply(bodyA.inv_mass * inv_dt)); - bodyB.velocity.add(tmp1$7.copy(jp).multiply(-bodyB.inv_mass * inv_dt)); + bodyA.velocity.add(tmp1$8.copy(jp).multiply(bodyA.inv_mass * inv_dt)); + bodyB.velocity.add(tmp1$8.copy(jp).multiply(-bodyB.inv_mass * inv_dt)); bodyA.rotation.value += ca1.cross(jp) * bodyA.inv_inertia * inv_dt; bodyB.rotation.value += ca2.cross(jp) * -bodyB.inv_inertia * inv_dt; manifold.contactData.lastOverlap = overlap; } }; -let tmp1$6 = new Vector2$1(), +let tmp1$7 = new Vector2$1(), tmp2$4 = new Vector2$1(), tmp3$1 = new Vector2$1(), tmp4$1 = new Vector2$1(); @@ -4968,7 +5439,7 @@ const ImpulseSolver = { solve(manifold) { let { bodyA, bodyB, ca1, ca2, restitution } = manifold; let { axis } = manifold.contactData; - let a$va = tmp1$6.set(ca1.y * -bodyA.rotation.value, ca1.x * bodyA.rotation.value); + let a$va = tmp1$7.set(ca1.y * -bodyA.rotation.value, ca1.x * bodyA.rotation.value); let a$vb = tmp2$4.set(ca2.y * -bodyB.rotation.value, ca2.x * bodyB.rotation.value); let va = tmp3$1.copy(bodyA.velocity).add(a$va); let vb = tmp4$1.copy(bodyB.velocity).add(a$vb); @@ -5496,6 +5967,9 @@ class QuadTreeBroadphase extends Broadphase { if (maxdepth) this._root.split(maxdepth); } + /** + * @private + */ _insert(client) { client.bounds.copy(client.body.bounds); if (!this._root.contains(obj.bounds)) @@ -5513,6 +5987,9 @@ class QuadTreeBroadphase extends Broadphase { } this._insert(client); } + /** + * @private + */ _remove(client) { return this._root.removeObject(obj) } @@ -5548,7 +6025,7 @@ class QuadTreeBroadphase extends Broadphase { /** * A depth first search of the quadtree that applies the given function to its nodes. * - * @param {Function} func The function that checks every node unless it returns true. + * @param {Traverser} func The function that checks every node unless it returns true. * */ traverse(func) { @@ -5570,7 +6047,7 @@ class QuadTreeBroadphase extends Broadphase { * Resizes a quadtree to a new bound size. * This method should not be used without care. * - * @param {Bounds} bounds. + * @param {Bounds} bounds * */ recalculateBounds(bounds) { @@ -5601,10 +6078,10 @@ class QuadTreeBroadphase extends Broadphase { * @callback Traverser * @param {Node} node * @returns {boolean} -*/ + */ const _arr = [], - tmp1$5 = { + tmp1$6 = { overlap: 0, verticesA: null, verticesB: null, @@ -5716,7 +6193,7 @@ const SAT = { * @param {number} iu */ projectShapesToAxes(shapeA, shapeB, axes, manifold, iu) { - let temp = tmp1$5; + let temp = tmp1$6; temp.vertex = null; temp.body = null; temp.overlap = Infinity; @@ -5871,7 +6348,15 @@ const SAT = { }; class NarrowPhase{ + /** + * @type {Map} + */ records = new Map() + /** + * @param {CollisionPair[]} contactList + * @param {Manifold[]} clmds + * @returns {Manifold[]} + */ getCollisionPairs(contactList,clmds){ } } @@ -5958,7 +6443,7 @@ class SATNarrowPhase extends NarrowPhase { /** * Class responsible for updating bodies,constraints and composites. */ -class World { +class World extends System { /** * Used to check if a manifold is persistent. * @@ -6073,6 +6558,7 @@ class World { enableIntergrate = true constructor() { + super(); this.broadphase = new NaiveBroadphase(this); this.narrowphase = new SATNarrowPhase(); } @@ -6181,6 +6667,8 @@ class World { let a = this.objects[i]; if (a.mass) a.acceleration.add(this.gravitationalAcceleration); + a.velocity.add(a.acceleration.multiply(dt)); + a.acceleration.set(0, 0); } } /** @@ -6393,10 +6881,10 @@ class Camera { * @see WebGLRenderer * @see WebGPURenderer */ -class Renderer { +class Renderer extends System { /** * @type number - */ + */ _rafID = 0 /** * Used to throttle the frame rate. @@ -6435,6 +6923,7 @@ class Renderer { * @param {HTMLCanvasElement} canvas element to draw on */ constructor(canvas, context) { + super(); this.domElement = canvas; this.ctx = context; this.camera = new Camera(this); @@ -6660,10 +7149,9 @@ class WebGLRenderer extends Renderer{ * This is the base class used to render images and paths onto the renderer. * Extend it to create your custom behaviour. * - * @implements Component * TODO - ADD id property to this class and Group class. */ -class Sprite { +class Sprite extends Component{ /** * @private */ @@ -6693,6 +7181,7 @@ class Sprite { * @param {Material} material */ constructor(geometry, material) { + super(); this.geometry = geometry; this.material = material; } @@ -6729,6 +7218,10 @@ class Sprite { set orientation(x) { this._orientation.copy(x); } + /** + * @param {CanvasRenderingContext2D} ctx + * @param {number} dt + */ render(ctx, dt) { ctx.save(); ctx.beginPath(); @@ -6758,6 +7251,10 @@ class Sprite { this._scale = new Vector2$1(1,1); return this } + /** + * @inheritdoc + * @returns {*} + */ toJson(){ let obj = { pos:this._position.toJson(), @@ -6768,11 +7265,17 @@ class Sprite { }; return obj } + /** + * @inheritdoc + * + * @param {Renderer} renderer + */ fromJson(obj,renderer){ this.geometry?.fromJson(obj.geometry); this.material?.fromJson(obj.material); this.position.fromJson(obj.pos); this._orientation.fromJson(obj.angle); + //Todo - implement this renderer function this.parent = renderer.getById(obj.parent); } } @@ -6974,12 +7477,14 @@ function drawImage( w = img.width, h = img.height, ix = 0, - iy = 0 + iy = 0, + dw = w, + dh = h ) { ctx.drawImage(img, w * ix, h * iy, w, h, x, y, - w, h); + dw, dh); } /** @@ -6988,74 +7493,76 @@ function drawImage( */ class SpriteMaterial { /** - * @type HTMLImageElement + * @type {HTMLImageElement} */ img = null /** * The index of the current action. * * @private - * @type number + * @type {number} */ _index = 0 /** * The current action's max frame index. * * @private - * @type number + * @type {number} */ _maxFrame = 0 /** * The current frame of an action. * * @private - * @type number + * @type {number} */ _frame = 0 /** * Used with ImageSprite#frameRate to throttle the fps of the sprite. * * @private - * @type number + * @type {number} */ _accumulator = 0 /** * The maximum frames for each given action. * - * @type number + * @type {number} */ frameRate = 1 / 60 /** * The current action. * * @private - * @type number[] + * @type {number[]} */ - _maxFrames = null + _maxFrames = [] + /** + * @type {Vector} /** * The width of the sprite. * - * @type number + * @type {number} */ width = 0 /** * The height of the sprite.. * - * @type number + * @type {number} */ height = 0 /** * The width of a frame. * * @private - * @type number + * @type {number} */ frameWidth = 0 /** * The height of a frame.. * * @private - * @type number + * @type {number} */ frameHeight = 0 /** @@ -7074,10 +7581,13 @@ class SpriteMaterial { */ setup(frames, actions) { this._maxFrame = frames - 1; - this.width = this.img.width; - this.height = this.img.height; this.frameWidth = this.img.width / (frames || 1); this.frameHeight = this.img.height / actions; + this.width ||= this.frameWidth; + this.height ||= this.frameHeight; + for (var i = 0; i < actions; i++) { + this._maxFrames.push(frames); + } } /** * Sets max number of frames for a given action @@ -7086,39 +7596,91 @@ class SpriteMaterial { * @param {number} max */ setMaxFrames(action, max) { - this._maxFrames = max; + this._maxFrames[action] = max; } /** * Sets a given action to be rendered * * @param {number} index */ - setAction(index) { - this._maxFrame = (this._maxFrames[index] || 0); - this._index = index; - this._frame = 0; + setAction(index) { + this._maxFrame = (this._maxFrames[index] || 0); + this._index = index; + this._frame = 0; + } + /** + * @param {CanvasRenderingContext2D} ctx + * @param {number} dt + */ + render(ctx, dt) { + drawImage( + ctx, + this.img, + -this.width / 2, + -this.width / 2, + this.frameWidth, + this.frameHeight, + this._frame, + this._index, + this.width, + this.height + ); + this._accumulator += dt; + if (this._accumulator < this.frameRate) return + this._accumulator = 0; + this._frame += 1; + if (this._frame >= this._maxFrame) + this._frame = 0; + } +} + +/** + * Material for rendering text. + */ +class TextMaterial extends Material { + /** + * @type {String} + */ + text = "" + /** + * @type {boolean} + */ + center = false + /** + * @type {String} + */ + color = "white" + /** + * @type {boolean} + */ + fill = true + /** + * @type {String} + */ + font = "16px sans-serif" + /** + * @param {String} text + */ + constructor(text) { + super(); + this.text = text; } /** + * @inheritdoc * @param {CanvasRenderingContext2D} ctx - * @param {number} dt */ - render(ctx, dt) { - drawImage( - ctx, - this.img, - -this.frameWidth / 2, - -this.frameHeight / 2, - this.frameWidth, - this.frameHeight, - this._frame, - this._index - ); - this._accumulator += dt; - if (this._accumulator < this.frameRate) return - this._accumulator = 0; - this._frame += 1; - if (this._frame >= this._maxFrame) - this._frame = 0; + render(ctx) { + /**@type {TextMetrics}*/ + const metrics = ctx.measureText(this.text); + const x = this.center ? -metrics.width / 2 : 0; + const y = 0; + ctx.strokeRect = this.color; + ctx.fillStyle = this.color; + ctx.font = this.font; + if (this.fill) + ctx.fillText(this.text, x, y); + else + ctx.strokeText(this.text, x, y); } } @@ -7148,7 +7710,7 @@ class BodySprite extends Sprite { * @type {boolean} */ drawBounds = false - /** + /** * Determine whether to draw the position of the body. * * @type {boolean} @@ -7168,7 +7730,7 @@ class BodySprite extends Sprite { * @inheritdoc * @param {CanvasRenderingContext2D} ctx * @param {number} dt - */ + */ render(ctx, dt) { if (this.body.physicsType == ObjType.COMPOSITE) { @@ -7186,6 +7748,11 @@ class BodySprite extends Sprite { if (this.drawPosition) this._drawCenter(this.body, ctx); } + /** + * @private + * @param {Body} body + * @param {CanvasRenderingContext2D} renderer + */ _drawCenter(body, ctx) { ctx.beginPath(); circle( @@ -7295,6 +7862,9 @@ class BufferGeometry { init(ctx) { this.updateVertices(this.vertices); } + /** + * @param {Vector2[]} data + */ updateVertices(data){ const path = this.drawable = new Path2D(); vertices(path, data, true); @@ -7323,6 +7893,37 @@ class CircleGeometry { } } +class BoxGeometry extends BufferGeometry{ + constructor(width,height){ + let v1 = new Vector2$1(-width / 2, -height / 2); + let v2 = new Vector2$1(-width / 2, height / 2); + let v3 = new Vector2$1(width / 2, height / 2); + let v4 = new Vector2$1(width / 2, -height / 2); + super([v1, v2, v3, v4]); + } +} + +class TriangleGeometry extends BufferGeometry{ + constructor(base, height, angle) { + let l1 = new Vector2$1(1).multiply(base); + let l2 = Vector2$1.fromRad(angle).multiply(height/Math.sin(angle)); + let center = tmp1.set((l1.x + l2.x) / 3, l2.y / 3); + super([ + new Vector2$1().sub(center), + l1.sub(center), + l2.sub(center) + ]); + } +} + +class LineGeometry extends BufferGeometry { + constructor(length) { + let start = new Vector2$1(1).multiply(length / 2), + end = new Vector2$1(1).multiply(-length / 2); + super([start, end]); + } +} + let geometry = new BufferGeometry([ new Vector2$1(-10, -10), new Vector2$1(-10, 10), @@ -7621,21 +8222,30 @@ class Group extends Sprite { class CamController { /** - * @readonly - * @type Vector2 + * @type {Vector2} */ offset = new Vector2$1() + /** + * @type {Transform} + */ + transform = null + /** + * @type {Vector2 | null} + */ + targetPosition = null + /** + * @type {Angle | null} + */ + targetOrientation = null /** * @param {Camera} camera */ + constructor(camera) { this.transform = camera.transform; - this.offset = new Vector2$1(); - this.targetPosition = null; - this.targetOrientation = null; } /** - * @param { Vector2} position + * @param {Vector2} position * @param {Angle} orientation */ follow(position, orientation = null) { @@ -8016,9 +8626,10 @@ class Sfx { * @type {AudioBufferSourceNode} */ _source = null + //Todo - Check to see if this one works /** * @private - * @type {function} + * @type {Function} */ _onended = null /** @@ -8070,6 +8681,8 @@ class Sfx { } /** * Set callback when the sound finishes playing. + * + * @type {Function} */ set onended(x) { this._onended = x; @@ -8579,7 +9192,7 @@ class Behaviour { draw(renderer) {} } -let tmp1$4 = new Vector2$1(); +let tmp1$5 = new Vector2$1(); /** * Creates a behaviour to evade a certain position. * @@ -8615,7 +9228,7 @@ class EvadeBehaviour extends Behaviour { * @returns Vector2 the first parameter */ calc(target,inv_dt) { - let difference = tmp1$4.copy(this.position).sub(this.pursuer); + let difference = tmp1$5.copy(this.position).sub(this.pursuer); let length = difference.magnitude(); if(length == 0 || length > this.radius)return difference.setMagnitude(map(length,0,this.radius,this.maxSpeed,0)); @@ -8626,7 +9239,7 @@ class EvadeBehaviour extends Behaviour { } } -let tmp1$3 = new Vector2$1(), +let tmp1$4 = new Vector2$1(), tmp2$2 = new Vector2$1(); /** @@ -8671,7 +9284,7 @@ class WanderBehaviour extends Behaviour { calc(target, inv_dt) { this._theta += rand(-this.dtheta, +this.dtheta); - let forward = tmp1$3.copy(this.velocity); + let forward = tmp1$4.copy(this.velocity); if (forward.equalsZero()) Vector2$1.random(forward); let radius = this._radius * 0.8; @@ -8747,7 +9360,7 @@ class Flock extends Behaviour{ } } -let tmp1$2 = new Vector2$1(); +let tmp1$3 = new Vector2$1(); /** * Creates a behaviour to seek out a target and move towards it. @@ -8788,7 +9401,7 @@ class SeekBehaviour extends Behaviour { * @returns Vector2 the first parameter */ calc(target,inv_dt) { - let difference = tmp1$2.copy(this.target).sub(this.position); + let difference = tmp1$3.copy(this.target).sub(this.position); difference.setMagnitude(this.maxSpeed); let steering = difference.sub(this.velocity).multiply(inv_dt); @@ -8797,7 +9410,7 @@ class SeekBehaviour extends Behaviour { } } -let tmp1$1 = new Vector2$1(), +let tmp1$2 = new Vector2$1(), tmp2$1 = new Vector2$1(); /** @@ -8835,7 +9448,7 @@ class ArriveBehaviour extends Behaviour { * @returns Vector2 the first parameter */ calc(target, inv_dt) { - let difference = tmp1$1.copy(this.target).sub(this.position); + let difference = tmp1$2.copy(this.target).sub(this.position); let velocity = tmp2$1.copy(this.velocity); let length = difference.magnitude(); @@ -8853,7 +9466,7 @@ class ArriveBehaviour extends Behaviour { } } -const tmp1 = new Vector2$1(); +const tmp1$1 = new Vector2$1(); const tmp2 = new Vector2$1(); /** * Creates a behaviour that follows a certain path. @@ -8882,18 +9495,18 @@ class PathFollowing extends Behaviour { * @returns Vector2 the first parameter */ calc(target, inv_dt) { - tmp1.copy(this.position); + tmp1$1.copy(this.position); let [p1, p2] = this.path.current(); tmp2.copy(p2).sub(p1).normalize(); - let proj = tmp2.dot(tmp1.sub(p1)); + let proj = tmp2.dot(tmp1$1.sub(p1)); let projPoint = this.path.update(proj); - tmp1.copy(projPoint).sub(this.position); - let length = tmp1.magnitude(); + tmp1$1.copy(projPoint).sub(this.position); + let length = tmp1$1.magnitude(); if (length < this.velocity.magnitude()) { - tmp1.setMagnitude(map(length, 0, this.maxSpeed, 0, this.maxSpeed)); + tmp1$1.setMagnitude(map(length, 0, this.maxSpeed, 0, this.maxSpeed)); } - let steering = tmp1.sub(this.velocity).multiply(inv_dt); + let steering = tmp1$1.sub(this.velocity).multiply(inv_dt); steering.clamp(0, this.maxForce); target.add(steering); @@ -9021,7 +9634,7 @@ class Path { return this } /** - * private + * @private */ advance() { if (this._points.length < 2) return false @@ -9061,15 +9674,24 @@ class Path { ); return this._lerpedPoint } + /** + * @returns {Vector2[]} + */ current() { return [ this._points[this._way[0]], this._points[this._way[1]] ] } + /** + * @returns {Vector2} + */ point() { return this._lerpedPoint } + /** + * @type {Vector2[]} + */ get path() { return this._points } @@ -9389,16 +10011,37 @@ const Storage = { } }; +/** + * @template T + */ class IndexedList { + /** + * @private + * @type {Map} + */ _keys = new Map() + /** + * @private + * @type {T[]} + */ _list = [] - get(name){ + /** + * @param {string} name + */ + get(name) { return this._list[this._keys.get(name)] } - push(name, value) { - this._keys.set(name,this._list.length); + /** + * @param {string} name + * @param {T} value + */ + set(name, value) { + this._keys.set(name, this._list.length); this._list.push(value); } + /** + * @param {string} name + */ remove(name) { this._list.splice( this._keys.get(name), @@ -9406,6 +10049,15 @@ class IndexedList { ); this._keys.delete(name); } + /** + * @returns {string[]} + */ + keys() { + return this._keys.keys() + } + /** + * @returns {T[]} + */ values() { return this._list } @@ -9459,7 +10111,9 @@ function createManager(options) { } //import {System} from "../ecs/index.js" - +/** + * @param {Manager} manager + */ function fpsDebugger(manager) { const container = document.body.appendChild(document.createElement("div")); @@ -9523,75 +10177,218 @@ function bodyDebugger(manager) { }); } +/** + * @param {Manager} manager + */ +function raycastDebugger(manager) { + manager.registerSystem("raycastDebugger", { + renderer: null, + raycaster: null, + init(manager) { + const that = this; + this.renderer = manager.getSystem("renderer"); + this.raycaster = manager.getSystem("raycaster"); + setupDebugger(this); + manager.events.add("clear", e => { + setupDebugger(that); + }); + }, + update(dt) {} + }); +} + +function setupDebugger(debug) { + debug.renderer.add({ + render(ctx) { + debug.raycaster.objects.forEach(e => { + ctx.save(); + ctx.beginPath(); + ctx.translate(...e._transform.position); + e.rays.forEach(r => { + ctx.moveTo(0, 0); + ctx.lineTo( + r.direction.x * r.maxLength, + r.direction.y * r.maxLength + ); + ctx.lineWidth = 2; + }); + ctx.strokeStyle = "rgba(255,255,255,0.5)"; + ctx.stroke(); + ctx.closePath(); + ctx.restore(); + e.collisionResults.forEach(r => { + r.collisions.forEach(c => { + c.points.forEach(p => { + ctx.beginPath(); + ctx.arc(...p.point, 3, 0, Math.PI * 2); + ctx.strokeStyle = "white"; + ctx.stroke(); + ctx.closePath(); + }); + }); + }); + }); + } + }); +} + class Ray { + /** + * @type {number} + */ maxLength = 1000; - constructor(origin = new Vector2$1(), direction = new Vector2$1()) { + /** + * @private + * @type {Vector2} + */ + _origin = null; + /** + * @private + * @type {Vector2} + */ + _direction = null; + /** + * @param {Vector2} origin + * @param {Vector2} direction + */ + constructor(origin = new Vector2$1(0, 1), direction = new Vector2$1()) { this._origin = origin; this._direction = direction; } + /** + * @type {Vector2} + */ get direction() { return this._direction } set direction(x) { this._direction.copy(x); } + /** + * @type {Vector2} + */ get origin() { return this._origin } set origin(x) { this._origin.copy(x); } + /** + * @param {number} x + * @param {number} y + */ setOrigin(x, y) { this._origin.set(x, y); } + /** + * @param {number} x + * @param {number} y + */ setDirection(x, y) { this._direction.set(x, y); } + /** + * @param {number} x + * @param {number} y + */ + lookAt(x, y) { + this._direction.set( + x - this._origin.x, + y - this._origin.y + ); + this._direction.normalize(); + } } -class RaycastResult{ - ray = null +class RaycastResult { + //TODO - Make this property work + /** + * @type {RayCastModes} + */ mode = RayCastModes.NONE + /** + * @type {RayCollisionResult[]} + */ collisions = [] } -class RayCollisionResult{ - distance = 0 +class RayCollisionResult { + /** + * @type {Body} + */ object = null - points = [ ] + /** + * @readonly + * @type {RayPoint[]} + */ + points = [] + /** + * @type {Ray} + */ ray = null + /** + * @param {Ray} ray + * @param {Body} object + */ + constructor(ray, object) { + this.ray = ray; + this.object = object; + } +} +class RayPoint { + /** + * @type {Vector2} + */ + point = null + /** + * @type {number} + */ + distance = 0 + /** + * @param {Vector2} point + * @param {number} distance + */ + constructor(point, distance) { + this.point = point; + this.distance = distance; + } } - /** + * @readonly * @enum {number} - * -*/ + */ const RayCastModes = { - NONE : 0, - NEAREST:1, - FIRST:2, - ANY:3 + NONE: 0, + NEAREST: 1, + FIRST: 2, + ANY: 3 }; class RaycastManager extends System { + /** + * @private + * @type {Raycaster[]} + */ objects = [] + /** + * @private + * @type {Body[]} + */ bodies = null + /** + * @inheritdoc + * @param {Manager} manager + */ init(manager) { if (!manager.getSystem("world")) throw "World is required for running Raycast system." - - let renderer = manager.getSystem("renderer"); - manager.setComponentList("raycaster",this.objects); + manager.setComponentList("raycaster", this.objects); this.bodies = manager.getComponentList("body"); - renderer.add({ - context:this, - render(ctx) { - this.context.objects.forEach(e=>{ - e.draw(ctx); - }); - } - }); + } - update(){ + /** + * @inheritdoc + */ + update(dt) { for (let i = 0; i < this.objects.length; i++) { this.objects[i].update(this.bodies); } @@ -9599,17 +10396,43 @@ class RaycastManager extends System { } class Raycaster extends Component { + /** + * @type {Ray[]} + */ rays = [] - initialDir = [] + /** + * @type {Ray[]} + */ + collisionResults = [] + /** + * @private + * @type {Ray[]} + */ _number = 0 + /** + * @private + * @type {Ray[]} + */ _angle = 0 + /** + * @private + * @type {Ray[]} + */ _transform = null + /** + * @private + * @type {number} + */ _lastangle = 0 + mode = RayCastModes.ANY constructor(number = 1, angleSpace = 0) { super(); this._angle = angleSpace; this._number = number; } + /** + * @inheritdoc + */ init(entity) { this.requires(entity, "transform"); this._transform = entity.get("transform"); @@ -9617,56 +10440,184 @@ class Raycaster extends Component { const halfview = this._number * this._angle / 2; for (let a = -halfview; a <= halfview; a += this._angle) { this.rays.push(new Ray(new Vector2$1(), Vector2$1.fromRad(a))); - this.initialDir.push(Vector2$1.fromRad(a)); if (this._angle == 0) break } } + /** + * @param {Body[]} bodies + */ update(bodies) { + this.collisionResults = []; const angle = this._transform.orientation.value; const rotangle = angle - this._lastangle; - for (var i = 0; i < this.rays.length; i++) { const ray = this.rays[i]; ray.origin.copy(this._transform.position); ray.direction.rotate(rotangle); } this._lastangle = angle; + for (let i = 0; i < bodies.length; i++) { + const shapes = bodies[i].shapes; + + for (let j = 0; j < shapes.length; j++) { + const shape = shapes[j]; + if (shape.type === Shape.POLYGON) + this.testVertices(shape.vertices, bodies[i]); + if (shape.type === Shape.CIRCLE) + this.testCircle(shape.position, shape.radius, bodies[i]); + } + } } /** - * @param {CanvasRenderingContext2D} ctx - */ - draw(ctx) { - ctx.translate(...this._transform.position); + * @private + */ + testCircle(position, radius, body) { + let results = new RaycastResult(); + for (let i = 0; i < this.rays.length; i++) { + const ray = this.rays[i]; - this.rays.forEach(r => { - ctx.moveTo(0, 0); - ctx.lineTo( - r.direction.x * r.maxLength, - r.direction.y * r.maxLength - ); - }); - ctx.lineWidth = 2; - ctx.strokeStyle = "rgba(255,255,255,0.5)"; - ctx.stroke(); + results.collisions.push(testraycircle(ray, position, radius, body)); + } + this.collisionResults.push(results); } - add() { - throw "noooo" + /** + * @private + */ + testVertices(vertices, body) { + let results = new RaycastResult(); + for (let i = 0; i < this.rays.length; i++) { + const ray = this.rays[i]; + + results.collisions.push(testray(ray, vertices, body)); + } + this.collisionResults.push(results); + } +} +/** + * @private + */ +function testray(ray, vertices, body) { + const origin = ray.origin; + const direction = ray.direction; + const results = new RayCollisionResult(ray, body); + + let res = testSingleEdge( + vertices[vertices.length - 1], + vertices[0], origin, direction + ); + if (res != void 0) + results.points.push( + new RayPoint( + res, + res.clone().sub(origin) + .magnitudeSquared() + ) + ); + for (let i = 0; i < vertices.length - 1; i++) { + let res = testSingleEdge( + vertices[i], vertices[i + 1], + origin, direction + ); + if (res != void 0) + results.points.push( + new RayPoint( + res, + res.clone().sub(origin) + .magnitudeSquared() + ) + ); } + return results +} + +/** + * @private + */ +function testSingleEdge(v1, v2, or, dir) { + const x1 = v1.x; + const y1 = v1.y; + const x2 = v2.x; + const y2 = v2.y; + const x3 = or.x; + const y3 = or.y; + const x4 = dir.x + x3; + const y4 = dir.y + y3; + + const den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); + + if (den === 0) return null + + const t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / den; + const u = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / den; + + if ( + t > 0 && t < 1 && + u > 0 + ) return new Vector2$1( + x1 + t * (x2 - x1), + y1 + t * (y2 - y1) + ) + return null +} + +/** + * @private + */ +function testraycircle(ray, center, radius, body) { + const results = new RayCollisionResult(ray, body); + + const x1 = ray.origin.x; + const y1 = ray.origin.y; + const x2 = ray.direction.x; + const y2 = ray.direction.y; + + const x3 = center.x; + const y3 = center.y; + const x4 = x3 - x1; + const y4 = y3 - y1; + const r = radius; + + const proj = x2 * x4 + y2 * y4; + const delta = proj * proj - ((x4 * x4 + y4 * y4) - r * r); + const sqrtDelta = Math.sqrt(delta); + const distance1 = proj + sqrtDelta; + const distance2 = proj - sqrtDelta; + + if (delta < 0 || distance1 < 0) return results + results.points.push(new RayPoint( + new Vector2$1( + x1 + distance1 * x2, + y1 + distance1 * y2 + ), distance1 * distance1 + )); + if (delta === 0 || (distance2 < 0)) return results + results.points.push(new RayPoint( + new Vector2$1( + x1 + distance2 * x2, + y1 + distance2 * y2 + ), + distance2 * distance2 + )); + return results } -export { Agent, AgentManager, AgentSprite, Angle, AngleUpdate, ArriveBehaviour, AudioHandler, Ball, BasicMaterial, Behaviour, Body, BodySprite, Bound$1 as Bound, BoundingBox, BoundingCircle, Box, BufferGeometry, CamController, Camera, Circle, CircleGeometry, Clock, ColorUpdate, Component, Composite, Constraint, Cookies, DEVICE, DOMEventHandler, DistanceConstraint, Easing, Entity, error$1 as Err, EulerSolver, EvadeBehaviour, EventDispatcher, Events, Flock, Geometry, Group, IndexedList, Input, Intergrator, Interpolation, Keyboard, Line, Loader, Manager, Material, Matrix2 as Matrix, Matrix2, Mouse, Movable$1 as Movable, NaiveBroadphase, NarrowPhase, Overlaps, Particle, ParticleSystemSprite, Path, PathFollowing, Perf, Pursuit, QuadTreeBroadphase, Ray, RayCastModes, RayCollisionResult, RaycastManager, RaycastResult, Raycaster, Rectangle, Renderer, Renderer2D, SATNarrowPhase, SeekBehaviour, Session, Sfx, Shape, Signal, SpringConstraint, Sprite, SpriteMaterial, StaticImageMaterial, Storage, System, Touch, Transform$1 as Transform, Triangle, Trigon, Tween, TweenManager, common as Utils, Vec2, Vector, Vector2$1 as Vector2, Vector2Update, Vector3Update, WanderBehaviour, WebGLRenderer, WebGPURenderer, World, arc, bodyDebugger, circle, clamp, createEntity, createManager, defaultCollisionHandler, defaultPrecollisionHandler, degToRad, drawImage, exp, fill, fillText, fpsDebugger, lerp, line, map, mixin, naturalizePair, radToDeg, rand, rect, round, sq, sqrt, stroke, vertices, wrapAngle }; +export { Agent, AgentManager, AgentSprite, Angle, AngleUpdate, ArriveBehaviour, AudioHandler, Ball, BasicMaterial, Behaviour, Body, BodySprite, Bound$1 as Bound, BoundingBox, BoundingCircle, Box, BoxGeometry, BufferGeometry, CamController, Camera, Circle, CircleGeometry, Clock, Color, ColorUpdate, Component, Composite, Constraint, Cookies, DEG2RAD, DEVICE, DOMEventHandler, DistanceConstraint, Easing, Entity, error$1 as Err, EulerSolver, EvadeBehaviour, EventDispatcher, Events, Flock, Geometry, Group, HALF_PI, IndexedList, Input, Intergrator, Interpolation, Keyboard, Line, LineGeometry, Loader, Manager, Material, Matrix2 as Matrix, Matrix2, Mouse, Movable$1 as Movable, NaiveBroadphase, NarrowPhase, Overlaps, PI, Particle, ParticleSystemSprite, Path, PathFollowing, Perf, Pursuit, QuadTreeBroadphase, RAD2DEG, Ray, RayCastModes, RayCollisionResult, RayPoint, RaycastManager, RaycastResult, Raycaster, Rectangle, Renderer, Renderer2D, SATNarrowPhase, SQRT2, SeekBehaviour, Session, Sfx, Shape, Signal, SpringConstraint, Sprite, SpriteMaterial, StaticImageMaterial, Storage, System, TWO_PI, TextMaterial, Touch, Transform$1 as Transform, Triangle, TriangleGeometry, Trigon, Tween, TweenManager, common as Utils, Vec2, Vector, Vector2$1 as Vector2, Vector2Update, Vector3Update, WanderBehaviour, WebGLRenderer, WebGPURenderer, World, arc, bodyDebugger, circle, clamp, createEntity, createManager, defaultCollisionHandler, defaultPrecollisionHandler, degToRad, drawImage, epilson, exp, fill, fillText, fpsDebugger, lerp, line, map, mixin, naturalizePair, radToDeg, rand, raycastDebugger, rect, round, sq, sqrt, stroke, vertices, wrapAngle }; /** * @typedef Bounds * @property {Vector_like} max * @property {Vector_like} min *//** + * @callback EasingFunc + * @param {number} t + * @returns {number} + *//** * @typedef CollisionPair * @property {Body} a * @property {Body} b */ /** - * @typedef Manifold + * @typedef transform = null * @property {Body} bodyA * @property {Body} bodyB * @property {ContactManifold} contactData diff --git a/dist/chaos.umd.js b/dist/chaos.umd.js index 2b51a051..03d5fdd4 100644 --- a/dist/chaos.umd.js +++ b/dist/chaos.umd.js @@ -1,7 +1,7 @@ /* * @author Wayne Mwashuma * {@link https://github.com/waynemwashuma/chaos-engine.git} - * @copyright 2023-2023 Wayne Mwashuma + * @copyright 2023-2024 Wayne Mwashuma * @license MIT * * @@ -226,7 +226,7 @@ SOFTWARE. proto.get = function(n) { return this.entity.getComponent(n); }; - proto.requires = function(entity,...names) { + proto.requires = function(entity, ...names) { for (var i = 0; i < names.length; i++) if (!entity.has(names[i])) throws(`The component \`${this.CHOAS_CLASSNAME}\` requires another component \`${names[i]}\` but cannot find it in the Entity with id ${entity.id}`); @@ -257,23 +257,17 @@ SOFTWARE. }); } /** - * Mixes the functions required by an object into another object. + * Todo - Fix this function to add all props if no props param is given + * Mixes the properties and methods required by an object from another object. * - * @param {Object} from the object constructor function to add methods from. - * @param {Object} to the object constructor function to add methods to. + * @param {*} from the object constructor function to add methods from. + * @param {*} to the object constructor function to add methods to. + * @param {string[]} [props] */ - function mixin(from, to,props = []) { - let proto = from.prototype; - let proto2 = to.prototype; - console.log(proto2); - Object.assign(proto,from); + function mixin(from, to, props = []) { for (let name of props) { - //if(!(methodName in proto))continue - //if (methodName in proto2) continue - - proto2[name] = proto[name]; + to[name] = from[name]; } - //console.log(new to()); } var common = /*#__PURE__*/Object.freeze({ @@ -342,16 +336,42 @@ SOFTWARE. //import { DEVICE } from "../device/index.js" class Loader { + /** + * @private + */ + _toload = [] + imgs = {} + sfx = {} + json = {} + /** + * @type {number} + * @private + */ + _progressBytes = 0 + /** + * @private + * @type {number} + */ + _totalBytes = 0 + /** + * @peivatw + * @type {number} + */ + _filesErr = 0 + /** + * @private + * @type {number} + */ + _filesLoaded = 0 + /** + * @private + * @type {number} + */ + _totalFileNo = 0 + /** + * @param {Manager} manager + */ constructor(manager) { - this._toload = []; - this.imgs = {}; - this.sfx = {}; - this.json = {}; - this._progressBytes = 0; - this._totalBytes = 0; - this._filesErr = 0; - this._filesLoaded = 0; - this._totalFileNo = 0; const that = this; this.onfinish = null; this._handlers = { @@ -398,6 +418,9 @@ SOFTWARE. } }; } + /** + * @private + */ _getName(url) { if (url.includes("/")) { let tmp = url.split("/"); @@ -405,6 +428,9 @@ SOFTWARE. } return url.split(".")[0] } + /** + * @private + */ _getType(url) { let ext; if (url.includes("/")) { @@ -495,7 +521,7 @@ SOFTWARE. * Adds an event handler to an event dispatcher. * * @param {string} name name of the event. - * @param {function} handler Function to be called when the event is triggered. + * @param {EventHandlerFunc} handler Function to be called when the event is triggered. */ add(name, handler) { if (name in this.handlers) { @@ -504,7 +530,14 @@ SOFTWARE. } this.handlers[name] = [handler]; } - } + } + + /** + * @callback EventHandlerFunc + * @param {any} data + * + * @returns {void} + */ /** * This handles events created by the DOM. @@ -642,40 +675,69 @@ SOFTWARE. PLAY : "play" }; + /** + * @template T + */ class Signal { _listeners = [] + /** + * @type {T} + */ _value = null - constructor(value){ + /** + * @param {T} value + */ + constructor(value) { this._value = value; } + /** + * @type {T} + */ + get value() { + return this._value + } set value(x) { this._value = x; for (var i = 0; i < this._listeners.length; i++) { let func = this._listeners[i]; func.listener(this); - if(func.callOnce) - this.removeListener(func.listener); + if (func.callOnce) + this.removeListener(func.listener); } } - get value() { - return this._value - } - addListener(listener,callOnce=false) { + /** + * @param {signalListener} listener + * @param {boolean} callOnce + */ + addListener(listener, callOnce = false) { this._listeners.push({ listener, callOnce }); } + /** + * @param {signalListener} listener + */ removeListener(listener) { for (var i = 0; i < this._listeners.length; i++) { if (this._listeners[i].listener == listener) return this._detach(i) } } - _detach(bindingIndex){ + /** + * @private + * @param {number} bindingIndex + */ + _detach(bindingIndex) { this._listeners.splice(i, 1); } - } + } + + /** + * @callback signalListener + * @param {Signal} value + * @returns {void} + */ /** * This class is responsible for managing all @@ -920,6 +982,7 @@ SOFTWARE. for (let i = this.objects.length - 1; i >= 0; i--) { this.remove(this.objects[i]); } + this.events.trigger("clear"); } /** * This method requests an animation frame from the browser @@ -1189,7 +1252,7 @@ SOFTWARE. } /** * @param {Entity} entity - */ + */ init(entity) {} /** * @param {number} dt @@ -1198,32 +1261,49 @@ SOFTWARE. warnOnce("Please override the update function in the component " + proto.constructor.name); } /** + * @param {Entity} entity * @param {string} n */ - get(entity,n) { + get(entity, n) { return entity.getComponent(n); } /** + * @param {Entity} entity * @param {...string} names + * @rheows */ - requires(entity,...names) { + requires(entity, ...names) { for (var i = 0; i < names.length; i++) if (!entity.has(names[i])) throws(`The component \`${this.CHOAS_CLASSNAME}\` requires another component \`${names[i]}\` but cannot find it in the Entity with id ${entity.id}`); } /** + * @param {Entity} entity * @param {CircleBounding | BoxBounding} bound - * @param {Entity} [target=[]] + * @param {Entity[]} [target=[]] + * @returns {Entity[]} */ - query(entity,bound, target = []) { + query(entity, bound, target = []) { return entity.query(bound, target) } - static fromJson() { + /** + * @template {System} T + * @param {*} obj + * @param {T} system + */ + fromJson(obj, system) { throw "Implement static method fromJson() in your component " + this.CHOAS_CLASSNAME + } - static toJson() { + /** + * @returns {*} + */ + toJson() { throw "Implement static method toJson() in your component " + this.CHOAS_CLASSNAME } + /** + * @param {*} component + */ static implement(component) { inheritComponent(component); } @@ -1231,53 +1311,41 @@ SOFTWARE. /** * Updates components assigned to it. - * - * @interface */ class System { - init() { + /** + * @param {Manager} manager + */ + init(manager) { warnOnce("Please override the init method in the system " + this.constructor.name); } - update() { + /** + * @param {number} dt + */ + update(dt) { warnOnce("Please override the update method in the system " + this.constructor.name); - } + /** + * @param {Component} component + */ add(component) { this.objects.push(component); } + /** + * @param {Component} component + */ remove(component) { let index = this.objects.indexOf(component); removeElement(this.objects, index); } + //Todo - Fix this + /** + * @param {any} system + */ static implement(system) { - mixin(System,system); + mixin(System, system); } - } - - /** - * - * @function - * @name System#add - * @param {Component} component - */ - /** - * - * @function - * @name System#remove - * @param {Component} component - */ - /** - * - * @function - * @name System#init - * @param {Manager} manager - */ - /** - * - * @function - * @name System#update - * @param {number} dt - */ + } /** * This is a container to hold components,tags and event handlers. @@ -1320,10 +1388,15 @@ SOFTWARE. * @type {boolean} */ active = false - + /** + * @type {string} + */ get CHAOS_OBJ_TYPE() { return "entity" } + /** + * @type {string} + */ get CHAOS_CLASSNAME() { return this.constructor.name.toLowerCase() } @@ -1530,12 +1603,6 @@ SOFTWARE. } return entity } - /** - * @returns {{ - deg: number, - type:string - }} - */ toJson() { let obj = { comps: {}, @@ -1553,11 +1620,20 @@ SOFTWARE. } class TweenManager extends System { + /** + * @type {Tween[]} + */ objects = [] + /** + * @inheritdoc + * @param {Manager} manager + */ init(manager) { manager.setComponentList("tween", this.objects); } - + /** + * @inheritdoc + */ update(dt) { for (var i = 0; i < this.objects.length; i++) { let tween = this.objects[i]; @@ -1567,9 +1643,14 @@ SOFTWARE. } } - const RHI = Math.PI / 180, - RHI_INV = 1 / RHI; - + const PI = Math.PI; + const TWO_PI = Math.PI * 2; + const HALF_PI = Math.PI / 2; + const DEG2RAD = Math.PI / 180; + const epilson = Math.pow(2, -53); + const RAD2DEG = 180 / Math.PI; + const SQRT2 = Math.sqrt(2); + /** * Creates a random number between the parameters * @@ -1586,7 +1667,7 @@ SOFTWARE. * * @param {number} x The number to square * @returns {number} - */ + */ function sq(x) { return x * x } @@ -1596,7 +1677,7 @@ SOFTWARE. * @param {number} x the number to power. * @param {number} [e=2] The number to power by. * @returns {number} - */ + */ function exp(x, e = 2) { return x ** e } @@ -1605,7 +1686,7 @@ SOFTWARE. * * @param {number} x The number to root * @returns {number} - */ + */ function sqrt(x) { return Math.sqrt(x) } @@ -1618,7 +1699,7 @@ SOFTWARE. * @param {number} b The maximum bound of the interpolation. * @param {number} t A number between 0 and 1 to interpopate by.Any other number greater than 1 or less than 0 will extapolate beyond b or a respectively. * @returns {number} - */ + */ function lerp(a, b, t) { return a + t * (b - a) } @@ -1629,7 +1710,7 @@ SOFTWARE. * @param {number} number The number to round. * @param {number} [precision=4] How many decimal places there should be. * @returns {number} - */ + */ function round(number, precision = 4) { precision = 10 ** precision; return Math.round(number * precision) / precision @@ -1642,7 +1723,7 @@ SOFTWARE. * @param {number} min The minimal bound of the clamped number. * @param {number} max The maximum bound of the clamped number. * @returns {number} - */ + */ function clamp(value, min, max) { if (value < min) return min if (value > max) return max @@ -1658,7 +1739,7 @@ SOFTWARE. * @param {number} x2 * @param {number} y2 * @returns {number} - */ + */ function map(v, x1, y1, x2, y2) { return x2 + v * (y2 - x2) / (y1 - x1) } @@ -1667,7 +1748,7 @@ SOFTWARE. * @param {number} a * @param {number} b * @returns {number} - */ + */ function naturalizePair(a, b) { if (a > b) return (a + b) * (a + b + 1) / 2 + a; @@ -1679,9 +1760,9 @@ SOFTWARE. * * @param {number} deg number to convert. * @returns {number} - */ + */ function degToRad(deg) { - return deg * RHI + return deg * DEG2RAD } /** @@ -1689,16 +1770,28 @@ SOFTWARE. * * @param {number} rad number to convert. * @returns {number} - */ + */ function radToDeg(rad) { - return rad * RHI_INV + return rad * RAD2DEG + } + /** + * @param {number} x + */ + function wrapAngle(x) { + let a = x; + while (a > Math.PI * 2) { + a = a - Math.PI * 2; + } + while (a < 0) { + a = a + Math.PI * 2; + } + return a } - let obj$1 = { + const obj$1 = { x: 0, y: 0 }; - let TWO_PI = Math.PI * 2; /** * This is a 2D vector class. * @@ -1755,7 +1848,7 @@ SOFTWARE. distanceTo(v) { obj$1.x = this.x - v.x; obj$1.y = this.y - v.y; - return Math.sqrt( Vector2$1.prototype.magnitudeSquared.call(obj$1)) + return Math.sqrt(Vector2$1.prototype.magnitudeSquared.call(obj$1)) } /** *Calculates length squared of this vector to another vector @@ -2027,7 +2120,7 @@ SOFTWARE. return this.multiply(min / length) return this } - + toJson() { return this } @@ -2166,15 +2259,24 @@ SOFTWARE. static ZERO = Object.freeze(new Vector2$1()) } - class Vector extends Vector2$1{ - constructor(x,y){ - super(x,y); + class Vector extends Vector2$1 { + /** + * @param {number} x the x coordinate of the vector + * @param {number} y the y coordinate of the vector + */ + constructor(x, y) { + super(x, y); console.error("The class `Vector` is depreciated since v0.4.13.Use Vector2 instead."); } } - class Vec2 extends Vector2$1{ - constructor(x,y){ - super(x,y); + + class Vec2 extends Vector2$1 { + /** + * @param {number} x the x coordinate of the vector + * @param {number} y the y coordinate of the vector + */ + constructor(x, y) { + super(x, y); console.error("The class `Vec2` is depreciated since v0.4.13.Use Vector2 instead."); } } @@ -2212,7 +2314,7 @@ SOFTWARE. //TODO - Change this to radians instead constructor(deg = 0) { - this.value = deg * Math.PI/2; + this.value = deg * Math.PI/180; } /** * @type string @@ -2528,84 +2630,130 @@ SOFTWARE. } } - function wrapAngle(x) { - let a = x; - while (a > Math.PI * 2) { - a = a - Math.PI * 2; - } - while (a < 0) { - a = a + Math.PI * 2; - } - return a - } - const Easing = { + /** + * @type {EasingFunc} + */ linear: function(x) { return x; }, + /** + * @type {EasingFunc} + */ quadraticIn: function(x) { return x * x; }, + /** + * @type {EasingFunc} + */ quadraticOut: function(x) { return x * (2 - x); }, + /** + * @type {EasingFunc} + */ quadraticInOut: function(x) { if ((x *= 2) < 1) { return 0.5 * x * x; } return -0.5 * (--x * (x - 2) - 1); }, + /** + * @type {EasingFunc} + */ cubicIn: function(x) { return x * x * x; }, + /** + * @type {EasingFunc} + */ cubicOut: function(x) { return --x * x * x + 1; }, + /** + * @type {EasingFunc} + */ cubicInOut: function(x) { if ((x *= 2) < 1) { return 0.5 * x * x * x; } return 0.5 * ((x -= 2) * x * x + 2); }, + /** + * @type {EasingFunc} + */ quarticIn: function(x) { return x * x * x * x; }, + /** + * @type {EasingFunc} + */ quarticOut: function(x) { return 1 - --x * x * x * x; }, + /** + * @type {EasingFunc} + */ quarticInOut: function(x) { if ((x *= 2) < 1) { return 0.5 * x * x * x * x; } return -0.5 * ((x -= 2) * x * x * x - 2); }, + /** + * @type {EasingFunc} + */ quinticIn: function(x) { return x * x * x * x * x; }, + /** + * @type {EasingFunc} + */ quinticOut: function(x) { return --x * x * x * x * x + 1; }, + /** + * @type {EasingFunc} + */ quinticInOut: function(x) { if ((x *= 2) < 1) { return 0.5 * x * x * x * x * x; } return 0.5 * ((x -= 2) * x * x * x * x + 2); }, + /** + * @type {EasingFunc} + */ sinusoidalIn: function(x) { return 1 - Math.sin(((1.0 - x) * Math.PI) / 2); }, + /** + * @type {EasingFunc} + */ sinusoidalOut: function(x) { return Math.sin((x * Math.PI) / 2); }, + /** + * @type {EasingFunc} + */ sinusoidalInOut: function(x) { return 0.5 * (1 - Math.sin(Math.PI * (0.5 - x))); }, + /** + * @type {EasingFunc} + */ exponentialIn: function(x) { return x === 0 ? 0 : Math.pow(1024, x - 1); }, + /** + * @type {EasingFunc} + */ exponentialOut: function(x) { return x === 1 ? 1 : 1 - Math.pow(2, -10 * x); }, + /** + * @type {EasingFunc} + */ exponentialInOut: function(x) { if (x === 0) { return 0; @@ -2618,18 +2766,30 @@ SOFTWARE. } return 0.5 * (-Math.pow(2, -10 * (x - 1)) + 2); }, + /** + * @type {EasingFunc} + */ circularIn: function(x) { return 1 - Math.sqrt(1 - x * x); }, + /** + * @type {EasingFunc} + */ circularOut: function(x) { return Math.sqrt(1 - --x * x); }, + /** + * @type {EasingFunc} + */ circularInOut: function(x) { if ((x *= 2) < 1) { return -0.5 * (Math.sqrt(1 - x * x) - 1); } return 0.5 * (Math.sqrt(1 - (x -= 2) * x) + 1); }, + /** + * @type {EasingFunc} + */ elasticIn: function(x) { if (x === 0) { return 0; @@ -2639,6 +2799,9 @@ SOFTWARE. } return -Math.pow(2, 10 * (x - 1)) * Math.sin((x - 1.1) * 5 * Math.PI); }, + /** + * @type {EasingFunc} + */ elasticOut: function(x) { if (x === 0) { return 0; @@ -2648,6 +2811,9 @@ SOFTWARE. } return Math.pow(2, -10 * x) * Math.sin((x - 0.1) * 5 * Math.PI) + 1; }, + /** + * @type {EasingFunc} + */ elasticInOut: function(x) { if (x === 0) { return 0; @@ -2661,14 +2827,23 @@ SOFTWARE. } return 0.5 * Math.pow(2, -10 * (x - 1)) * Math.sin((x - 1.1) * 5 * Math.PI) + 1; }, + /** + * @type {EasingFunc} + */ backIn: function(x) { var s = 1.70158; return x === 1 ? 1 : x * x * ((s + 1) * x - s); }, + /** + * @type {EasingFunc} + */ backOut: function(x) { var s = 1.70158; return x === 0 ? 0 : --x * x * ((s + 1) * x + s) + 1; }, + /** + * @type {EasingFunc} + */ backInOut: function(x) { var s = 1.70158 * 1.525; if ((x *= 2) < 1) { @@ -2676,10 +2851,16 @@ SOFTWARE. } return 0.5 * ((x -= 2) * x * ((s + 1) * x + s) + 2); }, + /** + * @type {EasingFunc} + */ bounceIn: function(x) { return 1 - Easing.bounceOut(1 - x); }, - bounceOut: function(x) { + /** + * @type {EasingFunc} + */ + bounceOut: function(x) { if (x < 1 / 2.75) { return 7.5625 * x * x; } @@ -2693,6 +2874,9 @@ SOFTWARE. return 7.5625 * (x -= 2.625 / 2.75) * x + 0.984375; } }, + /** + * @type {EasingFunc} + */ bounceInOut: function(x) { if (x < 0.5) { return Easing.bounceIn(x * 2) * 0.5; @@ -2702,9 +2886,17 @@ SOFTWARE. }; const Interpolation = { + /** + * @param {number} p0 + * @param {number} p1 + * @param {number} t + * + * @returns {number} + */ Linear: function(p0, p1, t) { return (p1 - p0) * t + p0 }, + //Todo - remove this Bernstein and Factorial. Bernstein: function(n, i) { const fc = Interpolation.Utils.Factorial; @@ -2728,7 +2920,15 @@ SOFTWARE. return s } })(), - + /** + * @param {number} p0 + * @param {number} p1 + * @param {number} p2 + * @param {number} p3 + * @param {number} t + * + * @returns {number} + */ CatmullRom: function(p0, p1, p2, p3, t) { const v0 = (p2 - p0) * 0.5; const v1 = (p3 - p1) * 0.5; @@ -2739,160 +2939,6 @@ SOFTWARE. }, }; - /** - * Component responsible for animations. - * - * @template {T} - */ - class Tween { - _duration = 0 - _repeat = false - active = false - /** - * @type {T} - */ - _to = null - _from = null - _into = null - _interpolationFunc = Interpolation.Linear - _easingFunction = Easing.linear - _timeTaken = 0 - _updateFunc = NoUpdateThrow - _next = null - /** - *@template {T} - *@param {T} to - *@param {T} from - *@param {number} duration - */ - constructor(into) { - this._into = into; - } - init(entity) { - this.play(); - } - /** - * @param {T} x - */ - to(x) { - this._to = x; - return this - } - /** - * @param {T} x - */ - from(x) { - this._from = x; - return this - } - /** - * @param {T} t - */ - duration(t) { - this._duration = t; - return this - } - repeat() { - this._repeat = true; - return this - } - play() { - this._timeTaken = 0; - this.active = true; - } - stop() { - this.active = false; - } - onUpdate(callback) { - this._updateFunc = callback; - return this - } - easing(func) { - this._easingFunction = func; - return this - } - interpolant(func) { - this._interpolationFunc = func; - return this - } - update(dt) { - if (!this.active) return - - this._timeTaken += dt; - if (this._timeTaken >= this._duration) { - if(this._next !== void 0){ - this.stop(); - this._next.play(); - } - if (this._repeat) { - this._timeTaken = 0; - } else { - this._timeTaken = this._duration; - this.active = false; - } - } - let t = this._easingFunction( - this._timeTaken / this._duration - ); - this._updateFunc( - this._interpolationFunc, - this._to, - this._from, - t, - this._into - ); - } - chain(next) { - this._next = next; - return this - } - } - - /** - * @type Tween - */ - new Tween(); - - /** - * @template {T} - * @callback TweenUpdate - * @param {Function} lerpFunc - * @param {T} to - * @param {T} from - * @param {number} t - * @param {T} into - * - * @returns {void} - */ - - /** - * @type {TweenUpdate} - */ - function Vector2Update(lerpFunc, to, from, t, into) { - into.x = lerpFunc(from.x, to.x, t); - into.y = lerpFunc(from.y, to.y, t); - } - function Vector3Update(lerpFunc, to, from, t, into) { - into.x = lerpFunc(from.x, to.x, t); - into.y = lerpFunc(from.y, to.y, t); - into.z = lerpFunc(from.z, to.z, t); - } - - function ColorUpdate(lerpFunc, to, from, t, into) { - into.r = lerpFunc(from.r, to.r, t); - into.g = lerpFunc(from.g, to.g, t); - into.b = lerpFunc(from.b, to.b, t); - into.a = lerpFunc(from.a, to.a, t); - } - - function AngleUpdate(lerpFunc, to, from, t, into) { - into.rad = lerpFunc(from.rad, to.rad, t); - } - - function NoUpdateThrow() { - throw "The Tween does not have a valid onUpdate callback." - } - /** * This module is used to check if bounds of a body overlap */ @@ -3173,35 +3219,397 @@ SOFTWARE. } } - this.pos.x = body.position.x; - this.pos.y = body.position.y; - this.r = Math.sqrt(radsq); + this.pos.x = body.position.x; + this.pos.y = body.position.y; + this.r = Math.sqrt(radsq); + } + /** + * Translates this bound to the given position. + * + * @param {Vector_like} pos + */ + update(pos) { + //let dx = pos.x - this.pos.x + //let dy = pos.y - this.pos.y + + this.pos.x = pos.x; + this.pos.y = pos.y; + } + toJson(){ + return { + posX:this.pos.x, + posY:this.pos.y, + r:this.r + } + } + fromJson(obj){ + this.pos.x = obj.posX; + this.pos.y = obj.posY; + this.r = obj.r; + } + } + + /** + * A color manipulation class. + */ + class Color { + + /** + * @param {number} [r=0] - red component [0 .. 255] + * @param {number} [g=0] - green component [0 .. 255] + * @param {number} [b=0] - blue component [0 .. 255] + * @param {number} [alpha=1.0] - alpha value [0.0 .. 1.0] + */ + constructor(r = 0, g = 0, b = 0, alpha = 1.0) { + this.set(r, g, b, alpha); + } + + /** + * Set this color to the specified value. + * @param {number} r - red component [0 .. 255] + * @param {number} g - green component [0 .. 255] + * @param {number} b - blue component [0 .. 255] + * @param {number} [alpha=1.0] - alpha value [0.0 .. 1.0] + * @returns {Color} Reference to this object for method chaining + */ + set(r, g, b, alpha = 1.0) { + this.r = r; + this.g = g; + this.b = b; + this.a = alpha; + return this; + } + + /** + * Create a new copy of this color object. + * @returns {Color} Reference to the newly cloned object + */ + clone() { + return new Color().copy(this); + } + + /** + * Copy a color object or CSS color into this one. + * @param {Color|string} color + * @returns {Color} Reference to this object for method chaining + */ + copy(color) { + this.set(color.r, color.g, color.b, color.a); + } + + /** + * Blend this color with the given one using addition. + * @param {Color} color + * @returns {Color} Reference to this object for method chaining + */ + add(color) { + this.r = clamp(this.r + color.r, 0, 255); + this.g = clamp(this.g + color.g, 0, 255); + this.b = clamp(this.b + color.b, 0, 255); + this.a = (this.a + color.a) / 2; + + return this; + } + + /** + * Darken this color value by 0..1 + * @param {number} scale + * @returns {Color} Reference to this object for method chaining + */ + darken(scale) { + scale = clamp(scale, 0, 1); + this.r *= scale; + this.g *= scale; + this.b *= scale; + + return this; + } + + /** + * Linearly interpolate between this color and the given one. + * @param {Color} color + * @param {number} alpha - with alpha = 0 being this color, and alpha = 1 being the given one. + * @returns {Color} Reference to this object for method chaining + */ + lerp(color, alpha) { + alpha = clamp(alpha, 0, 1); + this.r += (color.r - this.r) * alpha; + this.g += (color.g - this.g) * alpha; + this.b += (color.b - this.b) * alpha; + + return this; + } + + /** + * Lighten this color value by 0..1 + * @param {number} scale + * @returns {Color} Reference to this object for method chaining + */ + lighten(scale) { + scale = clamp(scale, 0, 1); + this.r = clamp(this.r + (1 - this.r) * scale, 0, 1); + this.g = clamp(this.g + (1 - this.g) * scale, 0, 1); + this.b = clamp(this.b + (1 - this.b) * scale, 0, 1); + + return this; + } + + /** + * Generate random r,g,b values for this color object + * @param {number} [min=0] - minimum value for the random range + * @param {number} [max=255] - maxmium value for the random range + * @returns {Color} Reference to this object for method chaining + */ + random(min = 0, max = 255) { + if (min < 0) { + min = 0; + } + if (max > 255) { + max = 255; + } + + return this.set( + rand(min, max), + rand(min, max), + rand(min, max), + this.a + ); + } + + + toArray(array, offset = 0) { + array[offset] = this.r; + array[offset + 1] = this.g; + array[offset + 2] = this.b; + array[offset + 3] = this.a; + + return array + } + } + + /** + * Component responsible for animations. + * + * @template T + */ + class Tween { + /** + * @type {number} + */ + _duration = 0 + /** + * @type {boolean} + */ + _repeat = false + /** + * @type {boolean} + */ + active = false + /** + * @type {T} + * @private + */ + _to = null + /** + * @type {T} + * @private + */ + _from = null + /** + * @type {T} + * @private + */ + _into = null + /** + * @type {LerpFunc} + * @private + */ + _interpolationFunc = Interpolation.Linear + /** + * @type {EasingFunc} + * @private + */ + _easingFunction = Easing.linear + /** + * @type {number} + * @private + */ + _timeTaken = 0 + /** + * @type {TweenUpdate} + * @private + */ + _updateFunc = NoUpdateThrow + /** + * @type {Tween} + * @private + */ + _next = null + /** + *@param {T} into + */ + constructor(into) { + this._into = into; + } + /** + * @param {Entity} entity + */ + init(entity) { + this.play(); + } + /** + * @param {T} x + */ + to(x) { + this._to = x; + return this + } + /** + * @param {T} x + */ + from(x) { + this._from = x; + return this + } + /** + * @param {T} t + */ + duration(t) { + this._duration = t; + return this + } + repeat() { + this._repeat = true; + return this + } + play() { + this._timeTaken = 0; + this.active = true; + } + stop() { + this.active = false; + } + /** + * @param {TweenUpdate} callback + */ + onUpdate(callback) { + this._updateFunc = callback; + return this + } + /** + * @param {EasingFunc} callback + */ + easing(func) { + this._easingFunction = func; + return this + } + /** + * @param {LerpFunc} callback + */ + interpolant(func) { + this._interpolationFunc = func; + return this + } + /** + * @param {number} dt + */ + update(dt) { + if (!this.active) return + + this._timeTaken += dt; + if (this._timeTaken >= this._duration) { + if (this._next !== void 0) { + this.stop(); + this._next.play(); + } + if (this._repeat) { + this._timeTaken = 0; + } else { + this._timeTaken = this._duration; + this.active = false; + } + } + let t = this._easingFunction( + this._timeTaken / this._duration + ); + this._updateFunc( + this._interpolationFunc, + this._to, + this._from, + t, + this._into + ); } /** - * Translates this bound to the given position. - * - * @param {Vector_like} pos + * @param {Tween} next */ - update(pos) { - //let dx = pos.x - this.pos.x - //let dy = pos.y - this.pos.y - - this.pos.x = pos.x; - this.pos.y = pos.y; - } - toJson(){ - return { - posX:this.pos.x, - posY:this.pos.y, - r:this.r - } - } - fromJson(obj){ - this.pos.x = obj.posX; - this.pos.y = obj.posY; - this.r = obj.r; + chain(next) { + this._next = next; + return this } - } + } + /** + * @template T + * @type {TweenUpdate} + */ + function Vector2Update(lerpFunc, to, from, t, into) { + into.x = lerpFunc(from.x, to.x, t); + into.y = lerpFunc(from.y, to.y, t); + } + /** + * @template T + * @type {TweenUpdate} + */ + function Vector3Update(lerpFunc, to, from, t, into) { + into.x = lerpFunc(from.x, to.x, t); + into.y = lerpFunc(from.y, to.y, t); + into.z = lerpFunc(from.z, to.z, t); + } + + /** + * @template T + * @type {TweenUpdate} + */ + function ColorUpdate(lerpFunc, to, from, t, into) { + into.r = lerpFunc(from.r, to.r, t); + into.g = lerpFunc(from.g, to.g, t); + into.b = lerpFunc(from.b, to.b, t); + into.a = lerpFunc(from.a, to.a, t); + } + /** + * @template T + * @type {TweenUpdate} + */ + function AngleUpdate(lerpFunc, to, from, t, into) { + into.rad = lerpFunc(from.rad, to.rad, t); + } + /** + * @template T + * @type {TweenUpdate} + */ + function NoUpdateThrow(lerpFunc, to, from, t, into) { + throw "The Tween does not have a valid onUpdate callback." + } + + /** + * @template {T} + * @callback TweenUpdate + * @param {LerpFunc} lerpFunc + * @param {T} to + * @param {T} from + * @param {number} t + * @param {T} into + * + * @returns {void} + */ + + /** + * @callback LerpFunc + * @param {number} p0 + * @param {number} p1 + * @param {number} t + * @returns {number} + */ class Geometry { /** @@ -3238,7 +3646,7 @@ SOFTWARE. } /** * @param {number} rad - * @param { Vector2[]} target + * @param {Vector2[]} target */ getNormals(rad, target) { target = target || []; @@ -3273,7 +3681,7 @@ SOFTWARE. * @param {number} n * @param { Vector2[]} vertices * @param { Vector2} pos - * @patam {number} rad + * @param {number} rad */ transform(vertices, pos, rad, n) { for (let i = 0; i < this.vertices.length; i++) { @@ -3337,7 +3745,7 @@ SOFTWARE. type:BodyType.DYNAMIC }; - let tmp1$c = new Vector2$1(); + let tmp1$d = new Vector2$1(); /** * This class makes a body tangible @@ -3425,7 +3833,7 @@ SOFTWARE. */ update(position, angle, scale) { this.angle = this.offAngle + angle; - this.geometry.transform(this.vertices, tmp1$c.copy(position).add(this.offPosition), this.angle, 1 , position); + this.geometry.transform(this.vertices, tmp1$d.copy(position).add(this.offPosition), this.angle, 1 , position); } /** @@ -3476,7 +3884,7 @@ SOFTWARE. /** * @param {number} length * @param { Vector2} offset - * @param {number} pffsetAngle + * @param {number} offsetAngle */ constructor(length,offset,offsetAngle) { let start = new Vector2$1(1).multiply(length / 2), @@ -3630,7 +4038,7 @@ SOFTWARE. } - let tmp1$b = new Vector2$1(); + let tmp1$c = new Vector2$1(); /** * A triangular shape. @@ -3644,18 +4052,23 @@ SOFTWARE. * @param {number} angle The angle between the two sides. * @param { Vector2} offset Positional offset from the body center. * @param {number} offsetAngle Angular offset from the body center. - * */ constructor(base, height, angle, offset, offsetAngle) { let l1 = new Vector2$1().set(1, 0).multiply(base); let l2 = Vector2$1.fromRad(angle).multiply(height/Math.sin(angle)); - let center = tmp1$b.set((l1.x + l2.x) / 3, l2.y / 3); + let center = tmp1$c.set((l1.x + l2.x) / 3, l2.y / 3); super([ new Vector2$1().sub(center), l1.sub(center), l2.sub(center) ], offset, offsetAngle); } + /** + * @param {number} mass + * @param {number} base + * @param {number} height + * @param {number} angle + */ static calcInertia(mass,base,height,angle){ return 0.5 * mass * base * height * (1 - 2/3 * (1 - (Math.cos(2 * angle * 180/Math.PI))/2)) } @@ -3716,6 +4129,10 @@ SOFTWARE. * */ class Movable$1 extends Component { + /** + * @type {Transform} + */ + transform = null /** * * @param {number} x * @param {number} y @@ -3724,12 +4141,14 @@ SOFTWARE. */ constructor(x, y, a) { super(); - this.transform = null; this.velocity = new Vector2$1(x, y); this.rotation = new Angle(a); this.acceleration = new Vector2$1(); this.torque = new Angle(); } + /** + * @inheritdoc + */ init(entity) { this.requires(entity, "transform"); if (!this.transform) @@ -3750,19 +4169,34 @@ SOFTWARE. } class Intergrator extends System { + /** + * @type {boolean} + */ active = false + /** + * @type {typeof EulerSolver.solve} + */ solver = EulerSolver.solve + /** + * @type {Movable} + */ objects = [] constructor() { super(); } + /** + * @inheritdoc + */ init(manager) { const world = manager.getSystem("world"); if (world) world.enableIntergrate = false; this.active = true; - + manager.setComponentList("movable", this.objects); } + /** + * @inheritdoc + */ update(dt) { for (let i = 0; i < this.objects.length; i++) { if (this.objects[i] == void 0) return @@ -3781,6 +4215,8 @@ SOFTWARE. */ class EulerSolver { /** + * @param {Transform} transform + * @param {Movable} movable * @param {number} dt */ static solve(transform, movable, dt) { @@ -4193,15 +4629,23 @@ SOFTWARE. /** * Applies a force to a body affecting its direction of travel and rotation. * - * * @param { Vector2} force The force to be applied. - * @param { Vector2} [arm= Vector2] The collision arm. + * @param { Vector2} [arm = Vector2] The collision arm. */ applyForce(force, arm = Vector2$1.ZERO) { this.acceleration.add(force.multiply(this.inv_mass)); - this.rotation.value += arm.cross(force) * this.inv_inertia; + this.torque.value += arm.cross(force) * this.inv_inertia; + } + /** + * Applies a force to a body affecting its direction of travel and rotation. + * + * @param { Vector2} impulse The force to be applied. + * @param { Vector2} [arm = Vector2] The collision arm. + */ + applyImpulse(impulse, arm = Vector2$1.ZERO) { + this.velocity.add(impulse.multiply(this.inv_mass)); + this.rotation.value += arm.cross(impulse) * this.inv_inertia; } - /** * Initializes the body to its given.Called by the world or an entity manager. * @@ -4214,8 +4658,8 @@ SOFTWARE. this.bounds = new BoundingBox(); if (entity != void 0) { this._movable.transform = this._transform; - entity.manager.addComponent("transform",this._transform); - entity.manager.addComponent("movable",this._movable); + entity.manager.addComponent("transform", this._transform); + entity.manager.addComponent("movable", this._movable); } this.update(); return @@ -4247,9 +4691,9 @@ SOFTWARE. this.bounds.update(this.position); //this.angle = this.angle > 360 ? this.angle - 360 : this.angle < 0 ? 360 + this.angle : this.angle } - - destroy(){ - this.entity.manager.removeComponent("movable",this._movable); + + destroy() { + this.entity.manager.removeComponent("movable", this._movable); } toJson() { let obj = { @@ -4280,7 +4724,12 @@ SOFTWARE. }); return obj } - //TODO - Add way to add shapes to body + /** + * @@param {Shape} shape + */ + addShape(shape) { + this.shapes.push(shape); + } fromJson(obj) { let shapes = []; obj.shapes.forEach((shape) => { @@ -4632,6 +5081,30 @@ SOFTWARE. * @see SpringConstraint */ class Constraint { + /** + * @type {Vector2} + */ + localA = null + /** + * @type {Vector2} + */ + localB = null + /** + * @type {Body} + */ + body1 = null + /** + * @type {Body} + */ + body2 = null + /**: + * @type {number} + */ + stiffness = 50 + /** + * @type {number} + */ + dampening = 0.03 /** * @param {Body} body1 * @param {Body} body2 @@ -4643,8 +5116,6 @@ SOFTWARE. this.body2 = body2; this.localA = localA || new Vector2$1(); this.localB = localB || new Vector2$1(); - this.stiffness = 50; - this.dampening = 0.03; } /** * Determine type of object this is in the world. @@ -4694,7 +5165,7 @@ SOFTWARE. localB: this.localB.toJson(), stiffness: this.stiffness, dampening: this.dampening, - type:this.CHAOS_OBJ_TYPE + type: this.CHAOS_OBJ_TYPE } } fromJson(obj, world) { @@ -4713,7 +5184,7 @@ SOFTWARE. } } - let tmp1$a = new Vector2$1(), + let tmp1$b = new Vector2$1(), tmp2$8 = new Vector2$1(), tmp3$4 = new Vector2$1(), tmp4$4 = new Vector2$1(), @@ -4744,7 +5215,7 @@ SOFTWARE. * @param {number} dt */ behavior(body1, body2,dt) { - let arm1 = tmp1$a.copy(this.localA), + let arm1 = tmp1$b.copy(this.localA), arm2 = tmp2$8.copy(this.localB), pos1 = tmp3$4.copy(body1.position).add(arm1), pos2 = tmp4$4.copy(body2.position).add(arm2), @@ -4772,7 +5243,7 @@ SOFTWARE. } } - let tmp1$9 = new Vector2$1(), + let tmp1$a = new Vector2$1(), tmp2$7 = new Vector2$1(), tmp3$3 = new Vector2$1(), tmp4$3 = new Vector2$1(), @@ -4805,7 +5276,7 @@ SOFTWARE. * @param {number} dt */ behavior(body1, body2, dt) { - let arm1 = tmp1$9.copy(this.localA), + let arm1 = tmp1$a.copy(this.localA), arm2 = tmp2$7.copy(this.localB), pos1 = tmp3$3.copy(body1.position).add(arm1), pos2 = tmp4$3.copy(body2.position).add(arm2), @@ -4859,7 +5330,7 @@ SOFTWARE. } } - let tmp1$8 = new Vector2$1(), + let tmp1$9 = new Vector2$1(), tmp2$6 = new Vector2$1(), tmp3$2 = new Vector2$1(), tmp4$2 = new Vector2$1(), @@ -4874,7 +5345,7 @@ SOFTWARE. let { bodyA: a, bodyB: b, ca1, ca2, impulse } = manifold; let { axis } = manifold.contactData; if (impulse <= 0) return - let a$va = tmp1$8.set(ca1.y * -a.rotation.value, ca1.x * a.rotation.value); + let a$va = tmp1$9.set(ca1.y * -a.rotation.value, ca1.x * a.rotation.value); let a$vb = tmp2$6.set(ca2.y * -b.rotation.value, ca2.x * b.rotation.value); let va = tmp3$2.copy(a.velocity).add(a$va); let vb = tmp4$2.copy(b.velocity).add(a$vb); @@ -4939,7 +5410,7 @@ SOFTWARE. } }; - const tmp1$7 = new Vector2$1(), + const tmp1$8 = new Vector2$1(), tmp2$5 = new Vector2$1(); let dampen = Settings.posDampen; @@ -4954,15 +5425,15 @@ SOFTWARE. const dampened = overlap * dampen; const a = dampened / (bodyA.inv_mass + bodyB.inv_mass + sq(ca1.cross(axis)) * bodyA.inv_inertia + sq(ca2.cross(axis)) * bodyB.inv_inertia); let jp = tmp2$5.copy(axis).multiply(a); - bodyA.velocity.add(tmp1$7.copy(jp).multiply(bodyA.inv_mass * inv_dt)); - bodyB.velocity.add(tmp1$7.copy(jp).multiply(-bodyB.inv_mass * inv_dt)); + bodyA.velocity.add(tmp1$8.copy(jp).multiply(bodyA.inv_mass * inv_dt)); + bodyB.velocity.add(tmp1$8.copy(jp).multiply(-bodyB.inv_mass * inv_dt)); bodyA.rotation.value += ca1.cross(jp) * bodyA.inv_inertia * inv_dt; bodyB.rotation.value += ca2.cross(jp) * -bodyB.inv_inertia * inv_dt; manifold.contactData.lastOverlap = overlap; } }; - let tmp1$6 = new Vector2$1(), + let tmp1$7 = new Vector2$1(), tmp2$4 = new Vector2$1(), tmp3$1 = new Vector2$1(), tmp4$1 = new Vector2$1(); @@ -4974,7 +5445,7 @@ SOFTWARE. solve(manifold) { let { bodyA, bodyB, ca1, ca2, restitution } = manifold; let { axis } = manifold.contactData; - let a$va = tmp1$6.set(ca1.y * -bodyA.rotation.value, ca1.x * bodyA.rotation.value); + let a$va = tmp1$7.set(ca1.y * -bodyA.rotation.value, ca1.x * bodyA.rotation.value); let a$vb = tmp2$4.set(ca2.y * -bodyB.rotation.value, ca2.x * bodyB.rotation.value); let va = tmp3$1.copy(bodyA.velocity).add(a$va); let vb = tmp4$1.copy(bodyB.velocity).add(a$vb); @@ -5502,6 +5973,9 @@ SOFTWARE. if (maxdepth) this._root.split(maxdepth); } + /** + * @private + */ _insert(client) { client.bounds.copy(client.body.bounds); if (!this._root.contains(obj.bounds)) @@ -5519,6 +5993,9 @@ SOFTWARE. } this._insert(client); } + /** + * @private + */ _remove(client) { return this._root.removeObject(obj) } @@ -5554,7 +6031,7 @@ SOFTWARE. /** * A depth first search of the quadtree that applies the given function to its nodes. * - * @param {Function} func The function that checks every node unless it returns true. + * @param {Traverser} func The function that checks every node unless it returns true. * */ traverse(func) { @@ -5576,7 +6053,7 @@ SOFTWARE. * Resizes a quadtree to a new bound size. * This method should not be used without care. * - * @param {Bounds} bounds. + * @param {Bounds} bounds * */ recalculateBounds(bounds) { @@ -5607,10 +6084,10 @@ SOFTWARE. * @callback Traverser * @param {Node} node * @returns {boolean} - */ + */ const _arr = [], - tmp1$5 = { + tmp1$6 = { overlap: 0, verticesA: null, verticesB: null, @@ -5722,7 +6199,7 @@ SOFTWARE. * @param {number} iu */ projectShapesToAxes(shapeA, shapeB, axes, manifold, iu) { - let temp = tmp1$5; + let temp = tmp1$6; temp.vertex = null; temp.body = null; temp.overlap = Infinity; @@ -5877,7 +6354,15 @@ SOFTWARE. }; class NarrowPhase{ + /** + * @type {Map} + */ records = new Map() + /** + * @param {CollisionPair[]} contactList + * @param {Manifold[]} clmds + * @returns {Manifold[]} + */ getCollisionPairs(contactList,clmds){ } } @@ -5964,7 +6449,7 @@ SOFTWARE. /** * Class responsible for updating bodies,constraints and composites. */ - class World { + class World extends System { /** * Used to check if a manifold is persistent. * @@ -6079,6 +6564,7 @@ SOFTWARE. enableIntergrate = true constructor() { + super(); this.broadphase = new NaiveBroadphase(this); this.narrowphase = new SATNarrowPhase(); } @@ -6187,6 +6673,8 @@ SOFTWARE. let a = this.objects[i]; if (a.mass) a.acceleration.add(this.gravitationalAcceleration); + a.velocity.add(a.acceleration.multiply(dt)); + a.acceleration.set(0, 0); } } /** @@ -6399,10 +6887,10 @@ SOFTWARE. * @see WebGLRenderer * @see WebGPURenderer */ - class Renderer { + class Renderer extends System { /** * @type number - */ + */ _rafID = 0 /** * Used to throttle the frame rate. @@ -6441,6 +6929,7 @@ SOFTWARE. * @param {HTMLCanvasElement} canvas element to draw on */ constructor(canvas, context) { + super(); this.domElement = canvas; this.ctx = context; this.camera = new Camera(this); @@ -6666,10 +7155,9 @@ SOFTWARE. * This is the base class used to render images and paths onto the renderer. * Extend it to create your custom behaviour. * - * @implements Component * TODO - ADD id property to this class and Group class. */ - class Sprite { + class Sprite extends Component{ /** * @private */ @@ -6699,6 +7187,7 @@ SOFTWARE. * @param {Material} material */ constructor(geometry, material) { + super(); this.geometry = geometry; this.material = material; } @@ -6735,6 +7224,10 @@ SOFTWARE. set orientation(x) { this._orientation.copy(x); } + /** + * @param {CanvasRenderingContext2D} ctx + * @param {number} dt + */ render(ctx, dt) { ctx.save(); ctx.beginPath(); @@ -6764,6 +7257,10 @@ SOFTWARE. this._scale = new Vector2$1(1,1); return this } + /** + * @inheritdoc + * @returns {*} + */ toJson(){ let obj = { pos:this._position.toJson(), @@ -6774,11 +7271,17 @@ SOFTWARE. }; return obj } + /** + * @inheritdoc + * + * @param {Renderer} renderer + */ fromJson(obj,renderer){ this.geometry?.fromJson(obj.geometry); this.material?.fromJson(obj.material); this.position.fromJson(obj.pos); this._orientation.fromJson(obj.angle); + //Todo - implement this renderer function this.parent = renderer.getById(obj.parent); } } @@ -6980,12 +7483,14 @@ SOFTWARE. w = img.width, h = img.height, ix = 0, - iy = 0 + iy = 0, + dw = w, + dh = h ) { ctx.drawImage(img, w * ix, h * iy, w, h, x, y, - w, h); + dw, dh); } /** @@ -6994,74 +7499,76 @@ SOFTWARE. */ class SpriteMaterial { /** - * @type HTMLImageElement + * @type {HTMLImageElement} */ img = null /** * The index of the current action. * * @private - * @type number + * @type {number} */ _index = 0 /** * The current action's max frame index. * * @private - * @type number + * @type {number} */ _maxFrame = 0 /** * The current frame of an action. * * @private - * @type number + * @type {number} */ _frame = 0 /** * Used with ImageSprite#frameRate to throttle the fps of the sprite. * * @private - * @type number + * @type {number} */ _accumulator = 0 /** * The maximum frames for each given action. * - * @type number + * @type {number} */ frameRate = 1 / 60 /** * The current action. * * @private - * @type number[] + * @type {number[]} */ - _maxFrames = null + _maxFrames = [] + /** + * @type {Vector} /** * The width of the sprite. * - * @type number + * @type {number} */ width = 0 /** * The height of the sprite.. * - * @type number + * @type {number} */ height = 0 /** * The width of a frame. * * @private - * @type number + * @type {number} */ frameWidth = 0 /** * The height of a frame.. * * @private - * @type number + * @type {number} */ frameHeight = 0 /** @@ -7080,10 +7587,13 @@ SOFTWARE. */ setup(frames, actions) { this._maxFrame = frames - 1; - this.width = this.img.width; - this.height = this.img.height; this.frameWidth = this.img.width / (frames || 1); this.frameHeight = this.img.height / actions; + this.width ||= this.frameWidth; + this.height ||= this.frameHeight; + for (var i = 0; i < actions; i++) { + this._maxFrames.push(frames); + } } /** * Sets max number of frames for a given action @@ -7092,39 +7602,91 @@ SOFTWARE. * @param {number} max */ setMaxFrames(action, max) { - this._maxFrames = max; + this._maxFrames[action] = max; + } + /** + * Sets a given action to be rendered + * + * @param {number} index + */ + setAction(index) { + this._maxFrame = (this._maxFrames[index] || 0); + this._index = index; + this._frame = 0; + } + /** + * @param {CanvasRenderingContext2D} ctx + * @param {number} dt + */ + render(ctx, dt) { + drawImage( + ctx, + this.img, + -this.width / 2, + -this.width / 2, + this.frameWidth, + this.frameHeight, + this._frame, + this._index, + this.width, + this.height + ); + this._accumulator += dt; + if (this._accumulator < this.frameRate) return + this._accumulator = 0; + this._frame += 1; + if (this._frame >= this._maxFrame) + this._frame = 0; } + } + + /** + * Material for rendering text. + */ + class TextMaterial extends Material { + /** + * @type {String} + */ + text = "" + /** + * @type {boolean} + */ + center = false + /** + * @type {String} + */ + color = "white" + /** + * @type {boolean} + */ + fill = true + /** + * @type {String} + */ + font = "16px sans-serif" /** - * Sets a given action to be rendered - * - * @param {number} index + * @param {String} text */ - setAction(index) { - this._maxFrame = (this._maxFrames[index] || 0); - this._index = index; - this._frame = 0; + constructor(text) { + super(); + this.text = text; } /** + * @inheritdoc * @param {CanvasRenderingContext2D} ctx - * @param {number} dt */ - render(ctx, dt) { - drawImage( - ctx, - this.img, - -this.frameWidth / 2, - -this.frameHeight / 2, - this.frameWidth, - this.frameHeight, - this._frame, - this._index - ); - this._accumulator += dt; - if (this._accumulator < this.frameRate) return - this._accumulator = 0; - this._frame += 1; - if (this._frame >= this._maxFrame) - this._frame = 0; + render(ctx) { + /**@type {TextMetrics}*/ + const metrics = ctx.measureText(this.text); + const x = this.center ? -metrics.width / 2 : 0; + const y = 0; + ctx.strokeRect = this.color; + ctx.fillStyle = this.color; + ctx.font = this.font; + if (this.fill) + ctx.fillText(this.text, x, y); + else + ctx.strokeText(this.text, x, y); } } @@ -7154,7 +7716,7 @@ SOFTWARE. * @type {boolean} */ drawBounds = false - /** + /** * Determine whether to draw the position of the body. * * @type {boolean} @@ -7174,7 +7736,7 @@ SOFTWARE. * @inheritdoc * @param {CanvasRenderingContext2D} ctx * @param {number} dt - */ + */ render(ctx, dt) { if (this.body.physicsType == ObjType.COMPOSITE) { @@ -7192,6 +7754,11 @@ SOFTWARE. if (this.drawPosition) this._drawCenter(this.body, ctx); } + /** + * @private + * @param {Body} body + * @param {CanvasRenderingContext2D} renderer + */ _drawCenter(body, ctx) { ctx.beginPath(); circle( @@ -7301,6 +7868,9 @@ SOFTWARE. init(ctx) { this.updateVertices(this.vertices); } + /** + * @param {Vector2[]} data + */ updateVertices(data){ const path = this.drawable = new Path2D(); vertices(path, data, true); @@ -7329,6 +7899,37 @@ SOFTWARE. } } + class BoxGeometry extends BufferGeometry{ + constructor(width,height){ + let v1 = new Vector2$1(-width / 2, -height / 2); + let v2 = new Vector2$1(-width / 2, height / 2); + let v3 = new Vector2$1(width / 2, height / 2); + let v4 = new Vector2$1(width / 2, -height / 2); + super([v1, v2, v3, v4]); + } + } + + class TriangleGeometry extends BufferGeometry{ + constructor(base, height, angle) { + let l1 = new Vector2$1(1).multiply(base); + let l2 = Vector2$1.fromRad(angle).multiply(height/Math.sin(angle)); + let center = tmp1.set((l1.x + l2.x) / 3, l2.y / 3); + super([ + new Vector2$1().sub(center), + l1.sub(center), + l2.sub(center) + ]); + } + } + + class LineGeometry extends BufferGeometry { + constructor(length) { + let start = new Vector2$1(1).multiply(length / 2), + end = new Vector2$1(1).multiply(-length / 2); + super([start, end]); + } + } + let geometry = new BufferGeometry([ new Vector2$1(-10, -10), new Vector2$1(-10, 10), @@ -7627,21 +8228,30 @@ SOFTWARE. class CamController { /** - * @readonly - * @type Vector2 + * @type {Vector2} */ offset = new Vector2$1() + /** + * @type {Transform} + */ + transform = null + /** + * @type {Vector2 | null} + */ + targetPosition = null + /** + * @type {Angle | null} + */ + targetOrientation = null /** * @param {Camera} camera */ + constructor(camera) { this.transform = camera.transform; - this.offset = new Vector2$1(); - this.targetPosition = null; - this.targetOrientation = null; } /** - * @param { Vector2} position + * @param {Vector2} position * @param {Angle} orientation */ follow(position, orientation = null) { @@ -8022,9 +8632,10 @@ SOFTWARE. * @type {AudioBufferSourceNode} */ _source = null + //Todo - Check to see if this one works /** * @private - * @type {function} + * @type {Function} */ _onended = null /** @@ -8076,6 +8687,8 @@ SOFTWARE. } /** * Set callback when the sound finishes playing. + * + * @type {Function} */ set onended(x) { this._onended = x; @@ -8585,7 +9198,7 @@ SOFTWARE. draw(renderer) {} } - let tmp1$4 = new Vector2$1(); + let tmp1$5 = new Vector2$1(); /** * Creates a behaviour to evade a certain position. * @@ -8621,7 +9234,7 @@ SOFTWARE. * @returns Vector2 the first parameter */ calc(target,inv_dt) { - let difference = tmp1$4.copy(this.position).sub(this.pursuer); + let difference = tmp1$5.copy(this.position).sub(this.pursuer); let length = difference.magnitude(); if(length == 0 || length > this.radius)return difference.setMagnitude(map(length,0,this.radius,this.maxSpeed,0)); @@ -8632,7 +9245,7 @@ SOFTWARE. } } - let tmp1$3 = new Vector2$1(), + let tmp1$4 = new Vector2$1(), tmp2$2 = new Vector2$1(); /** @@ -8677,7 +9290,7 @@ SOFTWARE. calc(target, inv_dt) { this._theta += rand(-this.dtheta, +this.dtheta); - let forward = tmp1$3.copy(this.velocity); + let forward = tmp1$4.copy(this.velocity); if (forward.equalsZero()) Vector2$1.random(forward); let radius = this._radius * 0.8; @@ -8753,7 +9366,7 @@ SOFTWARE. } } - let tmp1$2 = new Vector2$1(); + let tmp1$3 = new Vector2$1(); /** * Creates a behaviour to seek out a target and move towards it. @@ -8794,7 +9407,7 @@ SOFTWARE. * @returns Vector2 the first parameter */ calc(target,inv_dt) { - let difference = tmp1$2.copy(this.target).sub(this.position); + let difference = tmp1$3.copy(this.target).sub(this.position); difference.setMagnitude(this.maxSpeed); let steering = difference.sub(this.velocity).multiply(inv_dt); @@ -8803,7 +9416,7 @@ SOFTWARE. } } - let tmp1$1 = new Vector2$1(), + let tmp1$2 = new Vector2$1(), tmp2$1 = new Vector2$1(); /** @@ -8841,7 +9454,7 @@ SOFTWARE. * @returns Vector2 the first parameter */ calc(target, inv_dt) { - let difference = tmp1$1.copy(this.target).sub(this.position); + let difference = tmp1$2.copy(this.target).sub(this.position); let velocity = tmp2$1.copy(this.velocity); let length = difference.magnitude(); @@ -8859,7 +9472,7 @@ SOFTWARE. } } - const tmp1 = new Vector2$1(); + const tmp1$1 = new Vector2$1(); const tmp2 = new Vector2$1(); /** * Creates a behaviour that follows a certain path. @@ -8888,18 +9501,18 @@ SOFTWARE. * @returns Vector2 the first parameter */ calc(target, inv_dt) { - tmp1.copy(this.position); + tmp1$1.copy(this.position); let [p1, p2] = this.path.current(); tmp2.copy(p2).sub(p1).normalize(); - let proj = tmp2.dot(tmp1.sub(p1)); + let proj = tmp2.dot(tmp1$1.sub(p1)); let projPoint = this.path.update(proj); - tmp1.copy(projPoint).sub(this.position); - let length = tmp1.magnitude(); + tmp1$1.copy(projPoint).sub(this.position); + let length = tmp1$1.magnitude(); if (length < this.velocity.magnitude()) { - tmp1.setMagnitude(map(length, 0, this.maxSpeed, 0, this.maxSpeed)); + tmp1$1.setMagnitude(map(length, 0, this.maxSpeed, 0, this.maxSpeed)); } - let steering = tmp1.sub(this.velocity).multiply(inv_dt); + let steering = tmp1$1.sub(this.velocity).multiply(inv_dt); steering.clamp(0, this.maxForce); target.add(steering); @@ -9027,7 +9640,7 @@ SOFTWARE. return this } /** - * private + * @private */ advance() { if (this._points.length < 2) return false @@ -9067,15 +9680,24 @@ SOFTWARE. ); return this._lerpedPoint } + /** + * @returns {Vector2[]} + */ current() { return [ this._points[this._way[0]], this._points[this._way[1]] ] } + /** + * @returns {Vector2} + */ point() { return this._lerpedPoint } + /** + * @type {Vector2[]} + */ get path() { return this._points } @@ -9395,16 +10017,37 @@ SOFTWARE. } }; + /** + * @template T + */ class IndexedList { + /** + * @private + * @type {Map} + */ _keys = new Map() + /** + * @private + * @type {T[]} + */ _list = [] - get(name){ + /** + * @param {string} name + */ + get(name) { return this._list[this._keys.get(name)] } - push(name, value) { - this._keys.set(name,this._list.length); + /** + * @param {string} name + * @param {T} value + */ + set(name, value) { + this._keys.set(name, this._list.length); this._list.push(value); } + /** + * @param {string} name + */ remove(name) { this._list.splice( this._keys.get(name), @@ -9412,6 +10055,15 @@ SOFTWARE. ); this._keys.delete(name); } + /** + * @returns {string[]} + */ + keys() { + return this._keys.keys() + } + /** + * @returns {T[]} + */ values() { return this._list } @@ -9465,7 +10117,9 @@ SOFTWARE. } //import {System} from "../ecs/index.js" - + /** + * @param {Manager} manager + */ function fpsDebugger(manager) { const container = document.body.appendChild(document.createElement("div")); @@ -9529,75 +10183,218 @@ SOFTWARE. }); } + /** + * @param {Manager} manager + */ + function raycastDebugger(manager) { + manager.registerSystem("raycastDebugger", { + renderer: null, + raycaster: null, + init(manager) { + const that = this; + this.renderer = manager.getSystem("renderer"); + this.raycaster = manager.getSystem("raycaster"); + setupDebugger(this); + manager.events.add("clear", e => { + setupDebugger(that); + }); + }, + update(dt) {} + }); + } + + function setupDebugger(debug) { + debug.renderer.add({ + render(ctx) { + debug.raycaster.objects.forEach(e => { + ctx.save(); + ctx.beginPath(); + ctx.translate(...e._transform.position); + e.rays.forEach(r => { + ctx.moveTo(0, 0); + ctx.lineTo( + r.direction.x * r.maxLength, + r.direction.y * r.maxLength + ); + ctx.lineWidth = 2; + }); + ctx.strokeStyle = "rgba(255,255,255,0.5)"; + ctx.stroke(); + ctx.closePath(); + ctx.restore(); + e.collisionResults.forEach(r => { + r.collisions.forEach(c => { + c.points.forEach(p => { + ctx.beginPath(); + ctx.arc(...p.point, 3, 0, Math.PI * 2); + ctx.strokeStyle = "white"; + ctx.stroke(); + ctx.closePath(); + }); + }); + }); + }); + } + }); + } + class Ray { + /** + * @type {number} + */ maxLength = 1000; - constructor(origin = new Vector2$1(), direction = new Vector2$1()) { + /** + * @private + * @type {Vector2} + */ + _origin = null; + /** + * @private + * @type {Vector2} + */ + _direction = null; + /** + * @param {Vector2} origin + * @param {Vector2} direction + */ + constructor(origin = new Vector2$1(0, 1), direction = new Vector2$1()) { this._origin = origin; this._direction = direction; } + /** + * @type {Vector2} + */ get direction() { return this._direction } set direction(x) { this._direction.copy(x); } + /** + * @type {Vector2} + */ get origin() { return this._origin } set origin(x) { this._origin.copy(x); } + /** + * @param {number} x + * @param {number} y + */ setOrigin(x, y) { this._origin.set(x, y); } + /** + * @param {number} x + * @param {number} y + */ setDirection(x, y) { this._direction.set(x, y); } + /** + * @param {number} x + * @param {number} y + */ + lookAt(x, y) { + this._direction.set( + x - this._origin.x, + y - this._origin.y + ); + this._direction.normalize(); + } } - class RaycastResult{ - ray = null + class RaycastResult { + //TODO - Make this property work + /** + * @type {RayCastModes} + */ mode = RayCastModes.NONE + /** + * @type {RayCollisionResult[]} + */ collisions = [] } - class RayCollisionResult{ - distance = 0 + class RayCollisionResult { + /** + * @type {Body} + */ object = null - points = [ ] + /** + * @readonly + * @type {RayPoint[]} + */ + points = [] + /** + * @type {Ray} + */ ray = null + /** + * @param {Ray} ray + * @param {Body} object + */ + constructor(ray, object) { + this.ray = ray; + this.object = object; + } + } + class RayPoint { + /** + * @type {Vector2} + */ + point = null + /** + * @type {number} + */ + distance = 0 + /** + * @param {Vector2} point + * @param {number} distance + */ + constructor(point, distance) { + this.point = point; + this.distance = distance; + } } - /** + * @readonly * @enum {number} - * - */ + */ const RayCastModes = { - NONE : 0, - NEAREST:1, - FIRST:2, - ANY:3 + NONE: 0, + NEAREST: 1, + FIRST: 2, + ANY: 3 }; class RaycastManager extends System { + /** + * @private + * @type {Raycaster[]} + */ objects = [] + /** + * @private + * @type {Body[]} + */ bodies = null + /** + * @inheritdoc + * @param {Manager} manager + */ init(manager) { if (!manager.getSystem("world")) throw "World is required for running Raycast system." - - let renderer = manager.getSystem("renderer"); - manager.setComponentList("raycaster",this.objects); + manager.setComponentList("raycaster", this.objects); this.bodies = manager.getComponentList("body"); - renderer.add({ - context:this, - render(ctx) { - this.context.objects.forEach(e=>{ - e.draw(ctx); - }); - } - }); + } - update(){ + /** + * @inheritdoc + */ + update(dt) { for (let i = 0; i < this.objects.length; i++) { this.objects[i].update(this.bodies); } @@ -9605,17 +10402,43 @@ SOFTWARE. } class Raycaster extends Component { + /** + * @type {Ray[]} + */ rays = [] - initialDir = [] + /** + * @type {Ray[]} + */ + collisionResults = [] + /** + * @private + * @type {Ray[]} + */ _number = 0 + /** + * @private + * @type {Ray[]} + */ _angle = 0 + /** + * @private + * @type {Ray[]} + */ _transform = null + /** + * @private + * @type {number} + */ _lastangle = 0 + mode = RayCastModes.ANY constructor(number = 1, angleSpace = 0) { super(); this._angle = angleSpace; this._number = number; } + /** + * @inheritdoc + */ init(entity) { this.requires(entity, "transform"); this._transform = entity.get("transform"); @@ -9623,41 +10446,165 @@ SOFTWARE. const halfview = this._number * this._angle / 2; for (let a = -halfview; a <= halfview; a += this._angle) { this.rays.push(new Ray(new Vector2$1(), Vector2$1.fromRad(a))); - this.initialDir.push(Vector2$1.fromRad(a)); if (this._angle == 0) break } } + /** + * @param {Body[]} bodies + */ update(bodies) { + this.collisionResults = []; const angle = this._transform.orientation.value; const rotangle = angle - this._lastangle; - for (var i = 0; i < this.rays.length; i++) { const ray = this.rays[i]; ray.origin.copy(this._transform.position); ray.direction.rotate(rotangle); } this._lastangle = angle; + for (let i = 0; i < bodies.length; i++) { + const shapes = bodies[i].shapes; + + for (let j = 0; j < shapes.length; j++) { + const shape = shapes[j]; + if (shape.type === Shape.POLYGON) + this.testVertices(shape.vertices, bodies[i]); + if (shape.type === Shape.CIRCLE) + this.testCircle(shape.position, shape.radius, bodies[i]); + } + } } /** - * @param {CanvasRenderingContext2D} ctx - */ - draw(ctx) { - ctx.translate(...this._transform.position); + * @private + */ + testCircle(position, radius, body) { + let results = new RaycastResult(); + for (let i = 0; i < this.rays.length; i++) { + const ray = this.rays[i]; - this.rays.forEach(r => { - ctx.moveTo(0, 0); - ctx.lineTo( - r.direction.x * r.maxLength, - r.direction.y * r.maxLength - ); - }); - ctx.lineWidth = 2; - ctx.strokeStyle = "rgba(255,255,255,0.5)"; - ctx.stroke(); + results.collisions.push(testraycircle(ray, position, radius, body)); + } + this.collisionResults.push(results); + } + /** + * @private + */ + testVertices(vertices, body) { + let results = new RaycastResult(); + for (let i = 0; i < this.rays.length; i++) { + const ray = this.rays[i]; + + results.collisions.push(testray(ray, vertices, body)); + } + this.collisionResults.push(results); } - add() { - throw "noooo" + } + /** + * @private + */ + function testray(ray, vertices, body) { + const origin = ray.origin; + const direction = ray.direction; + const results = new RayCollisionResult(ray, body); + + let res = testSingleEdge( + vertices[vertices.length - 1], + vertices[0], origin, direction + ); + if (res != void 0) + results.points.push( + new RayPoint( + res, + res.clone().sub(origin) + .magnitudeSquared() + ) + ); + for (let i = 0; i < vertices.length - 1; i++) { + let res = testSingleEdge( + vertices[i], vertices[i + 1], + origin, direction + ); + if (res != void 0) + results.points.push( + new RayPoint( + res, + res.clone().sub(origin) + .magnitudeSquared() + ) + ); } + return results + } + + /** + * @private + */ + function testSingleEdge(v1, v2, or, dir) { + const x1 = v1.x; + const y1 = v1.y; + const x2 = v2.x; + const y2 = v2.y; + const x3 = or.x; + const y3 = or.y; + const x4 = dir.x + x3; + const y4 = dir.y + y3; + + const den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); + + if (den === 0) return null + + const t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / den; + const u = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / den; + + if ( + t > 0 && t < 1 && + u > 0 + ) return new Vector2$1( + x1 + t * (x2 - x1), + y1 + t * (y2 - y1) + ) + return null + } + + /** + * @private + */ + function testraycircle(ray, center, radius, body) { + const results = new RayCollisionResult(ray, body); + + const x1 = ray.origin.x; + const y1 = ray.origin.y; + const x2 = ray.direction.x; + const y2 = ray.direction.y; + + const x3 = center.x; + const y3 = center.y; + const x4 = x3 - x1; + const y4 = y3 - y1; + const r = radius; + + const proj = x2 * x4 + y2 * y4; + const delta = proj * proj - ((x4 * x4 + y4 * y4) - r * r); + const sqrtDelta = Math.sqrt(delta); + const distance1 = proj + sqrtDelta; + const distance2 = proj - sqrtDelta; + + if (delta < 0 || distance1 < 0) return results + results.points.push(new RayPoint( + new Vector2$1( + x1 + distance1 * x2, + y1 + distance1 * y2 + ), distance1 * distance1 + )); + if (delta === 0 || (distance2 < 0)) return results + results.points.push(new RayPoint( + new Vector2$1( + x1 + distance2 * x2, + y1 + distance2 * y2 + ), + distance2 * distance2 + )); + return results } exports.Agent = Agent; @@ -9676,17 +10623,20 @@ SOFTWARE. exports.BoundingBox = BoundingBox; exports.BoundingCircle = BoundingCircle; exports.Box = Box; + exports.BoxGeometry = BoxGeometry; exports.BufferGeometry = BufferGeometry; exports.CamController = CamController; exports.Camera = Camera; exports.Circle = Circle; exports.CircleGeometry = CircleGeometry; exports.Clock = Clock; + exports.Color = Color; exports.ColorUpdate = ColorUpdate; exports.Component = Component; exports.Composite = Composite; exports.Constraint = Constraint; exports.Cookies = Cookies; + exports.DEG2RAD = DEG2RAD; exports.DEVICE = DEVICE; exports.DOMEventHandler = DOMEventHandler; exports.DistanceConstraint = DistanceConstraint; @@ -9700,12 +10650,14 @@ SOFTWARE. exports.Flock = Flock; exports.Geometry = Geometry; exports.Group = Group; + exports.HALF_PI = HALF_PI; exports.IndexedList = IndexedList; exports.Input = Input; exports.Intergrator = Intergrator; exports.Interpolation = Interpolation; exports.Keyboard = Keyboard; exports.Line = Line; + exports.LineGeometry = LineGeometry; exports.Loader = Loader; exports.Manager = Manager; exports.Material = Material; @@ -9716,6 +10668,7 @@ SOFTWARE. exports.NaiveBroadphase = NaiveBroadphase; exports.NarrowPhase = NarrowPhase; exports.Overlaps = Overlaps; + exports.PI = PI; exports.Particle = Particle; exports.ParticleSystemSprite = ParticleSystemSprite; exports.Path = Path; @@ -9723,9 +10676,11 @@ SOFTWARE. exports.Perf = Perf; exports.Pursuit = Pursuit; exports.QuadTreeBroadphase = QuadTreeBroadphase; + exports.RAD2DEG = RAD2DEG; exports.Ray = Ray; exports.RayCastModes = RayCastModes; exports.RayCollisionResult = RayCollisionResult; + exports.RayPoint = RayPoint; exports.RaycastManager = RaycastManager; exports.RaycastResult = RaycastResult; exports.Raycaster = Raycaster; @@ -9733,6 +10688,7 @@ SOFTWARE. exports.Renderer = Renderer; exports.Renderer2D = Renderer2D; exports.SATNarrowPhase = SATNarrowPhase; + exports.SQRT2 = SQRT2; exports.SeekBehaviour = SeekBehaviour; exports.Session = Session; exports.Sfx = Sfx; @@ -9744,9 +10700,12 @@ SOFTWARE. exports.StaticImageMaterial = StaticImageMaterial; exports.Storage = Storage; exports.System = System; + exports.TWO_PI = TWO_PI; + exports.TextMaterial = TextMaterial; exports.Touch = Touch; exports.Transform = Transform$1; exports.Triangle = Triangle; + exports.TriangleGeometry = TriangleGeometry; exports.Trigon = Trigon; exports.Tween = Tween; exports.TweenManager = TweenManager; @@ -9770,6 +10729,7 @@ SOFTWARE. exports.defaultPrecollisionHandler = defaultPrecollisionHandler; exports.degToRad = degToRad; exports.drawImage = drawImage; + exports.epilson = epilson; exports.exp = exp; exports.fill = fill; exports.fillText = fillText; @@ -9781,6 +10741,7 @@ SOFTWARE. exports.naturalizePair = naturalizePair; exports.radToDeg = radToDeg; exports.rand = rand; + exports.raycastDebugger = raycastDebugger; exports.rect = rect; exports.round = round; exports.sq = sq; @@ -9795,13 +10756,17 @@ SOFTWARE. * @property {Vector_like} max * @property {Vector_like} min *//** + * @callback EasingFunc + * @param {number} t + * @returns {number} + *//** * @typedef CollisionPair * @property {Body} a * @property {Body} b */ /** - * @typedef Manifold + * @typedef transform = null * @property {Body} bodyA * @property {Body} bodyB * @property {ContactManifold} contactData diff --git a/doc-template/publish.js b/doc-template/publish.cjs similarity index 100% rename from doc-template/publish.js rename to doc-template/publish.cjs diff --git a/docs/AABBBroadphase.html b/docs/AABBBroadphase.html index 07cea904..0dff2c14 100644 --- a/docs/AABBBroadphase.html +++ b/docs/AABBBroadphase.html @@ -1194,13 +1194,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AI_agent.js.html b/docs/AI_agent.js.html index 792c44f8..3e5b8781 100644 --- a/docs/AI_agent.js.html +++ b/docs/AI_agent.js.html @@ -131,13 +131,13 @@

Source: AI/agent.js


- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AI_behaviourManager.js.html b/docs/AI_behaviourManager.js.html index 6d9a2f5e..2eca7943 100644 --- a/docs/AI_behaviourManager.js.html +++ b/docs/AI_behaviourManager.js.html @@ -108,13 +108,13 @@

Source: AI/behaviourManager.js


- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AI_behaviours_arrive.js.html b/docs/AI_behaviours_arrive.js.html index 2fd216e8..e303be64 100644 --- a/docs/AI_behaviours_arrive.js.html +++ b/docs/AI_behaviours_arrive.js.html @@ -90,13 +90,13 @@

Source: AI/behaviours/arrive.js


- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AI_behaviours_behaviour.js.html b/docs/AI_behaviours_behaviour.js.html index 7aaea37c..542bbdc3 100644 --- a/docs/AI_behaviours_behaviour.js.html +++ b/docs/AI_behaviours_behaviour.js.html @@ -90,13 +90,13 @@

Source: AI/behaviours/behaviour.js


- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AI_behaviours_evade.js.html b/docs/AI_behaviours_evade.js.html index 1d462948..7309ab29 100644 --- a/docs/AI_behaviours_evade.js.html +++ b/docs/AI_behaviours_evade.js.html @@ -81,13 +81,13 @@

Source: AI/behaviours/evade.js


- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AI_behaviours_flocking.js.html b/docs/AI_behaviours_flocking.js.html index b356f7b6..b1fbd0b8 100644 --- a/docs/AI_behaviours_flocking.js.html +++ b/docs/AI_behaviours_flocking.js.html @@ -67,13 +67,13 @@

Source: AI/behaviours/flocking.js


- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AI_behaviours_path.js.html b/docs/AI_behaviours_path.js.html index e6dc302e..655995cb 100644 --- a/docs/AI_behaviours_path.js.html +++ b/docs/AI_behaviours_path.js.html @@ -135,13 +135,13 @@

Source: AI/behaviours/path.js


- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AI_behaviours_pursuit.js.html b/docs/AI_behaviours_pursuit.js.html index d0c191cf..d21e2cfc 100644 --- a/docs/AI_behaviours_pursuit.js.html +++ b/docs/AI_behaviours_pursuit.js.html @@ -62,13 +62,13 @@

Source: AI/behaviours/pursuit.js


- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AI_behaviours_seek.js.html b/docs/AI_behaviours_seek.js.html index 738c53f3..8b0f4288 100644 --- a/docs/AI_behaviours_seek.js.html +++ b/docs/AI_behaviours_seek.js.html @@ -84,13 +84,13 @@

Source: AI/behaviours/seek.js


- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AI_behaviours_wandering.js.html b/docs/AI_behaviours_wandering.js.html index 7efa2522..16d54b46 100644 --- a/docs/AI_behaviours_wandering.js.html +++ b/docs/AI_behaviours_wandering.js.html @@ -96,13 +96,13 @@

Source: AI/behaviours/wandering.js


- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AI_manager.js.html b/docs/AI_manager.js.html index ea7b2536..3683ecc2 100644 --- a/docs/AI_manager.js.html +++ b/docs/AI_manager.js.html @@ -64,13 +64,13 @@

Source: AI/manager.js


- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AI_paths_path.js.html b/docs/AI_paths_path.js.html index 0d894d7a..b2d76741 100644 --- a/docs/AI_paths_path.js.html +++ b/docs/AI_paths_path.js.html @@ -93,7 +93,7 @@

Source: AI/paths/path.js

return this } /** - * private + * @private */ advance() { if (this._points.length < 2) return false @@ -133,15 +133,24 @@

Source: AI/paths/path.js

) return this._lerpedPoint } + /** + * @returns {Vector2[]} + */ current() { return [ this._points[this._way[0]], this._points[this._way[1]] ] } + /** + * @returns {Vector2} + */ point() { return this._lerpedPoint } + /** + * @type {Vector2[]} + */ get path() { return this._points } @@ -164,13 +173,13 @@

Source: AI/paths/path.js


- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Agent.html b/docs/Agent.html index fb542874..fe116018 100644 --- a/docs/Agent.html +++ b/docs/Agent.html @@ -1327,13 +1327,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AgentManager.html b/docs/AgentManager.html index 5cd653bb..12df4960 100644 --- a/docs/AgentManager.html +++ b/docs/AgentManager.html @@ -506,13 +506,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AgentSprite.html b/docs/AgentSprite.html index 288cc196..4c611dc3 100644 --- a/docs/AgentSprite.html +++ b/docs/AgentSprite.html @@ -370,7 +370,7 @@
Type:
Source:
@@ -469,6 +469,144 @@
Type:

Methods

+ + + + + + +

fromJson(renderer)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
renderer + + +Renderer + + + +
+ + + + + + +
+ + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -577,7 +715,7 @@
Parameters:
Source:
@@ -690,6 +828,11 @@
Parameters:
+
Overrides:
+
+ @@ -740,6 +883,113 @@
Parameters:
+ + + + + + +

toJson() → {*}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +* + + +
+
+ + + + + + + @@ -756,13 +1006,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Angle.html b/docs/Angle.html index ff0d5952..e5d10b6b 100644 --- a/docs/Angle.html +++ b/docs/Angle.html @@ -928,13 +928,13 @@
Returns:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/ArriveBehaviour.html b/docs/ArriveBehaviour.html index c843e375..261a83e9 100644 --- a/docs/ArriveBehaviour.html +++ b/docs/ArriveBehaviour.html @@ -1133,13 +1133,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/AudioHandler.html b/docs/AudioHandler.html index 7699b347..9ff163dd 100644 --- a/docs/AudioHandler.html +++ b/docs/AudioHandler.html @@ -621,7 +621,7 @@
Parameters:
-Loader +Loader @@ -1487,13 +1487,13 @@

unmute
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Ball.html b/docs/Ball.html index 2b0f7dad..dc92e78c 100644 --- a/docs/Ball.html +++ b/docs/Ball.html @@ -412,7 +412,7 @@
Type:
Source:
@@ -489,7 +489,7 @@
Type:
Source:
@@ -566,7 +566,7 @@
Type:
Source:
@@ -3186,6 +3186,95 @@
Type:

Methods

+ + + + + + +

addShape()

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -3353,7 +3442,204 @@
Parameters:
Source:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

applyImpulse(impulse, armopt)

+ + + + + + +
+ Applies a force to a body affecting its direction of travel and rotation. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
impulse + + +Vector2 + + + + + + + + + + + + The force to be applied.
arm + + +Vector2 + + + + + + <optional>
+ + + + + +
+ + Vector2 + + The collision arm.
+ + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -3927,7 +4213,7 @@
Parameters:
Source:
@@ -4180,7 +4466,7 @@

updateSource:
@@ -4226,13 +4512,13 @@

update
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/BasicMaterial.html b/docs/BasicMaterial.html index 9d6a3715..9f5b5b81 100644 --- a/docs/BasicMaterial.html +++ b/docs/BasicMaterial.html @@ -568,13 +568,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Behaviour.html b/docs/Behaviour.html index 48ff2ce0..dd280c18 100644 --- a/docs/Behaviour.html +++ b/docs/Behaviour.html @@ -954,13 +954,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/BehaviourManager.html b/docs/BehaviourManager.html index a4f5408b..452ebd99 100644 --- a/docs/BehaviourManager.html +++ b/docs/BehaviourManager.html @@ -930,13 +930,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Body.html b/docs/Body.html index 91ad33bd..a5ede60a 100644 --- a/docs/Body.html +++ b/docs/Body.html @@ -398,7 +398,7 @@
Type:
Source:
@@ -470,7 +470,7 @@
Type:
Source:
@@ -542,7 +542,7 @@
Type:
Source:
@@ -2997,6 +2997,90 @@
Type:

Methods

+ + + + + + +

addShape()

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -3159,7 +3243,199 @@
Parameters:
Source:
+ + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

applyImpulse(impulse, armopt)

+ + + + + + +
+ Applies a force to a body affecting its direction of travel and rotation. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
impulse + + +Vector2 + + + + + + + + + + + + The force to be applied.
arm + + +Vector2 + + + + + + <optional>
+ + + + + +
+ + Vector2 + + The collision arm.
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -3718,7 +3994,7 @@
Parameters:
Source:
@@ -3961,7 +4237,7 @@

updateSource:
@@ -4007,13 +4283,13 @@

update
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/BodySprite.html b/docs/BodySprite.html index f55f5cf3..c918faa5 100644 --- a/docs/BodySprite.html +++ b/docs/BodySprite.html @@ -756,7 +756,7 @@
Type:
Source:
@@ -855,6 +855,144 @@
Type:

Methods

+ + + + + + +

fromJson(renderer)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
renderer + + +Renderer + + + +
+ + + + + + +
+ + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -963,7 +1101,7 @@
Parameters:
Source:
@@ -1096,6 +1234,100 @@
Parameters:
+ + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

toJson() → {*}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + +
Inherited From:
+
@@ -1119,7 +1351,7 @@
Parameters:
Source:
@@ -1144,6 +1376,24 @@
Parameters:
+
Returns:
+ + + + +
+
+ Type +
+
+ +* + + +
+
+ + @@ -1165,13 +1415,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Bound.html b/docs/Bound.html index f45a3326..0e8173a7 100644 --- a/docs/Bound.html +++ b/docs/Bound.html @@ -231,13 +231,13 @@
Type:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/BoundingBox.html b/docs/BoundingBox.html index 3e5fc938..e5a6bcb9 100644 --- a/docs/BoundingBox.html +++ b/docs/BoundingBox.html @@ -276,7 +276,7 @@
Parameters:
Source:
@@ -387,7 +387,7 @@
Type:
Source:
@@ -459,7 +459,7 @@
Type:
Source:
@@ -527,7 +527,7 @@
Type:
Source:
@@ -691,7 +691,7 @@
Parameters:
Source:
@@ -779,7 +779,7 @@

cloneSource:
@@ -926,7 +926,7 @@
Parameters:
Source:
@@ -1066,7 +1066,7 @@
Parameters:
Source:
@@ -1213,7 +1213,7 @@
Parameters:
Source:
@@ -1396,7 +1396,7 @@
Parameters:
Source:
@@ -1452,13 +1452,13 @@
Returns:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/BoundingCircle.html b/docs/BoundingCircle.html index 57de098c..b3922e58 100644 --- a/docs/BoundingCircle.html +++ b/docs/BoundingCircle.html @@ -159,7 +159,7 @@
Parameters:
Source:
@@ -266,7 +266,7 @@
Type:
Source:
@@ -334,7 +334,7 @@
Type:
Source:
@@ -463,7 +463,7 @@
Parameters:
Source:
@@ -603,7 +603,7 @@
Parameters:
Source:
@@ -740,7 +740,7 @@
Parameters:
Source:
@@ -786,13 +786,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Box.html b/docs/Box.html index 1f7a1912..27308c6f 100644 --- a/docs/Box.html +++ b/docs/Box.html @@ -435,7 +435,7 @@
Type:
Source:
@@ -512,7 +512,7 @@
Type:
Source:
@@ -589,7 +589,7 @@
Type:
Source:
@@ -3209,6 +3209,95 @@
Type:

Methods

+ + + + + + +

addShape()

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -3376,7 +3465,204 @@
Parameters:
Source:
+ + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

applyImpulse(impulse, armopt)

+ + + + + + +
+ Applies a force to a body affecting its direction of travel and rotation. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
impulse + + +Vector2 + + + + + + + + + + + + The force to be applied.
arm + + +Vector2 + + + + + + <optional>
+ + + + + +
+ + Vector2 + + The collision arm.
+ + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -3950,7 +4236,7 @@
Parameters:
Source:
@@ -4203,7 +4489,7 @@

updateSource:
@@ -4249,13 +4535,13 @@

update
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Broadphase.html b/docs/Broadphase.html index ba82282f..62621b5d 100644 --- a/docs/Broadphase.html +++ b/docs/Broadphase.html @@ -1159,13 +1159,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/BufferGeometry_BufferGeometry.html b/docs/BufferGeometry_BufferGeometry.html index 3dd4956c..53653f40 100644 --- a/docs/BufferGeometry_BufferGeometry.html +++ b/docs/BufferGeometry_BufferGeometry.html @@ -197,13 +197,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/CamController_CamController.html b/docs/CamController_CamController.html index dda7cb50..4c409f12 100644 --- a/docs/CamController_CamController.html +++ b/docs/CamController_CamController.html @@ -135,7 +135,7 @@
Parameters:
Source:
@@ -197,13 +197,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Circle.html b/docs/Circle.html index ba7fab3e..70090e23 100644 --- a/docs/Circle.html +++ b/docs/Circle.html @@ -1611,13 +1611,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/CircleGeometry_CircleGeometry.html b/docs/CircleGeometry_CircleGeometry.html index 5d3f3f57..88af91ac 100644 --- a/docs/CircleGeometry_CircleGeometry.html +++ b/docs/CircleGeometry_CircleGeometry.html @@ -197,13 +197,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Clock.html b/docs/Clock.html index 759a720d..1ae608ec 100644 --- a/docs/Clock.html +++ b/docs/Clock.html @@ -369,13 +369,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Color.html b/docs/Color.html new file mode 100644 index 00000000..895bb08d --- /dev/null +++ b/docs/Color.html @@ -0,0 +1,1797 @@ + + + + + JSDoc: Class: Color + + + + + + + + + +
+ +

Class: Color

+ + + + + + +
+ +
+ +

Color(ropt, gopt, bopt, alphaopt)

+ +
A color manipulation class.
+ + +
+ +
+
+ + + + +

Constructor

+ + + +

new Color(ropt, gopt, bopt, alphaopt)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
r + + +number + + + + + + <optional>
+ + + + + +
+ + 0 + + red component [0 .. 255]
g + + +number + + + + + + <optional>
+ + + + + +
+ + 0 + + green component [0 .. 255]
b + + +number + + + + + + <optional>
+ + + + + +
+ + 0 + + blue component [0 .. 255]
alpha + + +number + + + + + + <optional>
+ + + + + +
+ + 1.0 + + alpha value [0.0 .. 1.0]
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +

Classes

+ +
+
Color
+
+
+ + + + + + + + + + + +

Methods

+ + + + + + + +

add(color) → {Color}

+ + + + + + +
+ Blend this color with the given one using addition. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
color + + +Color + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to this object for method chaining +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +

clone() → {Color}

+ + + + + + +
+ Create a new copy of this color object. +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to the newly cloned object +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +

copy(color) → {Color}

+ + + + + + +
+ Copy a color object or CSS color into this one. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
color + + +Color +| + +string + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to this object for method chaining +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +

darken(scale) → {Color}

+ + + + + + +
+ Darken this color value by 0..1 +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
scale + + +number + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to this object for method chaining +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +

lerp(color, alpha) → {Color}

+ + + + + + +
+ Linearly interpolate between this color and the given one. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
color + + +Color + + + +
alpha + + +number + + + + with alpha = 0 being this color, and alpha = 1 being the given one.
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to this object for method chaining +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +

lighten(scale) → {Color}

+ + + + + + +
+ Lighten this color value by 0..1 +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
scale + + +number + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to this object for method chaining +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +

random(minopt, maxopt) → {Color}

+ + + + + + +
+ Generate random r,g,b values for this color object +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
min + + +number + + + + + + <optional>
+ + + + + +
+ + 0 + + minimum value for the random range
max + + +number + + + + + + <optional>
+ + + + + +
+ + 255 + + maxmium value for the random range
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to this object for method chaining +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +

set(r, g, b, alphaopt) → {Color}

+ + + + + + +
+ Set this color to the specified value. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
r + + +number + + + + + + + + + + + + red component [0 .. 255]
g + + +number + + + + + + + + + + + + green component [0 .. 255]
b + + +number + + + + + + + + + + + + blue component [0 .. 255]
alpha + + +number + + + + + + <optional>
+ + + + + +
+ + 1.0 + + alpha value [0.0 .. 1.0]
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to this object for method chaining +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/Component.html b/docs/Component.html index 70b87e0f..05c6cc14 100644 --- a/docs/Component.html +++ b/docs/Component.html @@ -248,7 +248,7 @@

Methods

-

get(n)

+

fromJson(obj, system)

@@ -286,6 +286,185 @@
Parameters:
+ + + obj + + + + + +* + + + + + + + + + + + + + + + + + system + + + + + +T + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

get(entity, n)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -345,7 +524,7 @@
Parameters:
Source:
@@ -514,7 +693,7 @@
Parameters:
-

query(bound, targetopt)

+

query(entity, bound, targetopt) → {Array.<Entity>}

@@ -556,6 +735,41 @@
Parameters:
+ + + + + + + + + + + + + + + + + + + + @@ -602,7 +816,7 @@
Parameters:
+ + + + + + + + + + + + + + + + + + @@ -814,7 +1077,91 @@
Parameters:
Source:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

toJson() → {*}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -839,6 +1186,24 @@
Parameters:
+
Returns:
+ + + + +
+
+ Type +
+
+ +* + + +
+
+ + @@ -977,6 +1342,139 @@
Parameters:
+ + + + + + +

(static) implement(component)

+ + + + + + + + + + + + + + +
Parameters:
+ + +
NameTypeDescription
entity + + +Entity + + + +
n
entity + + +Entity + + + + + + + + + + + +
bound -Entity +Array.<Entity> @@ -669,7 +883,7 @@
Parameters:
Source:
@@ -694,6 +908,24 @@
Parameters:
+
Returns:
+ + + + +
+
+ Type +
+
+ +Array.<Entity> + + +
+
+ + @@ -705,7 +937,7 @@
Parameters:
-

requires(…names)

+

requires(entity, …names)

@@ -745,6 +977,37 @@
Parameters:
entity + + +Entity + + + + + + + + + +
names
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
component + + +* + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -993,13 +1491,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Composite.html b/docs/Composite.html index 5e1dc945..91817dcd 100644 --- a/docs/Composite.html +++ b/docs/Composite.html @@ -1414,13 +1414,13 @@

update
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Constraint.html b/docs/Constraint.html index 40b4b364..981205af 100644 --- a/docs/Constraint.html +++ b/docs/Constraint.html @@ -324,7 +324,7 @@
Type:
Source:
@@ -392,7 +392,347 @@
Type:
Source:
+ + + + + + + +

+ + + + + + + + +

body1 :Body

+ + + + + + +
Type:
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

body2 :Body

+ + + + + + +
Type:
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

dampening :number

+ + + + + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

localA :Vector2

+ + + + + + +
Type:
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

localB :Vector2

+ + + + + + +
Type:
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -464,7 +804,79 @@
Type:
Source:
+ + + + + + + +
+ + + + + + + + +

stiffness :number

+ + + + +
+ : +
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -639,7 +1051,7 @@
Parameters:
Source:
@@ -776,7 +1188,7 @@
Parameters:
Source:
@@ -822,13 +1234,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/DOMEventHandler.html b/docs/DOMEventHandler.html index b9c7c92d..34776072 100644 --- a/docs/DOMEventHandler.html +++ b/docs/DOMEventHandler.html @@ -724,13 +724,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/DistanceConstraint.html b/docs/DistanceConstraint.html index b30047f8..4d3064d2 100644 --- a/docs/DistanceConstraint.html +++ b/docs/DistanceConstraint.html @@ -460,13 +460,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Entity.html b/docs/Entity.html index 467a88af..7d397313 100644 --- a/docs/Entity.html +++ b/docs/Entity.html @@ -140,6 +140,142 @@

Members

+

CHAOS_CLASSNAME :string

+ + + + + + +
Type:
+
    +
  • + +string + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

CHAOS_OBJ_TYPE :string

+ + + + + + +
Type:
+
    +
  • + +string + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + +

active :boolean

@@ -256,7 +392,7 @@

managerSource:
@@ -385,7 +521,7 @@
Parameters:
Source:
@@ -545,7 +681,7 @@
Parameters:
Source:
@@ -651,7 +787,7 @@

destroySource:
@@ -811,7 +947,7 @@
Parameters:
Source:
@@ -948,7 +1084,7 @@
Parameters:
Source:
@@ -1106,7 +1242,7 @@
Parameters:
Source:
@@ -1264,7 +1400,7 @@
Parameters:
Source:
@@ -1419,7 +1555,7 @@
Parameters:
Source:
@@ -1574,7 +1710,7 @@
Parameters:
Source:
@@ -1766,7 +1902,7 @@
Parameters:
Source:
@@ -1944,7 +2080,7 @@
Parameters:
Source:
@@ -2081,7 +2217,7 @@
Parameters:
Source:
@@ -2169,7 +2305,7 @@

remov
Source:
@@ -2257,7 +2393,7 @@

removeSelf<
Source:
@@ -2394,7 +2530,7 @@

Parameters:
Source:
@@ -2482,91 +2618,7 @@

(package) reset<
Source:
- - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - -

toJson() → {Object}

- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
@@ -2591,24 +2643,6 @@

toJsonReturns:

- - - - -
-
- Type -
-
- -Object - - -
-
- - @@ -2721,7 +2755,7 @@
Parameters:
Source:
@@ -2904,7 +2938,7 @@
Parameters:
Source:
@@ -2968,13 +3002,13 @@
Returns:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/EulerSolver.html b/docs/EulerSolver.html index 985f88ab..b714b0b1 100644 --- a/docs/EulerSolver.html +++ b/docs/EulerSolver.html @@ -90,7 +90,7 @@

new EulerS
Source:
@@ -146,7 +146,7 @@

Methods

-

(static) solve(dt)

+

(static) solve(transform, movable, dt)

@@ -184,6 +184,52 @@
Parameters:
+ + + transform + + + + + +Transform + + + + + + + + + + + + + + + + + movable + + + + + +Movable + + + + + + + + + + + + + + dt @@ -243,7 +289,7 @@
Parameters:
Source:
@@ -570,7 +616,7 @@

Methods

-

(static) solve(dt)

+

(static) solve(transform, movable, dt)

@@ -608,6 +654,52 @@
Parameters:
+ + + transform + + + + + +Transform + + + + + + + + + + + + + + + + + movable + + + + + +Movable + + + + + + + + + + + + + + dt @@ -667,7 +759,7 @@
Parameters:
Source:
@@ -869,13 +961,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/EvadeBehaviour.html b/docs/EvadeBehaviour.html index bb884ddc..74d04b12 100644 --- a/docs/EvadeBehaviour.html +++ b/docs/EvadeBehaviour.html @@ -1133,13 +1133,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/EventDispatcher.html b/docs/EventDispatcher.html index 80d51f78..24dfc4c0 100644 --- a/docs/EventDispatcher.html +++ b/docs/EventDispatcher.html @@ -219,7 +219,7 @@
Parameters:
-function +EventHandlerFunc @@ -564,13 +564,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Flock.html b/docs/Flock.html index 22c3ee70..14462443 100644 --- a/docs/Flock.html +++ b/docs/Flock.html @@ -1080,13 +1080,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Geometry_Geometry.html b/docs/Geometry_Geometry.html index 89d223a3..b376f761 100644 --- a/docs/Geometry_Geometry.html +++ b/docs/Geometry_Geometry.html @@ -197,13 +197,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/GridBroadphase.html b/docs/GridBroadphase.html index 493cbec7..100799f6 100644 --- a/docs/GridBroadphase.html +++ b/docs/GridBroadphase.html @@ -1201,13 +1201,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Group.html b/docs/Group.html index f80a5b7c..00d1aff8 100644 --- a/docs/Group.html +++ b/docs/Group.html @@ -718,6 +718,144 @@
Parameters:
+ + + + + + +

fromJson(renderer)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
renderer + + +Renderer + + + +
+ + + + + + +
+ + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -826,7 +964,7 @@
Parameters:
Source:
@@ -1191,6 +1329,100 @@
Parameters:
+ + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

toJson() → {*}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + +
Inherited From:
+
@@ -1214,7 +1446,7 @@
Parameters:
Source:
@@ -1239,6 +1471,24 @@
Parameters:
+
Returns:
+ + + + +
+
+ Type +
+
+ +* + + +
+
+ + @@ -1260,13 +1510,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/IndexedList.html b/docs/IndexedList.html new file mode 100644 index 00000000..108527d0 --- /dev/null +++ b/docs/IndexedList.html @@ -0,0 +1,793 @@ + + + + + JSDoc: Class: IndexedList + + + + + + + + + +
+ +

Class: IndexedList

+ + + + + + +
+ +
+ +

IndexedList()

+ + +
+ +
+
+ + + + + + +

new IndexedList()

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

get(name)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
name + + +string + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

keys() → {Array.<string>}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Array.<string> + + +
+
+ + + + + + + + + + + + + +

remove(name)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
name + + +string + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

set(name, value)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
name + + +string + + + +
value + + +T + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

values() → {Array.<T>}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Array.<T> + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/Input.html b/docs/Input.html index 63288357..a3cae653 100644 --- a/docs/Input.html +++ b/docs/Input.html @@ -668,13 +668,13 @@

update
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Keyboard.html b/docs/Keyboard.html index fc202b02..fb3103d1 100644 --- a/docs/Keyboard.html +++ b/docs/Keyboard.html @@ -425,13 +425,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Line_Line.html b/docs/Line_Line.html index 81db74be..539d6833 100644 --- a/docs/Line_Line.html +++ b/docs/Line_Line.html @@ -25,7 +25,7 @@

Class: Line

-

Line(length, offset, pffsetAngle)

+

Line(length, offset, offsetAngle)

@@ -38,7 +38,7 @@

Linenew Line(length, offset, pffsetAngle)

+

new Line(length, offset, offsetAngle)

@@ -124,7 +124,7 @@
Parameters:
- pffsetAngle + offsetAngle @@ -243,13 +243,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Loader_Loader.html b/docs/Loader_Loader.html new file mode 100644 index 00000000..c46364e1 --- /dev/null +++ b/docs/Loader_Loader.html @@ -0,0 +1,212 @@ + + + + + JSDoc: Class: Loader + + + + + + + + + +
+ +

Class: Loader

+ + + + + + +
+ +
+ +

Loader(manager)

+ + +
+ +
+
+ + + + + + +

new Loader(manager)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
manager + + +Manager + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/Manager.html b/docs/Manager.html index 8de57310..ef6f98b4 100644 --- a/docs/Manager.html +++ b/docs/Manager.html @@ -363,7 +363,7 @@
Type:
-

(readonly) loader :Loader

+

(readonly) loader :Loader

@@ -378,7 +378,7 @@
Type:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

toJson() → {*}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + +
Inherited From:
+
@@ -1437,7 +1669,7 @@
Parameters:
Source:
@@ -1462,6 +1694,24 @@
Parameters:
+
Returns:
+ + + + +
+
+ Type +
+
+ +* + + +
+
+ + @@ -1483,13 +1733,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/PathFollowing.html b/docs/PathFollowing.html index 0f104f0b..2859c908 100644 --- a/docs/PathFollowing.html +++ b/docs/PathFollowing.html @@ -1567,13 +1567,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Pool.html b/docs/Pool.html index 17df41fd..c5beffe4 100644 --- a/docs/Pool.html +++ b/docs/Pool.html @@ -200,7 +200,7 @@

Members

-

_pool :Array.<any>

+

_pool :Array.<T>

@@ -215,7 +215,7 @@
Type:
  • -Array.<any> +Array.<T>
  • @@ -272,7 +272,7 @@
    Type:
    -

    size

    +

    size :number

    @@ -283,6 +283,16 @@

    sizenumber + + + +

+ @@ -316,7 +326,7 @@

sizeSource:
@@ -396,7 +406,7 @@

(protected) cre
Source:
@@ -425,7 +435,7 @@

Returns:
- object + T
@@ -492,7 +502,7 @@
Parameters:
-Object +T @@ -543,7 +553,7 @@
Parameters:
Source:
@@ -579,7 +589,7 @@
Parameters:
-

give()

+

give() → {T}

@@ -631,7 +641,7 @@

giveSource:
@@ -659,11 +669,19 @@

give - Object - +
+
+ Type +
+
+ +T + + +
+
@@ -727,7 +745,7 @@
Parameters:
-Object +T @@ -778,7 +796,7 @@
Parameters:
Source:
@@ -824,13 +842,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Pursuit.html b/docs/Pursuit.html index 29a2fdb5..d61795b3 100644 --- a/docs/Pursuit.html +++ b/docs/Pursuit.html @@ -1012,13 +1012,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/QuadTreeBroadphase.html b/docs/QuadTreeBroadphase.html index f10244e3..ce6dd413 100644 --- a/docs/QuadTreeBroadphase.html +++ b/docs/QuadTreeBroadphase.html @@ -1011,7 +1011,7 @@
Returns:
-

recalculateBounds()

+

recalculateBounds(bounds)

@@ -1055,7 +1055,7 @@
Parameters:
- bounds. + bounds @@ -1112,7 +1112,7 @@
Parameters:
Source:
@@ -1340,7 +1340,7 @@
Parameters:
-function +Traverser @@ -1391,7 +1391,7 @@
Parameters:
Source:
@@ -1579,13 +1579,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/RayCollisionResult_RayCollisionResult.html b/docs/RayCollisionResult_RayCollisionResult.html new file mode 100644 index 00000000..ff6010bc --- /dev/null +++ b/docs/RayCollisionResult_RayCollisionResult.html @@ -0,0 +1,235 @@ + + + + + JSDoc: Class: RayCollisionResult + + + + + + + + + +
+ +

Class: RayCollisionResult

+ + + + + + +
+ +
+ +

RayCollisionResult(ray, object)

+ + +
+ +
+
+ + + + + + +

new RayCollisionResult(ray, object)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ray + + +Ray + + + +
object + + +Body + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/RayPoint_RayPoint.html b/docs/RayPoint_RayPoint.html new file mode 100644 index 00000000..6743e0c0 --- /dev/null +++ b/docs/RayPoint_RayPoint.html @@ -0,0 +1,235 @@ + + + + + JSDoc: Class: RayPoint + + + + + + + + + +
+ +

Class: RayPoint

+ + + + + + +
+ +
+ +

RayPoint(point, distance)

+ + +
+ +
+
+ + + + + + +

new RayPoint(point, distance)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
point + + +Vector2 + + + +
distance + + +number + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/Ray_Ray.html b/docs/Ray_Ray.html new file mode 100644 index 00000000..de768f27 --- /dev/null +++ b/docs/Ray_Ray.html @@ -0,0 +1,235 @@ + + + + + JSDoc: Class: Ray + + + + + + + + + +
+ +

Class: Ray

+ + + + + + +
+ +
+ +

Ray(origin, direction)

+ + +
+ +
+
+ + + + + + +

new Ray(origin, direction)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
origin + + +Vector2 + + + +
direction + + +Vector2 + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/Rectangle_Rectangle.html b/docs/Rectangle_Rectangle.html index bf246bf3..4ac392a9 100644 --- a/docs/Rectangle_Rectangle.html +++ b/docs/Rectangle_Rectangle.html @@ -266,13 +266,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Renderer.html b/docs/Renderer.html index fedfb559..0cdd016b 100644 --- a/docs/Renderer.html +++ b/docs/Renderer.html @@ -168,7 +168,7 @@
Parameters:
Source:
@@ -286,7 +286,7 @@
Type:
Source:
@@ -354,7 +354,7 @@
Type:
Source:
@@ -428,7 +428,7 @@
Type:
Source:
@@ -500,7 +500,7 @@
Type:
Source:
@@ -572,7 +572,7 @@
Type:
Source:
@@ -634,7 +634,7 @@

perfSource:
@@ -706,7 +706,7 @@
Type:
Source:
@@ -786,7 +786,7 @@

(protected) RAFSource:
@@ -926,7 +926,7 @@
Parameters:
Source:
@@ -1098,7 +1098,7 @@
Parameters:
Source:
@@ -1186,7 +1186,7 @@

clearSource:
@@ -1323,7 +1323,7 @@
Parameters:
Source:
@@ -1411,7 +1411,7 @@

pauseSource:
@@ -1499,7 +1499,7 @@

playSource:
@@ -1636,7 +1636,7 @@
Parameters:
Source:
@@ -1724,7 +1724,7 @@

requ
Source:
@@ -1884,7 +1884,7 @@

Parameters:
Source:
@@ -2021,7 +2021,7 @@
Parameters:
Source:
@@ -2067,13 +2067,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Renderer2D.html b/docs/Renderer2D.html index e0f5c23d..c2fa5844 100644 --- a/docs/Renderer2D.html +++ b/docs/Renderer2D.html @@ -274,7 +274,7 @@
Type:
Source:
@@ -347,7 +347,7 @@
Type:
Source:
@@ -426,7 +426,7 @@
Type:
Source:
@@ -503,7 +503,7 @@
Type:
Source:
@@ -580,7 +580,7 @@
Type:
Source:
@@ -647,7 +647,7 @@

perfSource:
@@ -724,7 +724,7 @@
Type:
Source:
@@ -809,7 +809,7 @@

(protected) RAFSource:
@@ -954,7 +954,7 @@
Parameters:
Source:
@@ -1264,7 +1264,7 @@
Parameters:
Source:
@@ -1357,7 +1357,7 @@

clearSource:
@@ -1499,7 +1499,7 @@
Parameters:
Source:
@@ -1592,7 +1592,7 @@

pauseSource:
@@ -1685,7 +1685,7 @@

playSource:
@@ -1827,7 +1827,7 @@
Parameters:
Source:
@@ -1920,7 +1920,7 @@

requ
Source:
@@ -2085,7 +2085,7 @@

Parameters:
Source:
@@ -2269,13 +2269,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/RungeKuttaSolver.html b/docs/RungeKuttaSolver.html index a9a83006..1e679973 100644 --- a/docs/RungeKuttaSolver.html +++ b/docs/RungeKuttaSolver.html @@ -312,13 +312,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/SATNarrowPhase.html b/docs/SATNarrowPhase.html index e96fc3d8..aabd3da7 100644 --- a/docs/SATNarrowPhase.html +++ b/docs/SATNarrowPhase.html @@ -231,7 +231,7 @@
Parameters:
-Array.<Manifold> +Array.<Manifold> @@ -344,13 +344,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/SeekBehaviour.html b/docs/SeekBehaviour.html index 05f94041..b2c1eb88 100644 --- a/docs/SeekBehaviour.html +++ b/docs/SeekBehaviour.html @@ -1201,13 +1201,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Sfx.html b/docs/Sfx.html index 126a9a61..3ae8f98d 100644 --- a/docs/Sfx.html +++ b/docs/Sfx.html @@ -273,7 +273,7 @@
Type:
Source:
@@ -345,7 +345,7 @@
Type:
Source:
@@ -417,7 +417,7 @@
Type:
Source:
@@ -435,7 +435,7 @@
Type:
-

onended

+

onended :function

@@ -446,6 +446,16 @@

onendedType:

+
    +
  • + +function + + +
  • +
+ @@ -479,7 +489,7 @@

onendedSource:
@@ -608,7 +618,7 @@
Parameters:
Source:
@@ -696,7 +706,7 @@

disconnect<
Source:
@@ -784,7 +794,7 @@

pauseSource:
@@ -872,7 +882,7 @@

playSource:
@@ -960,7 +970,7 @@

resumeSource:
@@ -1006,13 +1016,13 @@

resume
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Shape.html b/docs/Shape.html index 35f270ad..38f56329 100644 --- a/docs/Shape.html +++ b/docs/Shape.html @@ -1548,13 +1548,13 @@
Returns:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Signal.html b/docs/Signal.html new file mode 100644 index 00000000..6967bbbc --- /dev/null +++ b/docs/Signal.html @@ -0,0 +1,664 @@ + + + + + JSDoc: Class: Signal + + + + + + + + + +
+ +

Class: Signal

+ + + + + + +
+ +
+ +

Signal(value)

+ + +
+ +
+
+ + + + + + +

new Signal(value)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +T + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +

Classes

+ +
+
Signal
+
+
+ + + + + + + + + +

Members

+ + + +

_value :T

+ + + + + + +
Type:
+
    +
  • + +T + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

value :T

+ + + + + + +
Type:
+
    +
  • + +T + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

addListener(listener, callOnce)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
listener + + +signalListener + + + + + +
callOnce + + +boolean + + + + + + false + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

removeListener(listener)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
listener + + +signalListener + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/SpringConstraint.html b/docs/SpringConstraint.html index 9b81a969..c01115cc 100644 --- a/docs/SpringConstraint.html +++ b/docs/SpringConstraint.html @@ -460,13 +460,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Sprite.html b/docs/Sprite.html index ac7267b0..6ad2bfe8 100644 --- a/docs/Sprite.html +++ b/docs/Sprite.html @@ -27,7 +27,7 @@

Class: Sprite

Sprite(geometry, material)

-
This is the base class used to render images and paths onto the renderer. Extend it to create your custom behaviour.
+
This is the base class used to render images and paths onto the renderer. Extend it to create your custom behaviour. TODO - ADD id property to this class and Group class.
@@ -146,13 +146,6 @@
Parameters:
-
Implements:
-
    - -
  • Component TODO - ADD id property to this class and Group class.
  • - -
- @@ -169,7 +162,7 @@
Parameters:
Source:
@@ -423,7 +416,7 @@
Type:
Source:
@@ -517,6 +510,139 @@
Type:

Methods

+ + + + + + +

fromJson(renderer)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
renderer + + +Renderer + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -620,7 +746,7 @@
Parameters:
Source:
@@ -650,6 +776,264 @@
Parameters:
+ + + + + + +

render(ctx, dt)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +CanvasRenderingContext2D + + + +
dt + + +number + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

toJson() → {*}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +* + + +
+
+ + + + + + + @@ -666,13 +1050,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/SpriteMaterial.html b/docs/SpriteMaterial.html index 05e743ef..3120dcff 100644 --- a/docs/SpriteMaterial.html +++ b/docs/SpriteMaterial.html @@ -419,7 +419,7 @@
Type:
Source:
@@ -505,13 +505,13 @@
Type:
-

width :number

+

width :Vector

- The width of the sprite. + /**The width of the sprite.
@@ -520,7 +520,7 @@
Type:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(static) implement(system)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
system + + +any + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -650,13 +821,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/TextMaterial.html b/docs/TextMaterial.html new file mode 100644 index 00000000..02ab0073 --- /dev/null +++ b/docs/TextMaterial.html @@ -0,0 +1,704 @@ + + + + + JSDoc: Class: TextMaterial + + + + + + + + + +
+ +

Class: TextMaterial

+ + + + + + +
+ +
+ +

TextMaterial(text)

+ +
Material for rendering text.
+ + +
+ +
+
+ + + + +

Constructor

+ + + +

new TextMaterial(text)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
text + + +String + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +

Classes

+ +
+
TextMaterial
+
+
+ + + + + + + + + +

Members

+ + + +

center :boolean

+ + + + + + +
Type:
+
    +
  • + +boolean + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

color :String

+ + + + + + +
Type:
+
    +
  • + +String + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

fill :boolean

+ + + + + + +
Type:
+
    +
  • + +boolean + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

font :String

+ + + + + + +
Type:
+
    +
  • + +String + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

text :String

+ + + + + + +
Type:
+
    +
  • + +String + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

render(ctx)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +CanvasRenderingContext2D + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/Touch.html b/docs/Touch.html index 67349c27..4c794f02 100644 --- a/docs/Touch.html +++ b/docs/Touch.html @@ -626,13 +626,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Transform.html b/docs/Transform.html index e4520a33..8b91e44e 100644 --- a/docs/Transform.html +++ b/docs/Transform.html @@ -260,13 +260,13 @@

Classes


- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Triangle.html b/docs/Triangle.html index c032a804..75f36f26 100644 --- a/docs/Triangle.html +++ b/docs/Triangle.html @@ -1497,6 +1497,208 @@
Parameters:
+ + + + + + +

(static) calcInertia(mass, base, height, angle)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
mass + + +number + + + +
base + + +number + + + +
height + + +number + + + +
angle + + +number + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -1513,13 +1715,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Trigon_Trigon.html b/docs/Trigon_Trigon.html index d141afcc..997f8a51 100644 --- a/docs/Trigon_Trigon.html +++ b/docs/Trigon_Trigon.html @@ -243,13 +243,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Tween.html b/docs/Tween.html index bfc67561..309a63db 100644 --- a/docs/Tween.html +++ b/docs/Tween.html @@ -25,7 +25,7 @@

Class: Tween

-

Tween(to, from, duration)

+

Tween(into)

Component responsible for animations.
@@ -42,7 +42,7 @@

Constructor

-

new Tween(to, from, duration)

+

new Tween(into)

@@ -82,7 +82,7 @@
Parameters:
- to + into @@ -102,10 +102,754 @@
Parameters:
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Classes

+ +
+
Tween
+
+
+ + + + + + + + + +

Members

+ + + +

_duration :number

+ + + + + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

_repeat :boolean

+ + + + + + +
Type:
+
    +
  • + +boolean + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

active :boolean

+ + + + + + +
Type:
+
    +
  • + +boolean + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

chain(next)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
next + + +Tween + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

duration(t)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
t + + +T + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

easing(callback)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
callback + + +EasingFunc + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

from(x)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + - + + +
NameTypeDescription
fromx @@ -125,16 +869,126 @@
Parameters:
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

init(entity)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
durationentity -number +Entity @@ -185,7 +1039,7 @@
Parameters:
Source:
@@ -215,49 +1069,75 @@
Parameters:
- - + + - +

interpolant(callback)

-

Classes

-
-
Tween
-
-
- - - + + + + + + + +
Parameters:
-

Members

+ + + + + + + + + - -

_to :T

+ + + + + + + + + + + + + -
Type:
-
    -
  • -T + + +
+ + + + +
NameTypeDescription
callback + + +LerpFunc + +
- - @@ -292,7 +1172,7 @@
Type:
Source:
@@ -308,11 +1188,19 @@
Type:
- - - -

Methods

+ + + + + + + + + + + + @@ -320,7 +1208,7 @@

Methods

-

duration(t)

+

onUpdate(callback)

@@ -360,13 +1248,13 @@
Parameters:
tcallback -T +TweenUpdate @@ -417,7 +1305,7 @@
Parameters:
Source:
@@ -453,7 +1341,7 @@
Parameters:
-

from(x)

+

to(x)

@@ -550,7 +1438,7 @@
Parameters:
Source:
@@ -586,7 +1474,7 @@
Parameters:
-

to(x)

+

update(dt)

@@ -626,13 +1514,13 @@
Parameters:
xdt -T +number @@ -683,7 +1571,7 @@
Parameters:
Source:
@@ -729,13 +1617,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Vec2_Vec2.html b/docs/Vec2_Vec2.html new file mode 100644 index 00000000..16befd18 --- /dev/null +++ b/docs/Vec2_Vec2.html @@ -0,0 +1,235 @@ + + + + + JSDoc: Class: Vec2 + + + + + + + + + +
+ +

Class: Vec2

+ + + + + + +
+ +
+ +

Vec2(x, y)

+ + +
+ +
+
+ + + + + + +

new Vec2(x, y)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
x + + +number + + + + the x coordinate of the vector
y + + +number + + + + the y coordinate of the vector
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/Vector2.html b/docs/Vector2.html index d6dd1770..570aa423 100644 --- a/docs/Vector2.html +++ b/docs/Vector2.html @@ -165,7 +165,7 @@
Parameters:
Source:
@@ -272,7 +272,7 @@
Type:
Source:
@@ -340,7 +340,7 @@
Type:
Source:
@@ -412,7 +412,7 @@
Type:
Source:
@@ -541,7 +541,7 @@
Parameters:
Source:
@@ -696,7 +696,7 @@
Parameters:
Source:
@@ -910,7 +910,7 @@
Parameters:
Source:
@@ -1016,7 +1016,7 @@

cloneSource:
@@ -1114,7 +1114,7 @@

copySource:
@@ -1261,7 +1261,7 @@
Parameters:
Source:
@@ -1416,7 +1416,7 @@
Parameters:
Source:
@@ -1553,7 +1553,7 @@
Parameters:
Source:
@@ -1708,7 +1708,7 @@
Parameters:
Source:
@@ -1863,7 +1863,7 @@
Parameters:
Source:
@@ -2140,7 +2140,7 @@
Parameters:
Source:
@@ -2295,7 +2295,7 @@
Parameters:
Source:
@@ -2401,7 +2401,7 @@

equalsZero<
Source:
@@ -2507,7 +2507,7 @@

magnitudeSource:
@@ -2613,7 +2613,7 @@

magni
Source:
@@ -2750,7 +2750,7 @@

Parameters:
Source:
@@ -2962,7 +2962,7 @@
Parameters:
Source:
@@ -3137,7 +3137,7 @@
Parameters:
Source:
@@ -3243,7 +3243,7 @@

normalizeSource:
@@ -3441,7 +3441,7 @@
Parameters:
Source:
@@ -3547,7 +3547,7 @@

reverseSource:
@@ -3702,7 +3702,7 @@
Parameters:
Source:
@@ -3880,7 +3880,7 @@
Parameters:
Source:
@@ -4035,7 +4035,7 @@
Parameters:
Source:
@@ -4172,7 +4172,7 @@
Parameters:
Source:
@@ -4327,7 +4327,7 @@
Parameters:
Source:
@@ -4502,7 +4502,7 @@
Parameters:
Source:
@@ -4692,7 +4692,7 @@
Parameters:
Source:
@@ -4890,7 +4890,7 @@
Parameters:
Source:
@@ -5068,7 +5068,7 @@
Parameters:
Source:
@@ -5246,7 +5246,7 @@
Parameters:
Source:
@@ -5424,7 +5424,7 @@
Parameters:
Source:
@@ -5602,7 +5602,7 @@
Parameters:
Source:
@@ -5862,7 +5862,7 @@
Parameters:
Source:
@@ -6029,7 +6029,7 @@
Parameters:
Source:
@@ -6184,7 +6184,7 @@
Parameters:
Source:
@@ -6339,7 +6339,7 @@
Parameters:
Source:
@@ -6403,13 +6403,13 @@
Returns:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/VectorPool.html b/docs/VectorPool.html index 083f2602..7f9e33e2 100644 --- a/docs/VectorPool.html +++ b/docs/VectorPool.html @@ -334,13 +334,13 @@

destroy
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Vector_Vector.html b/docs/Vector_Vector.html new file mode 100644 index 00000000..95b69d83 --- /dev/null +++ b/docs/Vector_Vector.html @@ -0,0 +1,235 @@ + + + + + JSDoc: Class: Vector + + + + + + + + + +
+ +

Class: Vector

+ + + + + + +
+ +
+ +

Vector(x, y)

+ + +
+ +
+
+ + + + + + +

new Vector(x, y)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
x + + +number + + + + the x coordinate of the vector
y + + +number + + + + the y coordinate of the vector
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/VerletSolver.html b/docs/VerletSolver.html index 8bf4d0f6..a5dcc7c0 100644 --- a/docs/VerletSolver.html +++ b/docs/VerletSolver.html @@ -312,13 +312,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/WanderBehaviour.html b/docs/WanderBehaviour.html index 7ab087a9..2a334634 100644 --- a/docs/WanderBehaviour.html +++ b/docs/WanderBehaviour.html @@ -1218,13 +1218,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/WebGLRenderer.html b/docs/WebGLRenderer.html index 42bd0e1b..c430c9ef 100644 --- a/docs/WebGLRenderer.html +++ b/docs/WebGLRenderer.html @@ -213,7 +213,7 @@
Type:
Source:
@@ -286,7 +286,7 @@
Type:
Source:
@@ -365,7 +365,7 @@
Type:
Source:
@@ -442,7 +442,7 @@
Type:
Source:
@@ -519,7 +519,7 @@
Type:
Source:
@@ -586,7 +586,7 @@

perfSource:
@@ -663,7 +663,7 @@
Type:
Source:
@@ -748,7 +748,7 @@

(protected) RAFSource:
@@ -893,7 +893,7 @@
Parameters:
Source:
@@ -1070,7 +1070,7 @@
Parameters:
Source:
@@ -1163,7 +1163,7 @@

clearSource:
@@ -1305,7 +1305,7 @@
Parameters:
Source:
@@ -1398,7 +1398,7 @@

pauseSource:
@@ -1491,7 +1491,7 @@

playSource:
@@ -1633,7 +1633,7 @@
Parameters:
Source:
@@ -1726,7 +1726,7 @@

requ
Source:
@@ -1891,7 +1891,7 @@

Parameters:
Source:
@@ -2033,7 +2033,7 @@
Parameters:
Source:
@@ -2079,13 +2079,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/WebGPURenderer.html b/docs/WebGPURenderer.html index 560b87c1..c369a5e1 100644 --- a/docs/WebGPURenderer.html +++ b/docs/WebGPURenderer.html @@ -213,7 +213,7 @@
Type:
Source:
@@ -286,7 +286,7 @@
Type:
Source:
@@ -365,7 +365,7 @@
Type:
Source:
@@ -442,7 +442,7 @@
Type:
Source:
@@ -519,7 +519,7 @@
Type:
Source:
@@ -586,7 +586,7 @@

perfSource:
@@ -663,7 +663,7 @@
Type:
Source:
@@ -748,7 +748,7 @@

(protected) RAFSource:
@@ -893,7 +893,7 @@
Parameters:
Source:
@@ -1070,7 +1070,7 @@
Parameters:
Source:
@@ -1163,7 +1163,7 @@

clearSource:
@@ -1305,7 +1305,7 @@
Parameters:
Source:
@@ -1398,7 +1398,7 @@

pauseSource:
@@ -1491,7 +1491,7 @@

playSource:
@@ -1633,7 +1633,7 @@
Parameters:
Source:
@@ -1726,7 +1726,7 @@

requ
Source:
@@ -1891,7 +1891,7 @@

Parameters:
Source:
@@ -2033,7 +2033,7 @@
Parameters:
Source:
@@ -2079,13 +2079,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/World.html b/docs/World.html index d9ea22a4..d29326b7 100644 --- a/docs/World.html +++ b/docs/World.html @@ -147,7 +147,7 @@

Members

-

CLMDs :Array.<Manifold>

+

CLMDs :Array.<Manifold>

@@ -162,7 +162,7 @@
Type:

-Loader +Loader @@ -1487,13 +1487,13 @@

unmute
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Ball.html b/docs/Ball.html index 2b0f7dad..dc92e78c 100644 --- a/docs/Ball.html +++ b/docs/Ball.html @@ -412,7 +412,7 @@
Type:
Source:
@@ -489,7 +489,7 @@
Type:
Source:
@@ -566,7 +566,7 @@
Type:
Source:
@@ -3186,6 +3186,95 @@
Type:

Methods

+ + + + + + +

addShape()

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -3353,7 +3442,204 @@
Parameters:
Source:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

applyImpulse(impulse, armopt)

+ + + + + + +
+ Applies a force to a body affecting its direction of travel and rotation. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
impulse + + +Vector2 + + + + + + + + + + + + The force to be applied.
arm + + +Vector2 + + + + + + <optional>
+ + + + + +
+ + Vector2 + + The collision arm.
+ + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -3927,7 +4213,7 @@
Parameters:
Source:
@@ -4180,7 +4466,7 @@

updateSource:
@@ -4226,13 +4512,13 @@

update
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/BasicMaterial.html b/docs/BasicMaterial.html index 9d6a3715..9f5b5b81 100644 --- a/docs/BasicMaterial.html +++ b/docs/BasicMaterial.html @@ -568,13 +568,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Behaviour.html b/docs/Behaviour.html index 48ff2ce0..dd280c18 100644 --- a/docs/Behaviour.html +++ b/docs/Behaviour.html @@ -954,13 +954,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/BehaviourManager.html b/docs/BehaviourManager.html index a4f5408b..452ebd99 100644 --- a/docs/BehaviourManager.html +++ b/docs/BehaviourManager.html @@ -930,13 +930,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Body.html b/docs/Body.html index 91ad33bd..a5ede60a 100644 --- a/docs/Body.html +++ b/docs/Body.html @@ -398,7 +398,7 @@
Type:
Source:
@@ -470,7 +470,7 @@
Type:
Source:
@@ -542,7 +542,7 @@
Type:
Source:
@@ -2997,6 +2997,90 @@
Type:

Methods

+ + + + + + +

addShape()

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -3159,7 +3243,199 @@
Parameters:
Source:
+ + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

applyImpulse(impulse, armopt)

+ + + + + + +
+ Applies a force to a body affecting its direction of travel and rotation. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
impulse + + +Vector2 + + + + + + + + + + + + The force to be applied.
arm + + +Vector2 + + + + + + <optional>
+ + + + + +
+ + Vector2 + + The collision arm.
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -3718,7 +3994,7 @@
Parameters:
Source:
@@ -3961,7 +4237,7 @@

updateSource:
@@ -4007,13 +4283,13 @@

update
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/BodySprite.html b/docs/BodySprite.html index f55f5cf3..c918faa5 100644 --- a/docs/BodySprite.html +++ b/docs/BodySprite.html @@ -756,7 +756,7 @@
Type:
Source:
@@ -855,6 +855,144 @@
Type:

Methods

+ + + + + + +

fromJson(renderer)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
renderer + + +Renderer + + + +
+ + + + + + +
+ + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -963,7 +1101,7 @@
Parameters:
Source:
@@ -1096,6 +1234,100 @@
Parameters:
+ + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

toJson() → {*}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + +
Inherited From:
+
@@ -1119,7 +1351,7 @@
Parameters:
Source:
@@ -1144,6 +1376,24 @@
Parameters:
+
Returns:
+ + + + +
+
+ Type +
+
+ +* + + +
+
+ + @@ -1165,13 +1415,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Bound.html b/docs/Bound.html index f45a3326..0e8173a7 100644 --- a/docs/Bound.html +++ b/docs/Bound.html @@ -231,13 +231,13 @@
Type:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/BoundingBox.html b/docs/BoundingBox.html index 3e5fc938..e5a6bcb9 100644 --- a/docs/BoundingBox.html +++ b/docs/BoundingBox.html @@ -276,7 +276,7 @@
Parameters:
Source:
@@ -387,7 +387,7 @@
Type:
Source:
@@ -459,7 +459,7 @@
Type:
Source:
@@ -527,7 +527,7 @@
Type:
Source:
@@ -691,7 +691,7 @@
Parameters:
Source:
@@ -779,7 +779,7 @@

cloneSource:
@@ -926,7 +926,7 @@
Parameters:
Source:
@@ -1066,7 +1066,7 @@
Parameters:
Source:
@@ -1213,7 +1213,7 @@
Parameters:
Source:
@@ -1396,7 +1396,7 @@
Parameters:
Source:
@@ -1452,13 +1452,13 @@
Returns:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/BoundingCircle.html b/docs/BoundingCircle.html index 57de098c..b3922e58 100644 --- a/docs/BoundingCircle.html +++ b/docs/BoundingCircle.html @@ -159,7 +159,7 @@
Parameters:
Source:
@@ -266,7 +266,7 @@
Type:
Source:
@@ -334,7 +334,7 @@
Type:
Source:
@@ -463,7 +463,7 @@
Parameters:
Source:
@@ -603,7 +603,7 @@
Parameters:
Source:
@@ -740,7 +740,7 @@
Parameters:
Source:
@@ -786,13 +786,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Box.html b/docs/Box.html index 1f7a1912..27308c6f 100644 --- a/docs/Box.html +++ b/docs/Box.html @@ -435,7 +435,7 @@
Type:
Source:
@@ -512,7 +512,7 @@
Type:
Source:
@@ -589,7 +589,7 @@
Type:
Source:
@@ -3209,6 +3209,95 @@
Type:

Methods

+ + + + + + +

addShape()

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -3376,7 +3465,204 @@
Parameters:
Source:
+ + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

applyImpulse(impulse, armopt)

+ + + + + + +
+ Applies a force to a body affecting its direction of travel and rotation. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
impulse + + +Vector2 + + + + + + + + + + + + The force to be applied.
arm + + +Vector2 + + + + + + <optional>
+ + + + + +
+ + Vector2 + + The collision arm.
+ + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -3950,7 +4236,7 @@
Parameters:
Source:
@@ -4203,7 +4489,7 @@

updateSource:
@@ -4249,13 +4535,13 @@

update
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Broadphase.html b/docs/Broadphase.html index ba82282f..62621b5d 100644 --- a/docs/Broadphase.html +++ b/docs/Broadphase.html @@ -1159,13 +1159,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/BufferGeometry_BufferGeometry.html b/docs/BufferGeometry_BufferGeometry.html index 3dd4956c..53653f40 100644 --- a/docs/BufferGeometry_BufferGeometry.html +++ b/docs/BufferGeometry_BufferGeometry.html @@ -197,13 +197,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/CamController_CamController.html b/docs/CamController_CamController.html index dda7cb50..4c409f12 100644 --- a/docs/CamController_CamController.html +++ b/docs/CamController_CamController.html @@ -135,7 +135,7 @@
Parameters:
Source:
@@ -197,13 +197,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Circle.html b/docs/Circle.html index ba7fab3e..70090e23 100644 --- a/docs/Circle.html +++ b/docs/Circle.html @@ -1611,13 +1611,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/CircleGeometry_CircleGeometry.html b/docs/CircleGeometry_CircleGeometry.html index 5d3f3f57..88af91ac 100644 --- a/docs/CircleGeometry_CircleGeometry.html +++ b/docs/CircleGeometry_CircleGeometry.html @@ -197,13 +197,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Clock.html b/docs/Clock.html index 759a720d..1ae608ec 100644 --- a/docs/Clock.html +++ b/docs/Clock.html @@ -369,13 +369,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Color.html b/docs/Color.html new file mode 100644 index 00000000..895bb08d --- /dev/null +++ b/docs/Color.html @@ -0,0 +1,1797 @@ + + + + + JSDoc: Class: Color + + + + + + + + + +
+ +

Class: Color

+ + + + + + +
+ +
+ +

Color(ropt, gopt, bopt, alphaopt)

+ +
A color manipulation class.
+ + +
+ +
+
+ + + + +

Constructor

+ + + +

new Color(ropt, gopt, bopt, alphaopt)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
r + + +number + + + + + + <optional>
+ + + + + +
+ + 0 + + red component [0 .. 255]
g + + +number + + + + + + <optional>
+ + + + + +
+ + 0 + + green component [0 .. 255]
b + + +number + + + + + + <optional>
+ + + + + +
+ + 0 + + blue component [0 .. 255]
alpha + + +number + + + + + + <optional>
+ + + + + +
+ + 1.0 + + alpha value [0.0 .. 1.0]
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +

Classes

+ +
+
Color
+
+
+ + + + + + + + + + + +

Methods

+ + + + + + + +

add(color) → {Color}

+ + + + + + +
+ Blend this color with the given one using addition. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
color + + +Color + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to this object for method chaining +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +

clone() → {Color}

+ + + + + + +
+ Create a new copy of this color object. +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to the newly cloned object +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +

copy(color) → {Color}

+ + + + + + +
+ Copy a color object or CSS color into this one. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
color + + +Color +| + +string + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to this object for method chaining +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +

darken(scale) → {Color}

+ + + + + + +
+ Darken this color value by 0..1 +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
scale + + +number + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to this object for method chaining +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +

lerp(color, alpha) → {Color}

+ + + + + + +
+ Linearly interpolate between this color and the given one. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
color + + +Color + + + +
alpha + + +number + + + + with alpha = 0 being this color, and alpha = 1 being the given one.
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to this object for method chaining +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +

lighten(scale) → {Color}

+ + + + + + +
+ Lighten this color value by 0..1 +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
scale + + +number + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to this object for method chaining +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +

random(minopt, maxopt) → {Color}

+ + + + + + +
+ Generate random r,g,b values for this color object +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
min + + +number + + + + + + <optional>
+ + + + + +
+ + 0 + + minimum value for the random range
max + + +number + + + + + + <optional>
+ + + + + +
+ + 255 + + maxmium value for the random range
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to this object for method chaining +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +

set(r, g, b, alphaopt) → {Color}

+ + + + + + +
+ Set this color to the specified value. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
r + + +number + + + + + + + + + + + + red component [0 .. 255]
g + + +number + + + + + + + + + + + + green component [0 .. 255]
b + + +number + + + + + + + + + + + + blue component [0 .. 255]
alpha + + +number + + + + + + <optional>
+ + + + + +
+ + 1.0 + + alpha value [0.0 .. 1.0]
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Reference to this object for method chaining +
+ + + +
+
+ Type +
+
+ +Color + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/Component.html b/docs/Component.html index 70b87e0f..05c6cc14 100644 --- a/docs/Component.html +++ b/docs/Component.html @@ -248,7 +248,7 @@

Methods

-

get(n)

+

fromJson(obj, system)

@@ -286,6 +286,185 @@
Parameters:

obj + + +* + + + +
system + + +T + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

get(entity, n)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -345,7 +524,7 @@
Parameters:
Source:
@@ -514,7 +693,7 @@
Parameters:
-

query(bound, targetopt)

+

query(entity, bound, targetopt) → {Array.<Entity>}

@@ -556,6 +735,41 @@
Parameters:
+ + + + + + + + + + + + + + + + + + + + @@ -602,7 +816,7 @@
Parameters:
+ + + + + + + + + + + + + + + + + + @@ -814,7 +1077,91 @@
Parameters:
Source:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

toJson() → {*}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -839,6 +1186,24 @@
Parameters:
+
Returns:
+ + + + +
+
+ Type +
+
+ +* + + +
+
+ + @@ -977,6 +1342,139 @@
Parameters:
+ + + + + + +

(static) implement(component)

+ + + + + + + + + + + + + + +
Parameters:
+ + +
NameTypeDescription
entity + + +Entity + + + +
n
entity + + +Entity + + + + + + + + + + + +
bound -Entity +Array.<Entity> @@ -669,7 +883,7 @@
Parameters:
Source:
@@ -694,6 +908,24 @@
Parameters:
+
Returns:
+ + + + +
+
+ Type +
+
+ +Array.<Entity> + + +
+
+ + @@ -705,7 +937,7 @@
Parameters:
-

requires(…names)

+

requires(entity, …names)

@@ -745,6 +977,37 @@
Parameters:
entity + + +Entity + + + + + + + + + +
names
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
component + + +* + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -993,13 +1491,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Composite.html b/docs/Composite.html index 5e1dc945..91817dcd 100644 --- a/docs/Composite.html +++ b/docs/Composite.html @@ -1414,13 +1414,13 @@

update
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Constraint.html b/docs/Constraint.html index 40b4b364..981205af 100644 --- a/docs/Constraint.html +++ b/docs/Constraint.html @@ -324,7 +324,7 @@
Type:
Source:
@@ -392,7 +392,347 @@
Type:
Source:
+ + + + + + + +

+ + + + + + + + +

body1 :Body

+ + + + + + +
Type:
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

body2 :Body

+ + + + + + +
Type:
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

dampening :number

+ + + + + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

localA :Vector2

+ + + + + + +
Type:
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

localB :Vector2

+ + + + + + +
Type:
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -464,7 +804,79 @@
Type:
Source:
+ + + + + + + +
+ + + + + + + + +

stiffness :number

+ + + + +
+ : +
+ + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -639,7 +1051,7 @@
Parameters:
Source:
@@ -776,7 +1188,7 @@
Parameters:
Source:
@@ -822,13 +1234,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/DOMEventHandler.html b/docs/DOMEventHandler.html index b9c7c92d..34776072 100644 --- a/docs/DOMEventHandler.html +++ b/docs/DOMEventHandler.html @@ -724,13 +724,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/DistanceConstraint.html b/docs/DistanceConstraint.html index b30047f8..4d3064d2 100644 --- a/docs/DistanceConstraint.html +++ b/docs/DistanceConstraint.html @@ -460,13 +460,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Entity.html b/docs/Entity.html index 467a88af..7d397313 100644 --- a/docs/Entity.html +++ b/docs/Entity.html @@ -140,6 +140,142 @@

Members

+

CHAOS_CLASSNAME :string

+ + + + + + +
Type:
+
    +
  • + +string + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

CHAOS_OBJ_TYPE :string

+ + + + + + +
Type:
+
    +
  • + +string + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + +

active :boolean

@@ -256,7 +392,7 @@

managerSource:
@@ -385,7 +521,7 @@
Parameters:
Source:
@@ -545,7 +681,7 @@
Parameters:
Source:
@@ -651,7 +787,7 @@

destroySource:
@@ -811,7 +947,7 @@
Parameters:
Source:
@@ -948,7 +1084,7 @@
Parameters:
Source:
@@ -1106,7 +1242,7 @@
Parameters:
Source:
@@ -1264,7 +1400,7 @@
Parameters:
Source:
@@ -1419,7 +1555,7 @@
Parameters:
Source:
@@ -1574,7 +1710,7 @@
Parameters:
Source:
@@ -1766,7 +1902,7 @@
Parameters:
Source:
@@ -1944,7 +2080,7 @@
Parameters:
Source:
@@ -2081,7 +2217,7 @@
Parameters:
Source:
@@ -2169,7 +2305,7 @@

remov
Source:
@@ -2257,7 +2393,7 @@

removeSelf<
Source:
@@ -2394,7 +2530,7 @@

Parameters:
Source:
@@ -2482,91 +2618,7 @@

(package) reset<
Source:
- - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - -

toJson() → {Object}

- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
@@ -2591,24 +2643,6 @@

toJsonReturns:

- - - - -
-
- Type -
-
- -Object - - -
-
- - @@ -2721,7 +2755,7 @@
Parameters:
Source:
@@ -2904,7 +2938,7 @@
Parameters:
Source:
@@ -2968,13 +3002,13 @@
Returns:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/EulerSolver.html b/docs/EulerSolver.html index 985f88ab..b714b0b1 100644 --- a/docs/EulerSolver.html +++ b/docs/EulerSolver.html @@ -90,7 +90,7 @@

new EulerS
Source:
@@ -146,7 +146,7 @@

Methods

-

(static) solve(dt)

+

(static) solve(transform, movable, dt)

@@ -184,6 +184,52 @@
Parameters:
+ + + transform + + + + + +Transform + + + + + + + + + + + + + + + + + movable + + + + + +Movable + + + + + + + + + + + + + + dt @@ -243,7 +289,7 @@
Parameters:
Source:
@@ -570,7 +616,7 @@

Methods

-

(static) solve(dt)

+

(static) solve(transform, movable, dt)

@@ -608,6 +654,52 @@
Parameters:
+ + + transform + + + + + +Transform + + + + + + + + + + + + + + + + + movable + + + + + +Movable + + + + + + + + + + + + + + dt @@ -667,7 +759,7 @@
Parameters:
Source:
@@ -869,13 +961,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/EvadeBehaviour.html b/docs/EvadeBehaviour.html index bb884ddc..74d04b12 100644 --- a/docs/EvadeBehaviour.html +++ b/docs/EvadeBehaviour.html @@ -1133,13 +1133,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/EventDispatcher.html b/docs/EventDispatcher.html index 80d51f78..24dfc4c0 100644 --- a/docs/EventDispatcher.html +++ b/docs/EventDispatcher.html @@ -219,7 +219,7 @@
Parameters:
-function +EventHandlerFunc @@ -564,13 +564,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Flock.html b/docs/Flock.html index 22c3ee70..14462443 100644 --- a/docs/Flock.html +++ b/docs/Flock.html @@ -1080,13 +1080,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Geometry_Geometry.html b/docs/Geometry_Geometry.html index 89d223a3..b376f761 100644 --- a/docs/Geometry_Geometry.html +++ b/docs/Geometry_Geometry.html @@ -197,13 +197,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/GridBroadphase.html b/docs/GridBroadphase.html index 493cbec7..100799f6 100644 --- a/docs/GridBroadphase.html +++ b/docs/GridBroadphase.html @@ -1201,13 +1201,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Group.html b/docs/Group.html index f80a5b7c..00d1aff8 100644 --- a/docs/Group.html +++ b/docs/Group.html @@ -718,6 +718,144 @@
Parameters:
+ + + + + + +

fromJson(renderer)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
renderer + + +Renderer + + + +
+ + + + + + +
+ + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -826,7 +964,7 @@
Parameters:
Source:
@@ -1191,6 +1329,100 @@
Parameters:
+ + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

toJson() → {*}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + +
Inherited From:
+
@@ -1214,7 +1446,7 @@
Parameters:
Source:
@@ -1239,6 +1471,24 @@
Parameters:
+
Returns:
+ + + + +
+
+ Type +
+
+ +* + + +
+
+ + @@ -1260,13 +1510,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/IndexedList.html b/docs/IndexedList.html new file mode 100644 index 00000000..108527d0 --- /dev/null +++ b/docs/IndexedList.html @@ -0,0 +1,793 @@ + + + + + JSDoc: Class: IndexedList + + + + + + + + + +
+ +

Class: IndexedList

+ + + + + + +
+ +
+ +

IndexedList()

+ + +
+ +
+
+ + + + + + +

new IndexedList()

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

get(name)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
name + + +string + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

keys() → {Array.<string>}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Array.<string> + + +
+
+ + + + + + + + + + + + + +

remove(name)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
name + + +string + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

set(name, value)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
name + + +string + + + +
value + + +T + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

values() → {Array.<T>}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Array.<T> + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/Input.html b/docs/Input.html index 63288357..a3cae653 100644 --- a/docs/Input.html +++ b/docs/Input.html @@ -668,13 +668,13 @@

update
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Keyboard.html b/docs/Keyboard.html index fc202b02..fb3103d1 100644 --- a/docs/Keyboard.html +++ b/docs/Keyboard.html @@ -425,13 +425,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Line_Line.html b/docs/Line_Line.html index 81db74be..539d6833 100644 --- a/docs/Line_Line.html +++ b/docs/Line_Line.html @@ -25,7 +25,7 @@

Class: Line

-

Line(length, offset, pffsetAngle)

+

Line(length, offset, offsetAngle)

@@ -38,7 +38,7 @@

Linenew Line(length, offset, pffsetAngle)

+

new Line(length, offset, offsetAngle)

@@ -124,7 +124,7 @@
Parameters:
- pffsetAngle + offsetAngle @@ -243,13 +243,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Loader_Loader.html b/docs/Loader_Loader.html new file mode 100644 index 00000000..c46364e1 --- /dev/null +++ b/docs/Loader_Loader.html @@ -0,0 +1,212 @@ + + + + + JSDoc: Class: Loader + + + + + + + + + +
+ +

Class: Loader

+ + + + + + +
+ +
+ +

Loader(manager)

+ + +
+ +
+
+ + + + + + +

new Loader(manager)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
manager + + +Manager + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/Manager.html b/docs/Manager.html index 8de57310..ef6f98b4 100644 --- a/docs/Manager.html +++ b/docs/Manager.html @@ -363,7 +363,7 @@
Type:
-

(readonly) loader :Loader

+

(readonly) loader :Loader

@@ -378,7 +378,7 @@
Type:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

toJson() → {*}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + +
Inherited From:
+
@@ -1437,7 +1669,7 @@
Parameters:
Source:
@@ -1462,6 +1694,24 @@
Parameters:
+
Returns:
+ + + + +
+
+ Type +
+
+ +* + + +
+
+ + @@ -1483,13 +1733,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/PathFollowing.html b/docs/PathFollowing.html index 0f104f0b..2859c908 100644 --- a/docs/PathFollowing.html +++ b/docs/PathFollowing.html @@ -1567,13 +1567,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Pool.html b/docs/Pool.html index 17df41fd..c5beffe4 100644 --- a/docs/Pool.html +++ b/docs/Pool.html @@ -200,7 +200,7 @@

Members

-

_pool :Array.<any>

+

_pool :Array.<T>

@@ -215,7 +215,7 @@
Type:
  • -Array.<any> +Array.<T>
  • @@ -272,7 +272,7 @@
    Type:
    -

    size

    +

    size :number

    @@ -283,6 +283,16 @@

    sizenumber + + + +

+ @@ -316,7 +326,7 @@

sizeSource:
@@ -396,7 +406,7 @@

(protected) cre
Source:
@@ -425,7 +435,7 @@

Returns:
- object + T
@@ -492,7 +502,7 @@
Parameters:
-Object +T @@ -543,7 +553,7 @@
Parameters:
Source:
@@ -579,7 +589,7 @@
Parameters:
-

give()

+

give() → {T}

@@ -631,7 +641,7 @@

giveSource:
@@ -659,11 +669,19 @@

give - Object - +
+
+ Type +
+
+ +T + + +
+
@@ -727,7 +745,7 @@
Parameters:
-Object +T @@ -778,7 +796,7 @@
Parameters:
Source:
@@ -824,13 +842,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Pursuit.html b/docs/Pursuit.html index 29a2fdb5..d61795b3 100644 --- a/docs/Pursuit.html +++ b/docs/Pursuit.html @@ -1012,13 +1012,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/QuadTreeBroadphase.html b/docs/QuadTreeBroadphase.html index f10244e3..ce6dd413 100644 --- a/docs/QuadTreeBroadphase.html +++ b/docs/QuadTreeBroadphase.html @@ -1011,7 +1011,7 @@
Returns:
-

recalculateBounds()

+

recalculateBounds(bounds)

@@ -1055,7 +1055,7 @@
Parameters:
- bounds. + bounds @@ -1112,7 +1112,7 @@
Parameters:
Source:
@@ -1340,7 +1340,7 @@
Parameters:
-function +Traverser @@ -1391,7 +1391,7 @@
Parameters:
Source:
@@ -1579,13 +1579,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/RayCollisionResult_RayCollisionResult.html b/docs/RayCollisionResult_RayCollisionResult.html new file mode 100644 index 00000000..ff6010bc --- /dev/null +++ b/docs/RayCollisionResult_RayCollisionResult.html @@ -0,0 +1,235 @@ + + + + + JSDoc: Class: RayCollisionResult + + + + + + + + + +
+ +

Class: RayCollisionResult

+ + + + + + +
+ +
+ +

RayCollisionResult(ray, object)

+ + +
+ +
+
+ + + + + + +

new RayCollisionResult(ray, object)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ray + + +Ray + + + +
object + + +Body + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/RayPoint_RayPoint.html b/docs/RayPoint_RayPoint.html new file mode 100644 index 00000000..6743e0c0 --- /dev/null +++ b/docs/RayPoint_RayPoint.html @@ -0,0 +1,235 @@ + + + + + JSDoc: Class: RayPoint + + + + + + + + + +
+ +

Class: RayPoint

+ + + + + + +
+ +
+ +

RayPoint(point, distance)

+ + +
+ +
+
+ + + + + + +

new RayPoint(point, distance)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
point + + +Vector2 + + + +
distance + + +number + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/Ray_Ray.html b/docs/Ray_Ray.html new file mode 100644 index 00000000..de768f27 --- /dev/null +++ b/docs/Ray_Ray.html @@ -0,0 +1,235 @@ + + + + + JSDoc: Class: Ray + + + + + + + + + +
+ +

Class: Ray

+ + + + + + +
+ +
+ +

Ray(origin, direction)

+ + +
+ +
+
+ + + + + + +

new Ray(origin, direction)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
origin + + +Vector2 + + + +
direction + + +Vector2 + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/Rectangle_Rectangle.html b/docs/Rectangle_Rectangle.html index bf246bf3..4ac392a9 100644 --- a/docs/Rectangle_Rectangle.html +++ b/docs/Rectangle_Rectangle.html @@ -266,13 +266,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Renderer.html b/docs/Renderer.html index fedfb559..0cdd016b 100644 --- a/docs/Renderer.html +++ b/docs/Renderer.html @@ -168,7 +168,7 @@
Parameters:
Source:
@@ -286,7 +286,7 @@
Type:
Source:
@@ -354,7 +354,7 @@
Type:
Source:
@@ -428,7 +428,7 @@
Type:
Source:
@@ -500,7 +500,7 @@
Type:
Source:
@@ -572,7 +572,7 @@
Type:
Source:
@@ -634,7 +634,7 @@

perfSource:
@@ -706,7 +706,7 @@
Type:
Source:
@@ -786,7 +786,7 @@

(protected) RAFSource:
@@ -926,7 +926,7 @@
Parameters:
Source:
@@ -1098,7 +1098,7 @@
Parameters:
Source:
@@ -1186,7 +1186,7 @@

clearSource:
@@ -1323,7 +1323,7 @@
Parameters:
Source:
@@ -1411,7 +1411,7 @@

pauseSource:
@@ -1499,7 +1499,7 @@

playSource:
@@ -1636,7 +1636,7 @@
Parameters:
Source:
@@ -1724,7 +1724,7 @@

requ
Source:
@@ -1884,7 +1884,7 @@

Parameters:
Source:
@@ -2021,7 +2021,7 @@
Parameters:
Source:
@@ -2067,13 +2067,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Renderer2D.html b/docs/Renderer2D.html index e0f5c23d..c2fa5844 100644 --- a/docs/Renderer2D.html +++ b/docs/Renderer2D.html @@ -274,7 +274,7 @@
Type:
Source:
@@ -347,7 +347,7 @@
Type:
Source:
@@ -426,7 +426,7 @@
Type:
Source:
@@ -503,7 +503,7 @@
Type:
Source:
@@ -580,7 +580,7 @@
Type:
Source:
@@ -647,7 +647,7 @@

perfSource:
@@ -724,7 +724,7 @@
Type:
Source:
@@ -809,7 +809,7 @@

(protected) RAFSource:
@@ -954,7 +954,7 @@
Parameters:
Source:
@@ -1264,7 +1264,7 @@
Parameters:
Source:
@@ -1357,7 +1357,7 @@

clearSource:
@@ -1499,7 +1499,7 @@
Parameters:
Source:
@@ -1592,7 +1592,7 @@

pauseSource:
@@ -1685,7 +1685,7 @@

playSource:
@@ -1827,7 +1827,7 @@
Parameters:
Source:
@@ -1920,7 +1920,7 @@

requ
Source:
@@ -2085,7 +2085,7 @@

Parameters:
Source:
@@ -2269,13 +2269,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/RungeKuttaSolver.html b/docs/RungeKuttaSolver.html index a9a83006..1e679973 100644 --- a/docs/RungeKuttaSolver.html +++ b/docs/RungeKuttaSolver.html @@ -312,13 +312,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/SATNarrowPhase.html b/docs/SATNarrowPhase.html index e96fc3d8..aabd3da7 100644 --- a/docs/SATNarrowPhase.html +++ b/docs/SATNarrowPhase.html @@ -231,7 +231,7 @@
Parameters:
-Array.<Manifold> +Array.<Manifold> @@ -344,13 +344,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/SeekBehaviour.html b/docs/SeekBehaviour.html index 05f94041..b2c1eb88 100644 --- a/docs/SeekBehaviour.html +++ b/docs/SeekBehaviour.html @@ -1201,13 +1201,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Sfx.html b/docs/Sfx.html index 126a9a61..3ae8f98d 100644 --- a/docs/Sfx.html +++ b/docs/Sfx.html @@ -273,7 +273,7 @@
Type:
Source:
@@ -345,7 +345,7 @@
Type:
Source:
@@ -417,7 +417,7 @@
Type:
Source:
@@ -435,7 +435,7 @@
Type:
-

onended

+

onended :function

@@ -446,6 +446,16 @@

onendedType:

+
    +
  • + +function + + +
  • +
+ @@ -479,7 +489,7 @@

onendedSource:
@@ -608,7 +618,7 @@
Parameters:
Source:
@@ -696,7 +706,7 @@

disconnect<
Source:
@@ -784,7 +794,7 @@

pauseSource:
@@ -872,7 +882,7 @@

playSource:
@@ -960,7 +970,7 @@

resumeSource:
@@ -1006,13 +1016,13 @@

resume
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Shape.html b/docs/Shape.html index 35f270ad..38f56329 100644 --- a/docs/Shape.html +++ b/docs/Shape.html @@ -1548,13 +1548,13 @@
Returns:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Signal.html b/docs/Signal.html new file mode 100644 index 00000000..6967bbbc --- /dev/null +++ b/docs/Signal.html @@ -0,0 +1,664 @@ + + + + + JSDoc: Class: Signal + + + + + + + + + +
+ +

Class: Signal

+ + + + + + +
+ +
+ +

Signal(value)

+ + +
+ +
+
+ + + + + + +

new Signal(value)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +T + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +

Classes

+ +
+
Signal
+
+
+ + + + + + + + + +

Members

+ + + +

_value :T

+ + + + + + +
Type:
+
    +
  • + +T + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

value :T

+ + + + + + +
Type:
+
    +
  • + +T + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

addListener(listener, callOnce)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
listener + + +signalListener + + + + + +
callOnce + + +boolean + + + + + + false + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

removeListener(listener)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
listener + + +signalListener + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/SpringConstraint.html b/docs/SpringConstraint.html index 9b81a969..c01115cc 100644 --- a/docs/SpringConstraint.html +++ b/docs/SpringConstraint.html @@ -460,13 +460,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Sprite.html b/docs/Sprite.html index ac7267b0..6ad2bfe8 100644 --- a/docs/Sprite.html +++ b/docs/Sprite.html @@ -27,7 +27,7 @@

Class: Sprite

Sprite(geometry, material)

-
This is the base class used to render images and paths onto the renderer. Extend it to create your custom behaviour.
+
This is the base class used to render images and paths onto the renderer. Extend it to create your custom behaviour. TODO - ADD id property to this class and Group class.
@@ -146,13 +146,6 @@
Parameters:
-
Implements:
-
    - -
  • Component TODO - ADD id property to this class and Group class.
  • - -
- @@ -169,7 +162,7 @@
Parameters:
Source:
@@ -423,7 +416,7 @@
Type:
Source:
@@ -517,6 +510,139 @@
Type:

Methods

+ + + + + + +

fromJson(renderer)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
renderer + + +Renderer + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -620,7 +746,7 @@
Parameters:
Source:
@@ -650,6 +776,264 @@
Parameters:
+ + + + + + +

render(ctx, dt)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +CanvasRenderingContext2D + + + +
dt + + +number + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

toJson() → {*}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +* + + +
+
+ + + + + + + @@ -666,13 +1050,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/SpriteMaterial.html b/docs/SpriteMaterial.html index 05e743ef..3120dcff 100644 --- a/docs/SpriteMaterial.html +++ b/docs/SpriteMaterial.html @@ -419,7 +419,7 @@
Type:
Source:
@@ -505,13 +505,13 @@
Type:
-

width :number

+

width :Vector

- The width of the sprite. + /**The width of the sprite.
@@ -520,7 +520,7 @@
Type:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(static) implement(system)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
system + + +any + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -650,13 +821,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/TextMaterial.html b/docs/TextMaterial.html new file mode 100644 index 00000000..02ab0073 --- /dev/null +++ b/docs/TextMaterial.html @@ -0,0 +1,704 @@ + + + + + JSDoc: Class: TextMaterial + + + + + + + + + +
+ +

Class: TextMaterial

+ + + + + + +
+ +
+ +

TextMaterial(text)

+ +
Material for rendering text.
+ + +
+ +
+
+ + + + +

Constructor

+ + + +

new TextMaterial(text)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
text + + +String + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +

Classes

+ +
+
TextMaterial
+
+
+ + + + + + + + + +

Members

+ + + +

center :boolean

+ + + + + + +
Type:
+
    +
  • + +boolean + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

color :String

+ + + + + + +
Type:
+
    +
  • + +String + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

fill :boolean

+ + + + + + +
Type:
+
    +
  • + +boolean + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

font :String

+ + + + + + +
Type:
+
    +
  • + +String + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

text :String

+ + + + + + +
Type:
+
    +
  • + +String + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

render(ctx)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +CanvasRenderingContext2D + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/Touch.html b/docs/Touch.html index 67349c27..4c794f02 100644 --- a/docs/Touch.html +++ b/docs/Touch.html @@ -626,13 +626,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Transform.html b/docs/Transform.html index e4520a33..8b91e44e 100644 --- a/docs/Transform.html +++ b/docs/Transform.html @@ -260,13 +260,13 @@

Classes


- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Triangle.html b/docs/Triangle.html index c032a804..75f36f26 100644 --- a/docs/Triangle.html +++ b/docs/Triangle.html @@ -1497,6 +1497,208 @@
Parameters:
+ + + + + + +

(static) calcInertia(mass, base, height, angle)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
mass + + +number + + + +
base + + +number + + + +
height + + +number + + + +
angle + + +number + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -1513,13 +1715,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Trigon_Trigon.html b/docs/Trigon_Trigon.html index d141afcc..997f8a51 100644 --- a/docs/Trigon_Trigon.html +++ b/docs/Trigon_Trigon.html @@ -243,13 +243,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Tween.html b/docs/Tween.html index bfc67561..309a63db 100644 --- a/docs/Tween.html +++ b/docs/Tween.html @@ -25,7 +25,7 @@

Class: Tween

-

Tween(to, from, duration)

+

Tween(into)

Component responsible for animations.
@@ -42,7 +42,7 @@

Constructor

-

new Tween(to, from, duration)

+

new Tween(into)

@@ -82,7 +82,7 @@
Parameters:
- to + into @@ -102,10 +102,754 @@
Parameters:
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Classes

+ +
+
Tween
+
+
+ + + + + + + + + +

Members

+ + + +

_duration :number

+ + + + + + +
Type:
+
    +
  • + +number + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

_repeat :boolean

+ + + + + + +
Type:
+
    +
  • + +boolean + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

active :boolean

+ + + + + + +
Type:
+
    +
  • + +boolean + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

chain(next)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
next + + +Tween + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

duration(t)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
t + + +T + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

easing(callback)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
callback + + +EasingFunc + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

from(x)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + - + + +
NameTypeDescription
fromx @@ -125,16 +869,126 @@
Parameters:
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

init(entity)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + - + - + - +
NameTypeDescription
durationentity -number +Entity @@ -185,7 +1039,7 @@
Parameters:
Source:
@@ -215,49 +1069,75 @@
Parameters:
- - + + - +

interpolant(callback)

-

Classes

-
-
Tween
-
-
- - - + + + + + + + +
Parameters:
-

Members

+ + + + + + + + + - -

_to :T

+ + + + + + + + + + + + + -
Type:
-
    -
  • -T + + +
+ + + + +
NameTypeDescription
callback + + +LerpFunc + +
- - @@ -292,7 +1172,7 @@
Type:
Source:
@@ -308,11 +1188,19 @@
Type:
- - - -

Methods

+ + + + + + + + + + + + @@ -320,7 +1208,7 @@

Methods

-

duration(t)

+

onUpdate(callback)

@@ -360,13 +1248,13 @@
Parameters:
tcallback -T +TweenUpdate @@ -417,7 +1305,7 @@
Parameters:
Source:
@@ -453,7 +1341,7 @@
Parameters:
-

from(x)

+

to(x)

@@ -550,7 +1438,7 @@
Parameters:
Source:
@@ -586,7 +1474,7 @@
Parameters:
-

to(x)

+

update(dt)

@@ -626,13 +1514,13 @@
Parameters:
xdt -T +number @@ -683,7 +1571,7 @@
Parameters:
Source:
@@ -729,13 +1617,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Vec2_Vec2.html b/docs/Vec2_Vec2.html new file mode 100644 index 00000000..16befd18 --- /dev/null +++ b/docs/Vec2_Vec2.html @@ -0,0 +1,235 @@ + + + + + JSDoc: Class: Vec2 + + + + + + + + + +
+ +

Class: Vec2

+ + + + + + +
+ +
+ +

Vec2(x, y)

+ + +
+ +
+
+ + + + + + +

new Vec2(x, y)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
x + + +number + + + + the x coordinate of the vector
y + + +number + + + + the y coordinate of the vector
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/Vector2.html b/docs/Vector2.html index d6dd1770..570aa423 100644 --- a/docs/Vector2.html +++ b/docs/Vector2.html @@ -165,7 +165,7 @@
Parameters:
Source:
@@ -272,7 +272,7 @@
Type:
Source:
@@ -340,7 +340,7 @@
Type:
Source:
@@ -412,7 +412,7 @@
Type:
Source:
@@ -541,7 +541,7 @@
Parameters:
Source:
@@ -696,7 +696,7 @@
Parameters:
Source:
@@ -910,7 +910,7 @@
Parameters:
Source:
@@ -1016,7 +1016,7 @@

cloneSource:
@@ -1114,7 +1114,7 @@

copySource:
@@ -1261,7 +1261,7 @@
Parameters:
Source:
@@ -1416,7 +1416,7 @@
Parameters:
Source:
@@ -1553,7 +1553,7 @@
Parameters:
Source:
@@ -1708,7 +1708,7 @@
Parameters:
Source:
@@ -1863,7 +1863,7 @@
Parameters:
Source:
@@ -2140,7 +2140,7 @@
Parameters:
Source:
@@ -2295,7 +2295,7 @@
Parameters:
Source:
@@ -2401,7 +2401,7 @@

equalsZero<
Source:
@@ -2507,7 +2507,7 @@

magnitudeSource:
@@ -2613,7 +2613,7 @@

magni
Source:
@@ -2750,7 +2750,7 @@

Parameters:
Source:
@@ -2962,7 +2962,7 @@
Parameters:
Source:
@@ -3137,7 +3137,7 @@
Parameters:
Source:
@@ -3243,7 +3243,7 @@

normalizeSource:
@@ -3441,7 +3441,7 @@
Parameters:
Source:
@@ -3547,7 +3547,7 @@

reverseSource:
@@ -3702,7 +3702,7 @@
Parameters:
Source:
@@ -3880,7 +3880,7 @@
Parameters:
Source:
@@ -4035,7 +4035,7 @@
Parameters:
Source:
@@ -4172,7 +4172,7 @@
Parameters:
Source:
@@ -4327,7 +4327,7 @@
Parameters:
Source:
@@ -4502,7 +4502,7 @@
Parameters:
Source:
@@ -4692,7 +4692,7 @@
Parameters:
Source:
@@ -4890,7 +4890,7 @@
Parameters:
Source:
@@ -5068,7 +5068,7 @@
Parameters:
Source:
@@ -5246,7 +5246,7 @@
Parameters:
Source:
@@ -5424,7 +5424,7 @@
Parameters:
Source:
@@ -5602,7 +5602,7 @@
Parameters:
Source:
@@ -5862,7 +5862,7 @@
Parameters:
Source:
@@ -6029,7 +6029,7 @@
Parameters:
Source:
@@ -6184,7 +6184,7 @@
Parameters:
Source:
@@ -6339,7 +6339,7 @@
Parameters:
Source:
@@ -6403,13 +6403,13 @@
Returns:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/VectorPool.html b/docs/VectorPool.html index 083f2602..7f9e33e2 100644 --- a/docs/VectorPool.html +++ b/docs/VectorPool.html @@ -334,13 +334,13 @@

destroy
- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/Vector_Vector.html b/docs/Vector_Vector.html new file mode 100644 index 00000000..95b69d83 --- /dev/null +++ b/docs/Vector_Vector.html @@ -0,0 +1,235 @@ + + + + + JSDoc: Class: Vector + + + + + + + + + +
+ +

Class: Vector

+ + + + + + +
+ +
+ +

Vector(x, y)

+ + +
+ +
+
+ + + + + + +

new Vector(x, y)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
x + + +number + + + + the x coordinate of the vector
y + + +number + + + + the y coordinate of the vector
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time) +
+ + + + + \ No newline at end of file diff --git a/docs/VerletSolver.html b/docs/VerletSolver.html index 8bf4d0f6..a5dcc7c0 100644 --- a/docs/VerletSolver.html +++ b/docs/VerletSolver.html @@ -312,13 +312,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/WanderBehaviour.html b/docs/WanderBehaviour.html index 7ab087a9..2a334634 100644 --- a/docs/WanderBehaviour.html +++ b/docs/WanderBehaviour.html @@ -1218,13 +1218,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/WebGLRenderer.html b/docs/WebGLRenderer.html index 42bd0e1b..c430c9ef 100644 --- a/docs/WebGLRenderer.html +++ b/docs/WebGLRenderer.html @@ -213,7 +213,7 @@
Type:
Source:
@@ -286,7 +286,7 @@
Type:
Source:
@@ -365,7 +365,7 @@
Type:
Source:
@@ -442,7 +442,7 @@
Type:
Source:
@@ -519,7 +519,7 @@
Type:
Source:
@@ -586,7 +586,7 @@

perfSource:
@@ -663,7 +663,7 @@
Type:
Source:
@@ -748,7 +748,7 @@

(protected) RAFSource:
@@ -893,7 +893,7 @@
Parameters:
Source:
@@ -1070,7 +1070,7 @@
Parameters:
Source:
@@ -1163,7 +1163,7 @@

clearSource:
@@ -1305,7 +1305,7 @@
Parameters:
Source:
@@ -1398,7 +1398,7 @@

pauseSource:
@@ -1491,7 +1491,7 @@

playSource:
@@ -1633,7 +1633,7 @@
Parameters:
Source:
@@ -1726,7 +1726,7 @@

requ
Source:
@@ -1891,7 +1891,7 @@

Parameters:
Source:
@@ -2033,7 +2033,7 @@
Parameters:
Source:
@@ -2079,13 +2079,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/WebGPURenderer.html b/docs/WebGPURenderer.html index 560b87c1..c369a5e1 100644 --- a/docs/WebGPURenderer.html +++ b/docs/WebGPURenderer.html @@ -213,7 +213,7 @@
Type:
Source:
@@ -286,7 +286,7 @@
Type:
Source:
@@ -365,7 +365,7 @@
Type:
Source:
@@ -442,7 +442,7 @@
Type:
Source:
@@ -519,7 +519,7 @@
Type:
Source:
@@ -586,7 +586,7 @@

perfSource:
@@ -663,7 +663,7 @@
Type:
Source:
@@ -748,7 +748,7 @@

(protected) RAFSource:
@@ -893,7 +893,7 @@
Parameters:
Source:
@@ -1070,7 +1070,7 @@
Parameters:
Source:
@@ -1163,7 +1163,7 @@

clearSource:
@@ -1305,7 +1305,7 @@
Parameters:
Source:
@@ -1398,7 +1398,7 @@

pauseSource:
@@ -1491,7 +1491,7 @@

playSource:
@@ -1633,7 +1633,7 @@
Parameters:
Source:
@@ -1726,7 +1726,7 @@

requ
Source:
@@ -1891,7 +1891,7 @@

Parameters:
Source:
@@ -2033,7 +2033,7 @@
Parameters:
Source:
@@ -2079,13 +2079,13 @@
Parameters:

- Documentation generated by JSDoc 4.0.2 on Sat Dec 09 2023 16:05:50 GMT+0300 (East Africa Time) + Documentation generated by JSDoc 4.0.2 on Mon Jan 08 2024 16:36:55 GMT+0300 (East Africa Time)
diff --git a/docs/World.html b/docs/World.html index d9ea22a4..d29326b7 100644 --- a/docs/World.html +++ b/docs/World.html @@ -147,7 +147,7 @@

Members

-

CLMDs :Array.<Manifold>

+

CLMDs :Array.<Manifold>

@@ -162,7 +162,7 @@
Type: