From 2329bd03d658eb90762686c676b8dbd9002aa1dd Mon Sep 17 00:00:00 2001 From: Prozi Jacek Pietal Date: Fri, 1 Nov 2024 04:44:17 +0100 Subject: [PATCH] feat: create functions accept custom types --- dist/base-system.d.ts | 24 ++--- dist/base-system.js | 30 +++--- dist/bodies/box.d.ts | 3 + dist/bodies/circle.d.ts | 3 + dist/bodies/ellipse.d.ts | 3 + dist/bodies/line.d.ts | 3 + dist/bodies/point.d.ts | 3 + dist/bodies/polygon.d.ts | 5 +- dist/bodies/polygon.js | 3 +- dist/demo/demo.js | 33 ++++--- docs/assets/navigation.js | 2 +- docs/assets/search.js | 2 +- docs/classes/Box.html | 114 +++++++++++------------ docs/classes/Circle.html | 86 +++++++++--------- docs/classes/Ellipse.html | 116 ++++++++++++------------ docs/classes/Line.html | 100 ++++++++++---------- docs/classes/Point.html | 114 +++++++++++------------ docs/classes/Polygon.html | 100 ++++++++++---------- docs/classes/System.html | 30 +++--- docs/demo/demo.js | 33 ++++--- docs/interfaces/BoxConstructor.html | 2 + docs/interfaces/CircleConstructor.html | 2 + docs/interfaces/EllipseConstructor.html | 2 + docs/interfaces/LineConstructor.html | 2 + docs/interfaces/PointConstructor.html | 2 + docs/interfaces/PolygonConstructor.html | 2 + docs/modules.html | 6 ++ package.json | 2 +- src/base-system.ts | 75 ++++++++------- src/bodies/box.ts | 11 ++- src/bodies/circle.ts | 13 ++- src/bodies/ellipse.ts | 12 ++- src/bodies/line.ts | 8 +- src/bodies/point.ts | 4 + src/bodies/polygon.ts | 8 +- src/system.spec.js | 17 ++++ 36 files changed, 548 insertions(+), 427 deletions(-) create mode 100644 docs/interfaces/BoxConstructor.html create mode 100644 docs/interfaces/CircleConstructor.html create mode 100644 docs/interfaces/EllipseConstructor.html create mode 100644 docs/interfaces/LineConstructor.html create mode 100644 docs/interfaces/PointConstructor.html create mode 100644 docs/interfaces/PolygonConstructor.html diff --git a/dist/base-system.d.ts b/dist/base-system.d.ts index 029c44e8..3ea46719 100644 --- a/dist/base-system.d.ts +++ b/dist/base-system.d.ts @@ -1,10 +1,10 @@ import { Body, BodyOptions, ChildrenData, Data, InTest, Leaf, PotentialVector, RBush, TraverseFunction, Vector } from "./model"; -import { Box } from "./bodies/box"; -import { Circle } from "./bodies/circle"; -import { Ellipse } from "./bodies/ellipse"; -import { Line } from "./bodies/line"; -import { Point } from "./bodies/point"; -import { Polygon } from "./bodies/polygon"; +import { Box, BoxConstructor } from "./bodies/box"; +import { Circle, CircleConstructor } from "./bodies/circle"; +import { Ellipse, EllipseConstructor } from "./bodies/ellipse"; +import { Line, LineConstructor } from "./bodies/line"; +import { Point, PointConstructor } from "./bodies/point"; +import { Polygon, PolygonConstructor } from "./bodies/polygon"; /** * very base collision system (create, insert, update, draw, remove) */ @@ -13,27 +13,27 @@ export declare class BaseSystem extends RBush impleme /** * create point at position with options and add to system */ - createPoint(position: PotentialVector, options?: BodyOptions): TPoint; + createPoint(position: PotentialVector, options?: BodyOptions, Class?: PointConstructor): TPoint | Point; /** * create line at position with options and add to system */ - createLine(start: Vector, end: Vector, options?: BodyOptions): TLine; + createLine(start: Vector, end: Vector, options?: BodyOptions, Class?: LineConstructor): TLine | Line; /** * create circle at position with options and add to system */ - createCircle(position: PotentialVector, radius: number, options?: BodyOptions): TCircle; + createCircle(position: PotentialVector, radius: number, options?: BodyOptions, Class?: CircleConstructor): TCircle | Circle; /** * create box at position with options and add to system */ - createBox(position: PotentialVector, width: number, height: number, options?: BodyOptions): TBox; + createBox(position: PotentialVector, width: number, height: number, options?: BodyOptions, Class?: BoxConstructor): TBox | Box; /** * create ellipse at position with options and add to system */ - createEllipse(position: PotentialVector, radiusX: number, radiusY?: number, step?: number, options?: BodyOptions): TEllipse; + createEllipse(position: PotentialVector, radiusX: number, radiusY?: number, step?: number, options?: BodyOptions, Class?: EllipseConstructor): TEllipse | Ellipse; /** * create polygon at position with options and add to system */ - createPolygon(position: PotentialVector, points: PotentialVector[], options?: BodyOptions): TPolygon; + createPolygon(position: PotentialVector, points: PotentialVector[], options?: BodyOptions, Class?: PolygonConstructor): TPolygon | Polygon; /** * re-insert body into collision tree and update its bbox * every body can be part of only one system diff --git a/dist/base-system.js b/dist/base-system.js index 19be1f07..79bbb369 100644 --- a/dist/base-system.js +++ b/dist/base-system.js @@ -17,48 +17,54 @@ class BaseSystem extends model_1.RBush { /** * create point at position with options and add to system */ - createPoint(position, options) { - const point = new point_1.Point(position, options); + createPoint(position, options, Class) { + const PointClass = Class || point_1.Point; + const point = new PointClass(position, options); this.insert(point); return point; } /** * create line at position with options and add to system */ - createLine(start, end, options) { - const line = new line_1.Line(start, end, options); + createLine(start, end, options, Class) { + const LineClass = Class || line_1.Line; + const line = new LineClass(start, end, options); this.insert(line); return line; } /** * create circle at position with options and add to system */ - createCircle(position, radius, options) { - const circle = new circle_1.Circle(position, radius, options); + createCircle(position, radius, options, Class) { + const CircleClass = Class || circle_1.Circle; + const circle = new CircleClass(position, radius, options); this.insert(circle); return circle; } /** * create box at position with options and add to system */ - createBox(position, width, height, options) { - const box = new box_1.Box(position, width, height, options); + createBox(position, width, height, options, Class) { + const BoxClass = Class || box_1.Box; + const box = new BoxClass(position, width, height, options); this.insert(box); return box; } /** * create ellipse at position with options and add to system */ - createEllipse(position, radiusX, radiusY = radiusX, step, options) { - const ellipse = new ellipse_1.Ellipse(position, radiusX, radiusY, step, options); + createEllipse(position, radiusX, radiusY = radiusX, step, options, Class) { + const EllipseClass = Class || ellipse_1.Ellipse; + const ellipse = new EllipseClass(position, radiusX, radiusY, step, options); this.insert(ellipse); return ellipse; } /** * create polygon at position with options and add to system */ - createPolygon(position, points, options) { - const polygon = new polygon_1.Polygon(position, points, options); + createPolygon(position, points, options, Class) { + const PolygonClass = Class || polygon_1.Polygon; + const polygon = new PolygonClass(position, points, options); this.insert(polygon); return polygon; } diff --git a/dist/bodies/box.d.ts b/dist/bodies/box.d.ts index 8467a4b1..e8689bbb 100644 --- a/dist/bodies/box.d.ts +++ b/dist/bodies/box.d.ts @@ -1,5 +1,8 @@ import { BodyGroup, BodyOptions, BodyType, PotentialVector } from "../model"; import { Polygon } from "./polygon"; +export interface BoxConstructor { + new (position: PotentialVector, width: number, height: number, options?: BodyOptions): TBox; +} /** * collider - box */ diff --git a/dist/bodies/circle.d.ts b/dist/bodies/circle.d.ts index 8e550e1e..bb9b1dd2 100644 --- a/dist/bodies/circle.d.ts +++ b/dist/bodies/circle.d.ts @@ -1,6 +1,9 @@ import { BBox, BodyGroup, BodyOptions, BodyProps, BodyType, PotentialVector, SATVector, Vector } from "../model"; import { Circle as SATCircle } from "sat"; import { System } from "../system"; +export interface CircleConstructor { + new (position: PotentialVector, radius: number, options?: BodyOptions): TCircle; +} /** * collider - circle */ diff --git a/dist/bodies/ellipse.d.ts b/dist/bodies/ellipse.d.ts index 871f3c15..4389f24e 100644 --- a/dist/bodies/ellipse.d.ts +++ b/dist/bodies/ellipse.d.ts @@ -1,5 +1,8 @@ import { BodyGroup, BodyOptions, BodyType, PotentialVector } from "../model"; import { Polygon } from "./polygon"; +export interface EllipseConstructor { + new (position: PotentialVector, radiusX: number, radiusY?: number, step?: number, options?: BodyOptions): TEllipse; +} /** * collider - ellipse */ diff --git a/dist/bodies/line.d.ts b/dist/bodies/line.d.ts index 4a2f9ac4..fa6c83c4 100644 --- a/dist/bodies/line.d.ts +++ b/dist/bodies/line.d.ts @@ -1,6 +1,9 @@ import { BodyGroup, BodyOptions, BodyType, Vector } from "../model"; import { Vector as SATVector } from "sat"; import { Polygon } from "./polygon"; +export interface LineConstructor { + new (start: Vector, end: Vector, options?: BodyOptions): TLine; +} /** * collider - line */ diff --git a/dist/bodies/point.d.ts b/dist/bodies/point.d.ts index ed1621a6..aece8ae4 100644 --- a/dist/bodies/point.d.ts +++ b/dist/bodies/point.d.ts @@ -1,5 +1,8 @@ import { BodyGroup, BodyOptions, BodyType, PotentialVector } from "../model"; import { Box } from "./box"; +export interface PointConstructor { + new (position: PotentialVector, options?: BodyOptions): TPoint; +} /** * collider - point (very tiny box) */ diff --git a/dist/bodies/polygon.d.ts b/dist/bodies/polygon.d.ts index 2dbd5d10..f4120b6f 100644 --- a/dist/bodies/polygon.d.ts +++ b/dist/bodies/polygon.d.ts @@ -1,8 +1,9 @@ -import { isSimple } from "poly-decomp-es"; import { BBox, BodyGroup, BodyOptions, BodyProps, BodyType, DecompPolygon, PotentialVector, SATVector, Vector } from "../model"; import { Polygon as SATPolygon } from "sat"; import { System } from "../system"; -export { isSimple }; +export interface PolygonConstructor { + new (position: PotentialVector, points: PotentialVector[], options?: BodyOptions): TPolygon; +} /** * collider - polygon */ diff --git a/dist/bodies/polygon.js b/dist/bodies/polygon.js index 3daf4769..5d8ced83 100644 --- a/dist/bodies/polygon.js +++ b/dist/bodies/polygon.js @@ -1,8 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.Polygon = exports.isSimple = void 0; +exports.Polygon = void 0; const poly_decomp_es_1 = require("poly-decomp-es"); -Object.defineProperty(exports, "isSimple", { enumerable: true, get: function () { return poly_decomp_es_1.isSimple; } }); const model_1 = require("../model"); const optimized_1 = require("../optimized"); const utils_1 = require("../utils"); diff --git a/dist/demo/demo.js b/dist/demo/demo.js index 9d5e33de..d8b609c5 100644 --- a/dist/demo/demo.js +++ b/dist/demo/demo.js @@ -2067,48 +2067,54 @@ class BaseSystem extends model_1.RBush { /** * create point at position with options and add to system */ - createPoint(position, options) { - const point = new point_1.Point(position, options); + createPoint(position, options, Class) { + const PointClass = Class || point_1.Point; + const point = new PointClass(position, options); this.insert(point); return point; } /** * create line at position with options and add to system */ - createLine(start, end, options) { - const line = new line_1.Line(start, end, options); + createLine(start, end, options, Class) { + const LineClass = Class || line_1.Line; + const line = new LineClass(start, end, options); this.insert(line); return line; } /** * create circle at position with options and add to system */ - createCircle(position, radius, options) { - const circle = new circle_1.Circle(position, radius, options); + createCircle(position, radius, options, Class) { + const CircleClass = Class || circle_1.Circle; + const circle = new CircleClass(position, radius, options); this.insert(circle); return circle; } /** * create box at position with options and add to system */ - createBox(position, width, height, options) { - const box = new box_1.Box(position, width, height, options); + createBox(position, width, height, options, Class) { + const BoxClass = Class || box_1.Box; + const box = new BoxClass(position, width, height, options); this.insert(box); return box; } /** * create ellipse at position with options and add to system */ - createEllipse(position, radiusX, radiusY = radiusX, step, options) { - const ellipse = new ellipse_1.Ellipse(position, radiusX, radiusY, step, options); + createEllipse(position, radiusX, radiusY = radiusX, step, options, Class) { + const EllipseClass = Class || ellipse_1.Ellipse; + const ellipse = new EllipseClass(position, radiusX, radiusY, step, options); this.insert(ellipse); return ellipse; } /** * create polygon at position with options and add to system */ - createPolygon(position, points, options) { - const polygon = new polygon_1.Polygon(position, points, options); + createPolygon(position, points, options, Class) { + const PolygonClass = Class || polygon_1.Polygon; + const polygon = new PolygonClass(position, points, options); this.insert(polygon); return polygon; } @@ -2769,9 +2775,8 @@ exports.Point = Point; "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.Polygon = exports.isSimple = void 0; +exports.Polygon = void 0; const poly_decomp_es_1 = __webpack_require__(/*! poly-decomp-es */ "./node_modules/poly-decomp-es/dist/poly-decomp-es.js"); -Object.defineProperty(exports, "isSimple", ({ enumerable: true, get: function () { return poly_decomp_es_1.isSimple; } })); const model_1 = __webpack_require__(/*! ../model */ "./src/model.ts"); const optimized_1 = __webpack_require__(/*! ../optimized */ "./src/optimized.ts"); const utils_1 = __webpack_require__(/*! ../utils */ "./src/utils.ts"); diff --git a/docs/assets/navigation.js b/docs/assets/navigation.js index 5f20d31e..8f9d2af4 100644 --- a/docs/assets/navigation.js +++ b/docs/assets/navigation.js @@ -1 +1 @@ -window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA52XS3PaMBSF/4vXpGlok7bsbEgIM2mTSTzZdLoQ9g1oMJJHkilMp/+94wfYkq+vaLY653x6WdL1zz+Bgb0JJkEk08NcySIPRkHOzDqYBCCKrb48CR/WZpsFo2DDRRpMvv4dWdn4kAMWLdup5L4NJRnTGsrY3k5cjbuZKVdJBv1Y3U4lb7OM5xqJNgKVfeACCZatVOpJcmH6saqZzmWHlRRYshKo7HNU6HU/WTWTOdC5FNjyHJVeelRbgklgdHrB9QXsDSjBsqDDfQnjoS07Se8mDy5Uq72b/QqJkQpF19I7yQdtYItgq3ZqhyLruHBhQL2xpDwxvSMzvr5xDuhjbrgUGs+3ug/zpGQ+DKlUCjFd8yxVIGbMMJTSNVCgQYAvOAcThlEU6qHF7Boo0JM0IAxnmfuddFiOh8I9s0PCtLnnBiW1MgUhhuIfQbmBbdQc8mZTnczHb1+ursfdPZVZxjWXYsqybMmSjQvpGXzEGSRymzuXZ83qSCjlrCN4hDh3h90Dcnn8Tx8LEYPuDb9u9c3/AdibmyzbfLmXMMY6bZp96VixHSgNd4VIyrvAxbi6dxdv5+PncNZidkxxtszKNa4lm/CpG34OZ+PZ7RwLNxIRXnIxTiFpw2/NkPVlI9nhm8/dsEwP3+UOUjR+FAlAwsSiPHcsMRiiI1OQNSSbcCEiFHEUKUD1sC6E+/Z2KJbjDFTvwPRZ6LFBYI+F0TwFL9H2UdhMJpvfXOMzPYo0QEB1r+hQKXYY4FgeH65fUjksvLKyQQqYAeux6kCOohfQq31dCFoDW6CU6XVZ8MYSo7QqhYDVWDH0ZDXSxRUV59owkaCzOGpUXLHf0es9mq4lT5j4XDsyAQGhCwVTKXaA7mdX92J+FNslqGFMrXsxzajrz3qYZtm80LracF5wF9kxUcC9AZHaxUmHdFIJxApMJAuRwIwrcN62FtV30Ujnd9kCIX/Mbrz3WFsA9M22EWUXEcf37CQSgKo41JBU5S4GsQzngMrzP/zeILZzofbf9wCy/zNOA+8Yvvqo8VwwcUVgPgqrX/g2H1jKRnPjZ1WmW5ZXr1cs3d+FtgPXQ4xzy/LaE8vBh9P1UDi5Q6dcthMxIc3C9z27HgKXl5cSWfHYDh/qkajDLAMJqrqiSjrHcg6MnKLtIXCKpeMUVhilkciHXYEplIhVgc6qVXuIX/8AfjD0VsIUAAA=" \ No newline at end of file +window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA52YT1PbMBDFv4vPUEpaaJubTSBkhpYOeLh0ehD2QjRxJI8kh2Q6/e4d/0lsSetVylXvvZ8l29Ku/etPZGBrommUyHw3V7Iqo5OoZGYZTSMQ1VqfHYQPS7MuopNoxUUeTb/+PbGy6a4ELFqPU8ltH8oKpjXUsa2dOJ8MM1dcZQX4sXacSl4XBS81Eu0EKnvHBRKsR6nUT8mF8WPNMJ0rdq9SYMlGoLIPSaWXfrIZJnOgSymw27NXvPRJa4mmkdH5KdensDWgBCuiAfcxTsce2UF6N3n0RvXau9lPkBmpUHQrvZO80wbWCLYZp55QYm0XLgyoF5bVO8bbMpOLS2eD3peGS6HxfK+HMD+VLMchjUojtldSaKMq+95anKGFgl0teZErEDNmGIoaGkhQ8xKGJua5KOTonEJz6c6i0GR8GwWdg4njJIn12Bs0NFCg+sALTc3xULjmIAzxXBMNbPZ8GOnaaKgBYTgr3BPBIloeCvfAdhnT5pYblNTLFISYSngG9Vbto2ZXdtvXyXz89uX8YjLcJ7IouOZSXLGieGbZyoV4hhBxBplcl06ZbFkDCaUcddjuIU6VsK+AlIn/ucZCpKC96bejofXfAXtxk/VYKPcYp9hFu+FQOlVsA0rDTSWy+tR3Ma4efIrX88lDPOsxG6Y4ey7qe9xKNuHTMPwQzyaz6zkW7iQi/MzFJIesD790U9ZnnWSHLz8PwzLffZcbyNH4XiQAGROLet+xzGCIgUxBlpCt4oVIUMRepABNXVoIt8saUCzHEShvw/gsdNsgsPvKaJ5DkGj7KGwhs9Ub1/hK9yINENCcKzpWiu1GOJYnhPObZ4eF99A2SAEzYFXoAWQvBgHeV44LQb92LFDO9LKu4qnEKL1KIeB1ohi6szrp9JyKc22YyNBV7DUqrthb8nSLplspECZe14FMQEDoStVt0AbQ5znUg5gf1foZ1Dim1YOYbtbtaz1Os2xBaNttOBXcRQ5MFHBrQOR2czIgHVQC8QomkZXIYMYVOLWtR/kuGun8GLFAyL8RN+4VawuA1mwbUV8i4fgzO4gEoGkONWRNj49BLMMxoKbHH603iO1YqP2fZQTp/3ahgTcMv/uo8VgwcURgPgqrH/m6HLmVnebGj+pM16xsqlcq3c+F/gKuh5jnmpWtJ5WjhdP1UDi5QZdcjxMxIc0i9D67HgJX1ocS2fHYjhDqnujDLAMJai5FtXSO5RgYuUTbQ+AUyyc5vGKUTiILuwJTKZGqCl1Vr3qI3/8A8K+b+KwWAAA=" \ No newline at end of file diff --git a/docs/assets/search.js b/docs/assets/search.js index 90569177..85708e07 100644 --- a/docs/assets/search.js +++ b/docs/assets/search.js @@ -1 +1 @@ -window.searchData = "data:application/octet-stream;base64,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"; \ No newline at end of file +window.searchData = "data:application/octet-stream;base64,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"; \ No newline at end of file diff --git a/docs/classes/Box.html b/docs/classes/Box.html index c08fefad..bf49da35 100644 --- a/docs/classes/Box.html +++ b/docs/classes/Box.html @@ -1,5 +1,5 @@ Box | Detect-Collisions

Class Box<UserDataType>

collider - box

-

Type Parameters

  • UserDataType = any

Hierarchy (view full)

Constructors

Type Parameters

  • UserDataType = any

Hierarchy (view full)

Constructors

Properties

Constructors

Properties

_group: number

group for collision filtering

-
_height: number

inner height

-
_width: number

inner width

-
angle: number

body angle in radians use deg2rad to convert +

Type Parameters

  • UserDataType = any

Parameters

Returns Box<UserDataType>

Properties

_group: number

group for collision filtering

+
_height: number

inner height

+
_width: number

inner width

+
angle: number

body angle in radians use deg2rad to convert move(speed) moves at 1 speed = 1px towards angle

bbox: BBox

bounding box cache, without padding

-
calcPoints: SATVector[]
centered: boolean = false

is body centered

-
convexPolygons: SATPolygon[]

optimization for convex polygons

-
dirty: boolean = false

was the polygon modified and needs update in the next checkCollision

-
edges: SATVector[]
isConvex = true

boxes are convex

-
isStatic: boolean

static bodies don't move but they collide

-
isTrigger: boolean

trigger bodies move but are like ghosts

-
maxX: number

maximum x bound of body

-
maxY: number

maximum y bound of body

-
minX: number

minimum x bound of body

-
minY: number

minimum y bound of body

-
normals: SATVector[]
offset: SATVector

each body may have offset from center

+
calcPoints: SATVector[]
centered: boolean = false

is body centered

+
convexPolygons: SATPolygon[]

optimization for convex polygons

+
dirty: boolean = false

was the polygon modified and needs update in the next checkCollision

+
edges: SATVector[]
isConvex = true

boxes are convex

+
isStatic: boolean

static bodies don't move but they collide

+
isTrigger: boolean

trigger bodies move but are like ghosts

+
maxX: number

maximum x bound of body

+
maxY: number

maximum y bound of body

+
minX: number

minimum x bound of body

+
minY: number

minimum y bound of body

+
normals: SATVector[]
offset: SATVector

each body may have offset from center

padding: number

bodies are not reinserted during update if their bbox didnt move outside bbox + padding

-
points: SATVector[]
pointsBackup: Vector[]

backup of points used for scaling

-
scaleVector: Vector = ...

scale Vector of body

-
system?: System<Body>

reference to collision system

-
type: Box | Point = BodyType.Box

type of body

-
typeGroup: Box | Point = BodyGroup.Box

faster than type

-
userData?: any

allows the user to set any misc data for client use

-

Accessors

points: SATVector[]
pointsBackup: Vector[]

backup of points used for scaling

+
scaleVector: Vector = ...

scale Vector of body

+
system?: System<Body>

reference to collision system

+
type: Box | Point = BodyType.Box

type of body

+
typeGroup: Box | Point = BodyGroup.Box

faster than type

+
userData?: any

allows the user to set any misc data for client use

+

Accessors

  • get group(): number
  • group for collision filtering

    Based on Box2D (tutorial)

    Values in BodyGroup are predefined and used each the body type and @@ -95,7 +95,7 @@

    0x7fffffff // member of all groups (can interact with everyting)
     
    -
  • set group(group): void
  • group for collision filtering

    +
  • set group(group): void
  • group for collision filtering

    Based on Box2D (tutorial)

    Values in BodyGroup are predefined and used each the body type and @@ -105,38 +105,38 @@

    0x7fffffff // member of all groups (can interact with everyting)
     
    -
    • get height(): number
    • get box height

      -

      Returns number

    • set height(height): void
    • set box height, update points

      -

      Parameters

      • height: number

      Returns void

    • get isCentered(): boolean
    • is polygon centered?

      -

      Returns boolean

    • set isCentered(isCentered): void
    • flag to set is polygon centered

      -

      Parameters

      • isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      -

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      -

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      -

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      -

      Returns number

    Methods

    • after setting width/height update translate +

    • get height(): number
    • get box height

      +

      Returns number

    • set height(height): void
    • set box height, update points

      +

      Parameters

      • height: number

      Returns void

    • get isCentered(): boolean
    • is polygon centered?

      +

      Returns boolean

    • set isCentered(isCentered): void
    • flag to set is polygon centered

      +

      Parameters

      • isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      +

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      +

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      +

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      +

      Returns number

    Methods

    • inner function for after position change update aabb in system and convex inner polygons

      -

      Parameters

      • updateNow: boolean = ...

      Returns void

    • update the position of the decomposed convex polygons (if any), called +

      Returns void

    • inner function for after position change update aabb in system and convex inner polygons

      +

      Parameters

      • updateNow: boolean = ...

      Returns void

    +

    Returns void

    diff --git a/docs/classes/Circle.html b/docs/classes/Circle.html index 8d776165..28804447 100644 --- a/docs/classes/Circle.html +++ b/docs/classes/Circle.html @@ -1,5 +1,5 @@ Circle | Detect-Collisions

    Class Circle<UserDataType>

    collider - circle

    -

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Implements

    Constructors

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Implements

    Constructors

    Properties

    _group angle bbox @@ -40,27 +40,27 @@ setScale updateBody

    Constructors

    Properties

    _group: number

    group for collision filtering

    -
    angle: number

    for compatibility reasons circle has angle

    -
    bbox: BBox

    bounding box cache, without padding

    -
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    -
    isCentered = true

    always centered

    -
    isConvex = true

    flag to show is it a convex body or non convex polygon

    -
    isStatic: boolean

    static bodies don't move but they collide

    -
    isTrigger: boolean

    trigger bodies move but are like ghosts

    -
    maxX: number

    maximum x bound of body

    -
    maxY: number

    maximum y bound of body

    -
    minX: number

    minimum x bound of body

    -
    minY: number

    minimum y bound of body

    -
    offset: SATVector

    offset

    -
    offsetCopy: Vector = ...

    offset copy without angle applied

    -
    padding: number

    bodies are not reinserted during update if their bbox didnt move outside bbox + padding

    -
    r: number
    system?: System<Body>

    reference to collision system

    -
    type: Circle = BodyType.Circle

    circle type

    -
    typeGroup: Circle = BodyGroup.Circle

    faster than type

    -
    unscaledRadius: number

    saved initial radius - internal

    -
    userData?: any

    allows the user to set any misc data for client use

    -

    Accessors

    Properties

    _group: number

    group for collision filtering

    +
    angle: number

    for compatibility reasons circle has angle

    +
    bbox: BBox

    bounding box cache, without padding

    +
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    +
    isCentered = true

    always centered

    +
    isConvex = true

    flag to show is it a convex body or non convex polygon

    +
    isStatic: boolean

    static bodies don't move but they collide

    +
    isTrigger: boolean

    trigger bodies move but are like ghosts

    +
    maxX: number

    maximum x bound of body

    +
    maxY: number

    maximum y bound of body

    +
    minX: number

    minimum x bound of body

    +
    minY: number

    minimum y bound of body

    +
    offset: SATVector

    offset

    +
    offsetCopy: Vector = ...

    offset copy without angle applied

    +
    padding: number

    bodies are not reinserted during update if their bbox didnt move outside bbox + padding

    +
    r: number
    system?: System<Body>

    reference to collision system

    +
    type: Circle = BodyType.Circle

    circle type

    +
    typeGroup: Circle = BodyGroup.Circle

    faster than type

    +
    unscaledRadius: number

    saved initial radius - internal

    +
    userData?: any

    allows the user to set any misc data for client use

    +

    Accessors

    • get group(): number
    • group for collision filtering

      Based on Box2D (tutorial)

      Values in BodyGroup are predefined and used each the body type and @@ -70,7 +70,7 @@

      0x7fffffff // member of all groups (can interact with everyting)
       
      -
  • set group(group): void
  • group for collision filtering

    +
  • set group(group): void
  • group for collision filtering

    Based on Box2D (tutorial)

    Values in BodyGroup are predefined and used each the body type and @@ -80,23 +80,23 @@

    0x7fffffff // member of all groups (can interact with everyting)
     
    -
    • get scaleX(): number
    • scaleX = scale in case of Circles

      -

      Returns number

    • get scaleY(): number
    • scaleY = scale in case of Circles

      -

      Returns number

    Methods

    • Draws collider on a CanvasRenderingContext2D's current path

      -

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • update instantly or mark as dirty

      -

      Parameters

      • updateNow: boolean = false

      Returns void

    • inner function for after position change update aabb in system

      -

      Parameters

      • updateNow: boolean = ...

      Returns void

    +
    • get scaleX(): number
    • scaleX = scale in case of Circles

      +

      Returns number

    • get scaleY(): number
    • scaleY = scale in case of Circles

      +

      Returns number

    Methods

    • Draws collider on a CanvasRenderingContext2D's current path

      +

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • update instantly or mark as dirty

      +

      Parameters

      • updateNow: boolean = false

      Returns void

    • inner function for after position change update aabb in system

      +

      Parameters

      • updateNow: boolean = ...

      Returns void

    diff --git a/docs/classes/Ellipse.html b/docs/classes/Ellipse.html index 5d506393..dd623a7b 100644 --- a/docs/classes/Ellipse.html +++ b/docs/classes/Ellipse.html @@ -1,5 +1,5 @@ Ellipse | Detect-Collisions

    Class Ellipse<UserDataType>

    collider - ellipse

    -

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Constructors

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Constructors

    Properties

    Constructors

    Properties

    _group: number

    group for collision filtering

    -
    _radiusX: number

    inner initial params save

    -
    _radiusY: number
    _step: number
    angle: number

    body angle in radians use deg2rad to convert +

    Type Parameters

    • UserDataType = any

    Parameters

    Returns Ellipse<UserDataType>

    Properties

    _group: number

    group for collision filtering

    +
    _radiusX: number

    inner initial params save

    +
    _radiusY: number
    _step: number
    angle: number

    body angle in radians use deg2rad to convert move(speed) moves at 1 speed = 1px towards angle

    bbox: BBox

    bounding box cache, without padding

    -
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    -
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    -
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    -
    edges: SATVector[]
    isConvex = true

    ellipses are convex

    -
    isStatic: boolean

    static bodies don't move but they collide

    -
    isTrigger: boolean

    trigger bodies move but are like ghosts

    -
    maxX: number

    maximum x bound of body

    -
    maxY: number

    maximum y bound of body

    -
    minX: number

    minimum x bound of body

    -
    minY: number

    minimum y bound of body

    -
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    +
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    +
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    +
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    +
    edges: SATVector[]
    isConvex = true

    ellipses are convex

    +
    isStatic: boolean

    static bodies don't move but they collide

    +
    isTrigger: boolean

    trigger bodies move but are like ghosts

    +
    maxX: number

    maximum x bound of body

    +
    maxY: number

    maximum y bound of body

    +
    minX: number

    minimum x bound of body

    +
    minY: number

    minimum y bound of body

    +
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    padding: number

    bodies are not reinserted during update if their bbox didnt move outside bbox + padding

    -
    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    -
    scaleVector: Vector = ...

    scale Vector of body

    -
    system?: System<Body>

    reference to collision system

    -
    type: Ellipse = BodyType.Ellipse

    ellipse type

    -
    typeGroup: Ellipse = BodyGroup.Ellipse

    faster than type

    -
    userData?: any

    allows the user to set any misc data for client use

    -

    Accessors

    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    +
    scaleVector: Vector = ...

    scale Vector of body

    +
    system?: System<Body>

    reference to collision system

    +
    type: Ellipse = BodyType.Ellipse

    ellipse type

    +
    typeGroup: Ellipse = BodyGroup.Ellipse

    faster than type

    +
    userData?: any

    allows the user to set any misc data for client use

    +

    Accessors

    • get group(): number
    • group for collision filtering

      Based on Box2D (tutorial)

      Values in BodyGroup are predefined and used each the body type and @@ -96,7 +96,7 @@

      0x7fffffff // member of all groups (can interact with everyting)
       
      -
  • set group(group): void
  • group for collision filtering

    +
  • set group(group): void
  • group for collision filtering

    Based on Box2D (tutorial)

    Values in BodyGroup are predefined and used each the body type and @@ -106,39 +106,39 @@

    0x7fffffff // member of all groups (can interact with everyting)
     
    -
    • get isCentered(): boolean
    • is body centered?

      -

      Returns boolean

    • set isCentered(_isCentered): void
    • flag to set is body centered

      -

      Parameters

      • _isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      -

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      -

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      -

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      -

      Returns number

    Methods

    • inner function for after position change update aabb in system and convex inner polygons

      -

      Parameters

      • updateNow: boolean = ...

      Returns void

    • update the position of the decomposed convex polygons (if any), called +

    • get isCentered(): boolean
    • is body centered?

      +

      Returns boolean

    • set isCentered(_isCentered): void
    • flag to set is body centered

      +

      Parameters

      • _isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      +

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      +

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      +

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      +

      Returns number

    Methods

    • inner function for after position change update aabb in system and convex inner polygons

      +

      Parameters

      • updateNow: boolean = ...

      Returns void

    +

    Returns void

    diff --git a/docs/classes/Line.html b/docs/classes/Line.html index 4a7c11a7..691a8033 100644 --- a/docs/classes/Line.html +++ b/docs/classes/Line.html @@ -1,5 +1,5 @@ Line | Detect-Collisions

    Class Line<UserDataType>

    collider - line

    -

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Constructors

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Constructors

    Properties

    Constructors

    Properties

    _group: number

    group for collision filtering

    -
    angle: number

    body angle in radians use deg2rad to convert +

    Type Parameters

    • UserDataType = any

    Parameters

    Returns Line<UserDataType>

    Properties

    _group: number

    group for collision filtering

    +
    angle: number

    body angle in radians use deg2rad to convert move(speed) moves at 1 speed = 1px towards angle

    bbox: BBox

    bounding box cache, without padding

    -
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    -
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    -
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    -
    edges: SATVector[]
    isConvex = true

    line is convex

    -
    isStatic: boolean

    static bodies don't move but they collide

    -
    isTrigger: boolean

    trigger bodies move but are like ghosts

    -
    maxX: number

    maximum x bound of body

    -
    maxY: number

    maximum y bound of body

    -
    minX: number

    minimum x bound of body

    -
    minY: number

    minimum y bound of body

    -
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    +
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    +
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    +
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    +
    edges: SATVector[]
    isConvex = true

    line is convex

    +
    isStatic: boolean

    static bodies don't move but they collide

    +
    isTrigger: boolean

    trigger bodies move but are like ghosts

    +
    maxX: number

    maximum x bound of body

    +
    maxY: number

    maximum y bound of body

    +
    minX: number

    minimum x bound of body

    +
    minY: number

    minimum y bound of body

    +
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    padding: number

    bodies are not reinserted during update if their bbox didnt move outside bbox + padding

    -
    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    -
    scaleVector: Vector = ...

    scale Vector of body

    -
    system?: System<Body>

    reference to collision system

    -
    type: Line = BodyType.Line

    line type

    -
    typeGroup: Line = BodyGroup.Line

    faster than type

    -
    userData?: any

    allows the user to set any misc data for client use

    -

    Accessors

    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    +
    scaleVector: Vector = ...

    scale Vector of body

    +
    system?: System<Body>

    reference to collision system

    +
    type: Line = BodyType.Line

    line type

    +
    typeGroup: Line = BodyGroup.Line

    faster than type

    +
    userData?: any

    allows the user to set any misc data for client use

    +

    Accessors

    • get group(): number
    • group for collision filtering

      Based on Box2D (tutorial)

      Values in BodyGroup are predefined and used each the body type and @@ -90,7 +90,7 @@

      0x7fffffff // member of all groups (can interact with everyting)
       
      -
  • set group(group): void
  • group for collision filtering

    +
  • set group(group): void
  • group for collision filtering

    Based on Box2D (tutorial)

    Values in BodyGroup are predefined and used each the body type and @@ -100,32 +100,32 @@

    0x7fffffff // member of all groups (can interact with everyting)
     
    -
    • get isCentered(): boolean
    • is polygon centered?

      -

      Returns boolean

    • set isCentered(isCentered): void
    • flag to set is polygon centered

      -

      Parameters

      • isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      -

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      -

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      -

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      -

      Returns number

    Methods

    • inner function for after position change update aabb in system and convex inner polygons

      -

      Parameters

      • updateNow: boolean = ...

      Returns void

    • update the position of the decomposed convex polygons (if any), called +

    • get isCentered(): boolean
    • is polygon centered?

      +

      Returns boolean

    • set isCentered(isCentered): void
    • flag to set is polygon centered

      +

      Parameters

      • isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      +

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      +

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      +

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      +

      Returns number

    Methods

    • inner function for after position change update aabb in system and convex inner polygons

      +

      Parameters

      • updateNow: boolean = ...

      Returns void

    +

    Returns void

    diff --git a/docs/classes/Point.html b/docs/classes/Point.html index 60181aaf..6219b79a 100644 --- a/docs/classes/Point.html +++ b/docs/classes/Point.html @@ -1,5 +1,5 @@ Point | Detect-Collisions

    Class Point<UserDataType>

    collider - point (very tiny box)

    -

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Constructors

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Constructors

    Properties

    Constructors

    Properties

    _group: number

    group for collision filtering

    -
    _height: number

    inner height

    -
    _width: number

    inner width

    -
    angle: number

    body angle in radians use deg2rad to convert +

    Type Parameters

    • UserDataType = any

    Parameters

    Returns Point<UserDataType>

    Properties

    _group: number

    group for collision filtering

    +
    _height: number

    inner height

    +
    _width: number

    inner width

    +
    angle: number

    body angle in radians use deg2rad to convert move(speed) moves at 1 speed = 1px towards angle

    bbox: BBox

    bounding box cache, without padding

    -
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    -
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    -
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    -
    edges: SATVector[]
    isConvex = true

    boxes are convex

    -
    isStatic: boolean

    static bodies don't move but they collide

    -
    isTrigger: boolean

    trigger bodies move but are like ghosts

    -
    maxX: number

    maximum x bound of body

    -
    maxY: number

    maximum y bound of body

    -
    minX: number

    minimum x bound of body

    -
    minY: number

    minimum y bound of body

    -
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    +
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    +
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    +
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    +
    edges: SATVector[]
    isConvex = true

    boxes are convex

    +
    isStatic: boolean

    static bodies don't move but they collide

    +
    isTrigger: boolean

    trigger bodies move but are like ghosts

    +
    maxX: number

    maximum x bound of body

    +
    maxY: number

    maximum y bound of body

    +
    minX: number

    minimum x bound of body

    +
    minY: number

    minimum y bound of body

    +
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    padding: number

    bodies are not reinserted during update if their bbox didnt move outside bbox + padding

    -
    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    -
    scaleVector: Vector = ...

    scale Vector of body

    -
    system?: System<Body>

    reference to collision system

    -
    type: Point = BodyType.Point

    point type

    -
    typeGroup: Point = BodyGroup.Point

    faster than type

    -
    userData?: any

    allows the user to set any misc data for client use

    -

    Accessors

    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    +
    scaleVector: Vector = ...

    scale Vector of body

    +
    system?: System<Body>

    reference to collision system

    +
    type: Point = BodyType.Point

    point type

    +
    typeGroup: Point = BodyGroup.Point

    faster than type

    +
    userData?: any

    allows the user to set any misc data for client use

    +

    Accessors

    • get group(): number
    • group for collision filtering

      Based on Box2D (tutorial)

      Values in BodyGroup are predefined and used each the body type and @@ -95,7 +95,7 @@

      0x7fffffff // member of all groups (can interact with everyting)
       
      -
  • set group(group): void
  • group for collision filtering

    +
  • set group(group): void
  • group for collision filtering

    Based on Box2D (tutorial)

    Values in BodyGroup are predefined and used each the body type and @@ -105,38 +105,38 @@

    0x7fffffff // member of all groups (can interact with everyting)
     
    -
    • get height(): number
    • get box height

      -

      Returns number

    • set height(height): void
    • set box height, update points

      -

      Parameters

      • height: number

      Returns void

    • get isCentered(): boolean
    • is polygon centered?

      -

      Returns boolean

    • set isCentered(isCentered): void
    • flag to set is polygon centered

      -

      Parameters

      • isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      -

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      -

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      -

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      -

      Returns number

    • get width(): number
    • get box width

      -

      Returns number

    • set width(width): void
    • set box width, update points

      -

      Parameters

      • width: number

      Returns void

    Methods

    • after setting width/height update translate +

    • get height(): number
    • get box height

      +

      Returns number

    • set height(height): void
    • set box height, update points

      +

      Parameters

      • height: number

      Returns void

    • get isCentered(): boolean
    • is polygon centered?

      +

      Returns boolean

    • set isCentered(isCentered): void
    • flag to set is polygon centered

      +

      Parameters

      • isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      +

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      +

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      +

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      +

      Returns number

    • get width(): number
    • get box width

      +

      Returns number

    • set width(width): void
    • set box width, update points

      +

      Parameters

      • width: number

      Returns void

    Methods

    • Draws exact collider on canvas context

      -

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • Draws Bounding Box on canvas context

      -

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • inner function for after position change update aabb in system and convex inner polygons

      -

      Parameters

      • updateNow: boolean = ...

      Returns void

    • Draws exact collider on canvas context

      +

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • Draws Bounding Box on canvas context

      +

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • inner function for after position change update aabb in system and convex inner polygons

      +

      Parameters

      • updateNow: boolean = ...

      Returns void

    +

    Returns void

    diff --git a/docs/classes/Polygon.html b/docs/classes/Polygon.html index edf09484..77e17071 100644 --- a/docs/classes/Polygon.html +++ b/docs/classes/Polygon.html @@ -1,5 +1,5 @@ Polygon | Detect-Collisions

    Class Polygon<UserDataType>

    collider - polygon

    -

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Implements

    Constructors

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Implements

    Constructors

    Properties

    Constructors

    Properties

    _group: number

    group for collision filtering

    -
    angle: number

    body angle in radians use deg2rad to convert +

    Type Parameters

    • UserDataType = any

    Parameters

    Returns Polygon<UserDataType>

    Properties

    _group: number

    group for collision filtering

    +
    angle: number

    body angle in radians use deg2rad to convert move(speed) moves at 1 speed = 1px towards angle

    bbox: BBox

    bounding box cache, without padding

    -
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    -
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    -
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    -
    edges: SATVector[]
    isConvex: boolean

    is it a convex polgyon as opposed to a hollow inside (concave) polygon

    -
    isStatic: boolean

    static bodies don't move but they collide

    -
    isTrigger: boolean

    trigger bodies move but are like ghosts

    -
    maxX: number

    maximum x bound of body

    -
    maxY: number

    maximum y bound of body

    -
    minX: number

    minimum x bound of body

    -
    minY: number

    minimum y bound of body

    -
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    +
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    +
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    +
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    +
    edges: SATVector[]
    isConvex: boolean

    is it a convex polgyon as opposed to a hollow inside (concave) polygon

    +
    isStatic: boolean

    static bodies don't move but they collide

    +
    isTrigger: boolean

    trigger bodies move but are like ghosts

    +
    maxX: number

    maximum x bound of body

    +
    maxY: number

    maximum y bound of body

    +
    minX: number

    minimum x bound of body

    +
    minY: number

    minimum y bound of body

    +
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    padding: number

    bodies are not reinserted during update if their bbox didnt move outside bbox + padding

    -
    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    -
    scaleVector: Vector = ...

    scale Vector of body

    -
    system?: System<Body>

    reference to collision system

    -
    type:
        | Ellipse
        | Polygon
        | Box
        | Line
        | Point = BodyType.Polygon

    type of body

    -
    typeGroup:
        | Ellipse
        | Polygon
        | Box
        | Line
        | Point = BodyGroup.Polygon

    faster than type

    -
    userData?: any

    allows the user to set any misc data for client use

    -

    Accessors

    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    +
    scaleVector: Vector = ...

    scale Vector of body

    +
    system?: System<Body>

    reference to collision system

    +
    type:
        | Ellipse
        | Polygon
        | Box
        | Line
        | Point = BodyType.Polygon

    type of body

    +
    typeGroup:
        | Ellipse
        | Polygon
        | Box
        | Line
        | Point = BodyGroup.Polygon

    faster than type

    +
    userData?: any

    allows the user to set any misc data for client use

    +

    Accessors

    • get group(): number
    • group for collision filtering

      Based on Box2D (tutorial)

      Values in BodyGroup are predefined and used each the body type and @@ -88,7 +88,7 @@

      0x7fffffff // member of all groups (can interact with everyting)
       
      -
  • set group(group): void
  • group for collision filtering

    +
  • set group(group): void
  • group for collision filtering

    Based on Box2D (tutorial)

    Values in BodyGroup are predefined and used each the body type and @@ -98,32 +98,32 @@

    0x7fffffff // member of all groups (can interact with everyting)
     
    -
    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      -

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      -

      Returns number

    Methods

    • if true, polygon is not an invalid, self-crossing polygon

      -

      Returns boolean

    • update instantly or mark as dirty

      -

      Parameters

      • updateNow: boolean = false

      Returns void

    • inner function for after position change update aabb in system and convex inner polygons

      -

      Parameters

      • updateNow: boolean = ...

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      +

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      +

      Returns number

    Methods

    • if true, polygon is not an invalid, self-crossing polygon

      +

      Returns boolean

    • update instantly or mark as dirty

      +

      Parameters

      • updateNow: boolean = false

      Returns void

    • inner function for after position change update aabb in system and convex inner polygons

      +

      Parameters

      • updateNow: boolean = ...

      Returns void

    • update the position of the decomposed convex polygons (if any), called after the position of the body has changed

      -

      Returns void

    +

    Returns void

    diff --git a/docs/classes/System.html b/docs/classes/System.html index fe206f34..0d4ef3f1 100644 --- a/docs/classes/System.html +++ b/docs/classes/System.html @@ -47,29 +47,29 @@ traverse update updateBody -

    Constructors

    Properties

    _maxEntries: number
    _minEntries: number
    ray: Line<any>

    for raycasting

    +

    Constructors

    Properties

    _maxEntries: number
    _minEntries: number
    ray: Line<any>

    for raycasting

    response: Response = ...

    the last collision result

    Methods

    • Parameters

      • bbox: any
      • path: any
      • level: any

      Returns void

    • Parameters

      • node: any
      • result: any

      Returns any

    • Parameters

      • node: any
      • m: any
      • M: any
      • compare: any

      Returns number

    • Parameters

      • items: any
      • left: any
      • right: any
      • height: any

      Returns {
          children: any;
          height: number;
          leaf: boolean;
          maxX: number;
          maxY: number;
          minX: number;
          minY: number;
      }

      • children: any
      • height: number
      • leaf: boolean
      • maxX: number
      • maxY: number
      • minX: number
      • minY: number
    • Parameters

      • node: any
      • m: any
      • M: any

      Returns void

    • Parameters

      • node: any
      • m: any
      • M: any

      Returns any

    • Parameters

      • bbox: any
      • node: any
      • level: any
      • path: any

      Returns any

    • Parameters

      • item: any
      • level: any
      • isNode: any

      Returns void

    • Parameters

      • insertPath: any
      • level: any

      Returns void

    • Parameters

      • node: any
      • newNode: any

      Returns void

    • check do 2 objects collide

      Parameters

      Returns boolean

    • Parameters

      • bbox: any

      Returns boolean

    • Parameters

      • a: any
      • b: any

      Returns number

    • Parameters

      • a: any
      • b: any

      Returns number

    • create box at position with options and add to system

      -

      Type Parameters

      • TBox extends Box<any>

      Parameters

      Returns TBox

    • create ellipse at position with options and add to system

      -

      Type Parameters

      Parameters

      Returns TEllipse

    • draw exact bodies colliders outline

      -

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • draw bounding boxes hierarchy outline

      -

      Parameters

      • context: CanvasRenderingContext2D
      • isTrigger: boolean = true

      Returns void

    • Parameters

      • bbox: any

      Returns boolean

    • Parameters

      • a: any
      • b: any

      Returns number

    • Parameters

      • a: any
      • b: any

      Returns number

    • draw exact bodies colliders outline

      +

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • draw bounding boxes hierarchy outline

      +

      Parameters

      • context: CanvasRenderingContext2D
      • isTrigger: boolean = true

      Returns void

    • get object potential colliders

      Parameters

      Returns TBody[]

      because it's slower to use than checkOne() or checkAll()

      -
    • re-insert body into collision tree and update its bbox +

    • re-insert body into collision tree and update its bbox every body can be part of only one system

      Parameters

      Returns this

    • remove body aabb from collision tree

      -

      Parameters

      Returns this

    • separate (move away) bodies

      +

      Parameters

      Returns this

    • separate (move away) 1 body, with optional callback before collision

      Parameters

      Returns void

    • used to find body deep inside data with finder function returning boolean found or not

      -

      Parameters

      Returns undefined | TBody

    • update all bodies aabb

      -

      Returns void

    • updates body in collision tree

      -

      Parameters

      Returns void

    +

    Parameters

    Returns undefined | TBody

    • update all bodies aabb

      +

      Returns void

    • updates body in collision tree

      +

      Parameters

      Returns void

    diff --git a/docs/demo/demo.js b/docs/demo/demo.js index 9d5e33de..d8b609c5 100644 --- a/docs/demo/demo.js +++ b/docs/demo/demo.js @@ -2067,48 +2067,54 @@ class BaseSystem extends model_1.RBush { /** * create point at position with options and add to system */ - createPoint(position, options) { - const point = new point_1.Point(position, options); + createPoint(position, options, Class) { + const PointClass = Class || point_1.Point; + const point = new PointClass(position, options); this.insert(point); return point; } /** * create line at position with options and add to system */ - createLine(start, end, options) { - const line = new line_1.Line(start, end, options); + createLine(start, end, options, Class) { + const LineClass = Class || line_1.Line; + const line = new LineClass(start, end, options); this.insert(line); return line; } /** * create circle at position with options and add to system */ - createCircle(position, radius, options) { - const circle = new circle_1.Circle(position, radius, options); + createCircle(position, radius, options, Class) { + const CircleClass = Class || circle_1.Circle; + const circle = new CircleClass(position, radius, options); this.insert(circle); return circle; } /** * create box at position with options and add to system */ - createBox(position, width, height, options) { - const box = new box_1.Box(position, width, height, options); + createBox(position, width, height, options, Class) { + const BoxClass = Class || box_1.Box; + const box = new BoxClass(position, width, height, options); this.insert(box); return box; } /** * create ellipse at position with options and add to system */ - createEllipse(position, radiusX, radiusY = radiusX, step, options) { - const ellipse = new ellipse_1.Ellipse(position, radiusX, radiusY, step, options); + createEllipse(position, radiusX, radiusY = radiusX, step, options, Class) { + const EllipseClass = Class || ellipse_1.Ellipse; + const ellipse = new EllipseClass(position, radiusX, radiusY, step, options); this.insert(ellipse); return ellipse; } /** * create polygon at position with options and add to system */ - createPolygon(position, points, options) { - const polygon = new polygon_1.Polygon(position, points, options); + createPolygon(position, points, options, Class) { + const PolygonClass = Class || polygon_1.Polygon; + const polygon = new PolygonClass(position, points, options); this.insert(polygon); return polygon; } @@ -2769,9 +2775,8 @@ exports.Point = Point; "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.Polygon = exports.isSimple = void 0; +exports.Polygon = void 0; const poly_decomp_es_1 = __webpack_require__(/*! poly-decomp-es */ "./node_modules/poly-decomp-es/dist/poly-decomp-es.js"); -Object.defineProperty(exports, "isSimple", ({ enumerable: true, get: function () { return poly_decomp_es_1.isSimple; } })); const model_1 = __webpack_require__(/*! ../model */ "./src/model.ts"); const optimized_1 = __webpack_require__(/*! ../optimized */ "./src/optimized.ts"); const utils_1 = __webpack_require__(/*! ../utils */ "./src/utils.ts"); diff --git a/docs/interfaces/BoxConstructor.html b/docs/interfaces/BoxConstructor.html new file mode 100644 index 00000000..5ffb3318 --- /dev/null +++ b/docs/interfaces/BoxConstructor.html @@ -0,0 +1,2 @@ +BoxConstructor | Detect-Collisions

    Interface BoxConstructor<TBox>

    interface BoxConstructor<TBox> {
        new BoxConstructornew (position: PotentialVector, width: number, height: number, options?: BodyOptions<any>): TBox;
    }

    Type Parameters

    • TBox extends Box

    Constructors

    Constructors

    diff --git a/docs/interfaces/CircleConstructor.html b/docs/interfaces/CircleConstructor.html new file mode 100644 index 00000000..0ecfd83f --- /dev/null +++ b/docs/interfaces/CircleConstructor.html @@ -0,0 +1,2 @@ +CircleConstructor | Detect-Collisions

    Interface CircleConstructor<TCircle>

    interface CircleConstructor<TCircle> {
        new CircleConstructornew (position: PotentialVector, radius: number, options?: BodyOptions<any>): TCircle;
    }

    Type Parameters

    Constructors

    Constructors

    diff --git a/docs/interfaces/EllipseConstructor.html b/docs/interfaces/EllipseConstructor.html new file mode 100644 index 00000000..c668d3e4 --- /dev/null +++ b/docs/interfaces/EllipseConstructor.html @@ -0,0 +1,2 @@ +EllipseConstructor | Detect-Collisions

    Interface EllipseConstructor<TEllipse>

    interface EllipseConstructor<TEllipse> {
        new EllipseConstructornew (position: PotentialVector, radiusX: number, radiusY?: number, step?: number, options?: BodyOptions<any>): TEllipse;
    }

    Type Parameters

    Constructors

    Constructors

    diff --git a/docs/interfaces/LineConstructor.html b/docs/interfaces/LineConstructor.html new file mode 100644 index 00000000..11aefaca --- /dev/null +++ b/docs/interfaces/LineConstructor.html @@ -0,0 +1,2 @@ +LineConstructor | Detect-Collisions

    Interface LineConstructor<TLine>

    interface LineConstructor<TLine> {
        new LineConstructornew (start: Vector, end: Vector, options?: BodyOptions<any>): TLine;
    }

    Type Parameters

    Constructors

    Constructors

    diff --git a/docs/interfaces/PointConstructor.html b/docs/interfaces/PointConstructor.html new file mode 100644 index 00000000..0fbd4ae0 --- /dev/null +++ b/docs/interfaces/PointConstructor.html @@ -0,0 +1,2 @@ +PointConstructor | Detect-Collisions

    Interface PointConstructor<TPoint>

    interface PointConstructor<TPoint> {
        new PointConstructornew (position: PotentialVector, options?: BodyOptions<any>): TPoint;
    }

    Type Parameters

    Constructors

    Constructors

    diff --git a/docs/interfaces/PolygonConstructor.html b/docs/interfaces/PolygonConstructor.html new file mode 100644 index 00000000..a078e91b --- /dev/null +++ b/docs/interfaces/PolygonConstructor.html @@ -0,0 +1,2 @@ +PolygonConstructor | Detect-Collisions

    Interface PolygonConstructor<TPolygon>

    interface PolygonConstructor<TPolygon> {
        new PolygonConstructornew (position: PotentialVector, points: PotentialVector[], options?: BodyOptions<any>): TPolygon;
    }

    Type Parameters

    Constructors

    Constructors

    diff --git a/docs/modules.html b/docs/modules.html index ba2ebba2..ee99e012 100644 --- a/docs/modules.html +++ b/docs/modules.html @@ -15,9 +15,15 @@

    Interfaces

    BBox BodyOptions BodyProps +BoxConstructor ChildrenData +CircleConstructor Data +EllipseConstructor GetAABBAsBox +LineConstructor +PointConstructor +PolygonConstructor PotentialVector RaycastHit Vector diff --git a/package.json b/package.json index 52255f61..b98034d4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "detect-collisions", - "version": "9.19.1", + "version": "9.20.0", "description": "Detect collisions between different shapes such as Points, Lines, Boxes, Polygons (including concave), Ellipses, and Circles. Features include RayCasting and support for offsets, rotation, scaling, bounding box padding, with options for static and trigger bodies (non-colliding).", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/base-system.ts b/src/base-system.ts index f9516599..ca51bf3a 100644 --- a/src/base-system.ts +++ b/src/base-system.ts @@ -13,19 +13,20 @@ import { import { filter, forEach } from "./optimized"; import { bodyMoved, drawBVH } from "./utils"; -import { Box } from "./bodies/box"; -import { Circle } from "./bodies/circle"; -import { Ellipse } from "./bodies/ellipse"; -import { Line } from "./bodies/line"; -import { Point } from "./bodies/point"; -import { Polygon } from "./bodies/polygon"; +import { Box, BoxConstructor } from "./bodies/box"; +import { Circle, CircleConstructor } from "./bodies/circle"; +import { Ellipse, EllipseConstructor } from "./bodies/ellipse"; +import { Line, LineConstructor } from "./bodies/line"; +import { Point, PointConstructor } from "./bodies/point"; +import { Polygon, PolygonConstructor } from "./bodies/polygon"; /** * very base collision system (create, insert, update, draw, remove) */ export class BaseSystem extends RBush - implements Data { + implements Data +{ data!: ChildrenData; /** @@ -33,13 +34,15 @@ export class BaseSystem */ createPoint( position: PotentialVector, - options?: BodyOptions - ): TPoint { - const point = new Point(position, options); + options?: BodyOptions, + Class?: PointConstructor + ): TPoint | Point { + const PointClass = Class || Point; + const point = new PointClass(position, options); this.insert(point as TBody); - return point as TPoint; + return point; } /** @@ -48,13 +51,15 @@ export class BaseSystem createLine( start: Vector, end: Vector, - options?: BodyOptions - ): TLine { - const line = new Line(start, end, options); + options?: BodyOptions, + Class?: LineConstructor + ): TLine | Line { + const LineClass = Class || Line; + const line = new LineClass(start, end, options); this.insert(line as TBody); - return line as TLine; + return line; } /** @@ -63,13 +68,15 @@ export class BaseSystem createCircle( position: PotentialVector, radius: number, - options?: BodyOptions - ): TCircle { - const circle = new Circle(position, radius, options); + options?: BodyOptions, + Class?: CircleConstructor + ): TCircle | Circle { + const CircleClass = Class || Circle; + const circle = new CircleClass(position, radius, options); this.insert(circle as TBody); - return circle as TCircle; + return circle; } /** @@ -79,13 +86,15 @@ export class BaseSystem position: PotentialVector, width: number, height: number, - options?: BodyOptions - ): TBox { - const box = new Box(position, width, height, options); + options?: BodyOptions, + Class?: BoxConstructor + ): TBox | Box { + const BoxClass = Class || Box; + const box = new BoxClass(position, width, height, options); this.insert(box as TBody); - return box as TBox; + return box; } /** @@ -96,13 +105,15 @@ export class BaseSystem radiusX: number, radiusY: number = radiusX, step?: number, - options?: BodyOptions - ): TEllipse { - const ellipse = new Ellipse(position, radiusX, radiusY, step, options); + options?: BodyOptions, + Class?: EllipseConstructor + ): TEllipse | Ellipse { + const EllipseClass = Class || Ellipse; + const ellipse = new EllipseClass(position, radiusX, radiusY, step, options); this.insert(ellipse as TBody); - return ellipse as TEllipse; + return ellipse; } /** @@ -111,13 +122,15 @@ export class BaseSystem createPolygon( position: PotentialVector, points: PotentialVector[], - options?: BodyOptions - ): TPolygon { - const polygon = new Polygon(position, points, options); + options?: BodyOptions, + Class?: PolygonConstructor + ): TPolygon | Polygon { + const PolygonClass = Class || Polygon; + const polygon = new PolygonClass(position, points, options); this.insert(polygon as TBody); - return polygon as TPolygon; + return polygon; } /** diff --git a/src/bodies/box.ts b/src/bodies/box.ts index e277c90f..a56d39ff 100644 --- a/src/bodies/box.ts +++ b/src/bodies/box.ts @@ -3,6 +3,15 @@ import { BodyGroup, BodyOptions, BodyType, PotentialVector } from "../model"; import { createBox } from "../utils"; import { Polygon } from "./polygon"; +export interface BoxConstructor { + new ( + position: PotentialVector, + width: number, + height: number, + options?: BodyOptions + ): TBox; +} + /** * collider - box */ @@ -39,7 +48,7 @@ export class Box extends Polygon { position: PotentialVector, width: number, height: number, - options?: BodyOptions, + options?: BodyOptions ) { super(position, createBox(width, height), options); diff --git a/src/bodies/circle.ts b/src/bodies/circle.ts index 428c967e..3e44db97 100644 --- a/src/bodies/circle.ts +++ b/src/bodies/circle.ts @@ -20,12 +20,21 @@ import { import { Circle as SATCircle } from "sat"; import { System } from "../system"; +export interface CircleConstructor { + new ( + position: PotentialVector, + radius: number, + options?: BodyOptions + ): TCircle; +} + /** * collider - circle */ export class Circle extends SATCircle - implements BBox, BodyProps { + implements BBox, BodyProps +{ /** * minimum x bound of body */ @@ -132,7 +141,7 @@ export class Circle constructor( position: PotentialVector, radius: number, - options?: BodyOptions, + options?: BodyOptions ) { super(ensureVectorPoint(position), radius); diff --git a/src/bodies/ellipse.ts b/src/bodies/ellipse.ts index 7009e49c..fac59e39 100644 --- a/src/bodies/ellipse.ts +++ b/src/bodies/ellipse.ts @@ -3,6 +3,16 @@ import { BodyGroup, BodyOptions, BodyType, PotentialVector } from "../model"; import { createEllipse } from "../utils"; import { Polygon } from "./polygon"; +export interface EllipseConstructor { + new ( + position: PotentialVector, + radiusX: number, + radiusY?: number, + step?: number, + options?: BodyOptions + ): TEllipse; +} + /** * collider - ellipse */ @@ -37,7 +47,7 @@ export class Ellipse extends Polygon { radiusX: number, radiusY: number = radiusX, step: number = (radiusX + radiusY) / Math.PI, - options?: BodyOptions, + options?: BodyOptions ) { super(position, createEllipse(radiusX, radiusY, step), options); diff --git a/src/bodies/line.ts b/src/bodies/line.ts index 37763390..dcbab9c5 100644 --- a/src/bodies/line.ts +++ b/src/bodies/line.ts @@ -3,6 +3,10 @@ import { BodyGroup, BodyOptions, BodyType, Vector } from "../model"; import { Vector as SATVector } from "sat"; import { Polygon } from "./polygon"; +export interface LineConstructor { + new (start: Vector, end: Vector, options?: BodyOptions): TLine; +} + /** * collider - line */ @@ -32,7 +36,7 @@ export class Line extends Polygon { { x: 0, y: 0 }, { x: end.x - start.x, y: end.y - start.y }, ], - options, + options ); if (this.calcPoints.length === 1 || !end) { @@ -76,7 +80,7 @@ export class Line extends Polygon { getCentroid(): SATVector { return new SATVector( (this.end.x - this.start.x) / 2, - (this.end.y - this.start.y) / 2, + (this.end.y - this.start.y) / 2 ); } diff --git a/src/bodies/point.ts b/src/bodies/point.ts index 5c164260..260b3ef5 100644 --- a/src/bodies/point.ts +++ b/src/bodies/point.ts @@ -3,6 +3,10 @@ import { BodyGroup, BodyOptions, BodyType, PotentialVector } from "../model"; import { ensureVectorPoint } from "../utils"; import { Box } from "./box"; +export interface PointConstructor { + new (position: PotentialVector, options?: BodyOptions): TPoint; +} + /** * collider - point (very tiny box) */ diff --git a/src/bodies/polygon.ts b/src/bodies/polygon.ts index ffa5208c..1c51571f 100644 --- a/src/bodies/polygon.ts +++ b/src/bodies/polygon.ts @@ -28,7 +28,13 @@ import { import { Polygon as SATPolygon } from "sat"; import { System } from "../system"; -export { isSimple }; +export interface PolygonConstructor { + new ( + position: PotentialVector, + points: PotentialVector[], + options?: BodyOptions, + ): TPolygon; +} /** * collider - polygon diff --git a/src/system.spec.js b/src/system.spec.js index dc0c905b..935667b7 100644 --- a/src/system.spec.js +++ b/src/system.spec.js @@ -184,4 +184,21 @@ describe("GIVEN System", () => { expectToBeNear(hit.point.y, 70, 10); }); }); + + it("THEN I can provide custom class to body create functions", () => { + const { System, Polygon } = require("."); + const physics = new System(); + + class MyPolygon extends Polygon { + constructor(position, points, options) { + super(position, points, options); + this.foo = "bar"; + } + } + + // create minimal MyPolygon and insert to system + const myPolygon = physics.createPolygon({}, [{}], {}, MyPolygon); + + expect(myPolygon.foo).toBe("bar"); + }); });