From c1740e3f7cbd8d74bbbf511e476a2d8975b59bb4 Mon Sep 17 00:00:00 2001 From: Alberto Quiles Boix Date: Thu, 20 Jun 2024 19:49:26 +0200 Subject: [PATCH 1/2] fix #20 --- examples/example/src/app.component.ts | 54 ++++++++++++++++++++- src/components/core/graphics.component.ts | 16 +++++- src/components/prefabs/box.component.ts | 34 +++++++++++++ src/components/prefabs/capsule.component.ts | 33 +++++++++++++ src/components/prefabs/index.ts | 2 + src/enums/shapes.enum.ts | 2 + src/types/shapes/core.types.ts | 18 ++++++- src/types/shapes/prefabs.types.ts | 20 ++++++++ src/utils/shapes.utils.ts | 11 +++++ 9 files changed, 187 insertions(+), 3 deletions(-) create mode 100644 src/components/prefabs/box.component.ts create mode 100644 src/components/prefabs/capsule.component.ts diff --git a/examples/example/src/app.component.ts b/examples/example/src/app.component.ts index 1148f07..49b9fe2 100644 --- a/examples/example/src/app.component.ts +++ b/examples/example/src/app.component.ts @@ -8,8 +8,10 @@ import { EventMode, global, plane, + box, sprite, world, + capsule, } from "@tulib/tulip"; import { flyComponent } from "fly.component"; @@ -104,7 +106,7 @@ export const appComponent: AsyncComponent = async () => { props: { physics: { enabled: true, - gravity: { x: 0, y: -0 }, + gravity: { x: 0, y: -0.25 }, }, }, }); @@ -180,5 +182,55 @@ export const appComponent: AsyncComponent = async () => { $container.add($world2); + // Shapes + const colors = [0x219c90, 0xfff455, 0xffc700, 0xee4e4e]; + + colors.forEach((color, i) => { + const $capsule = capsule({ + props: { + color, + length: 100 - i * 10, + radius: 10 - i * 1.2, + mass: 2, + }, + }); + $capsule.setPosition({ x: 800, y: 100 - i * 15 }); + $world2.add($capsule); + + const $box = box({ + props: { + color: color, + width: 50 - i * 10, + height: 50 - i * 10, + mass: 2, + }, + }); + $box.setPosition({ x: 680, y: 80 - i * 60 }); + $world2.add($box); + + const $circle = circle({ + props: { + color, + mass: 2, + size: 10, + }, + }); + $circle.setPosition({ x: 600, y: 50 - i * 10 }); + $world2.add($circle); + }); + + const $plane3 = plane({ + position: { + x: 400, + y: 300, + }, + angle: 0, + props: { + color: 0xff00ff, + }, + alpha: 0.5, + }); + $world2.add($plane3); + return $container.getComponent(appComponent); }; diff --git a/src/components/core/graphics.component.ts b/src/components/core/graphics.component.ts index 271be5a..4eec9cf 100644 --- a/src/components/core/graphics.component.ts +++ b/src/components/core/graphics.component.ts @@ -14,6 +14,7 @@ type Props = { radius?: number; polygon?: number[]; + length?: number; } & ContainerProps; type Mutable = { @@ -22,6 +23,7 @@ type Mutable = { setPolygon: (polygon: number[]) => void; setCircle: (radius: number) => void; + setCapsule: (length: number, radius: number) => void; } & DisplayObjectMutable; export const graphics: Component = (originalProps) => { @@ -29,6 +31,7 @@ export const graphics: Component = (originalProps) => { color: defaultColor, radius: defaultRadius, polygon: defaultPolygon, + length: defaultLength, label, ...props } = originalProps; @@ -38,6 +41,7 @@ export const graphics: Component = (originalProps) => { let $color = defaultColor; let $polygon = defaultPolygon; let $radius = defaultRadius; + let $length = defaultLength; const graphics = new PIXI.Graphics() as Graphics; @@ -62,6 +66,14 @@ export const graphics: Component = (originalProps) => { graphics.clear(); graphics.circle(0, 0, radius).fill({ color: 0xffffff }); }; + const setCapsule = (length: number, radius: number) => { + graphics.clear(); + graphics + .rect(-length / 2, -radius, length, 2 * radius) + .circle(-length / 2, 0, radius) + .circle(length / 2, 0, radius) + .fill({ color: 0xffffff }); + }; const $getRaw = (): Props => { return { @@ -82,7 +94,8 @@ export const graphics: Component = (originalProps) => { $color !== undefined && setColor($color); $polygon && setPolygon($polygon); - $radius && setCircle($radius); + $radius && !$length && setCircle($radius); + $radius && $length && setCapsule($length, $radius); const mutable: InternalMutable = { // container @@ -93,6 +106,7 @@ export const graphics: Component = (originalProps) => { setPolygon, setCircle, + setCapsule, // @ts-ignore getComponent: (component) => { diff --git a/src/components/prefabs/box.component.ts b/src/components/prefabs/box.component.ts new file mode 100644 index 0000000..2b0a6b9 --- /dev/null +++ b/src/components/prefabs/box.component.ts @@ -0,0 +1,34 @@ +import { body, container, graphics } from "../"; +import { Shape } from "../../enums"; +import { BoxProps, Component, ContainerMutable } from "../../types"; + +export const box: Component = (props) => { + const $container = container({ + ...props, + }); + + const { + props: { color, width, height, mass, material }, + } = $container.getProps(); + + const $box = graphics({ + color, + }); + $box.setPolygon([0, 0, width, 0, width, height, 0, height]); + $box.setPivot({ x: width / 2, y: height / 2 }); + $container.add($box); + + const spriteBody = body({ + mass, + material, + }); + spriteBody.addShape({ + type: Shape.BOX, + width, + height, + }); + + $container.setBody(spriteBody); + + return $container.getComponent(box); +}; diff --git a/src/components/prefabs/capsule.component.ts b/src/components/prefabs/capsule.component.ts new file mode 100644 index 0000000..159810b --- /dev/null +++ b/src/components/prefabs/capsule.component.ts @@ -0,0 +1,33 @@ +import { body, container, graphics } from "../"; +import { Shape } from "../../enums"; +import { CapsuleProps, Component, ContainerMutable } from "../../types"; + +export const capsule: Component = (props) => { + const $container = container({ + ...props, + }); + + const { + props: { color, length, radius, mass, material }, + } = $container.getProps(); + + const $capsule = graphics({ + color, + }); + $capsule.setCapsule(length, radius); + $container.add($capsule); + + const spriteBody = body({ + mass, + material, + }); + spriteBody.addShape({ + type: Shape.CAPSULE, + radius, + length, + }); + + $container.setBody(spriteBody); + + return $container.getComponent(capsule); +}; diff --git a/src/components/prefabs/index.ts b/src/components/prefabs/index.ts index 8221eec..d0ef50b 100644 --- a/src/components/prefabs/index.ts +++ b/src/components/prefabs/index.ts @@ -1,2 +1,4 @@ export * from "./plane.component"; export * from "./circle.component"; +export * from "./box.component"; +export * from "./capsule.component"; diff --git a/src/enums/shapes.enum.ts b/src/enums/shapes.enum.ts index 8e2fc66..ce1e060 100644 --- a/src/enums/shapes.enum.ts +++ b/src/enums/shapes.enum.ts @@ -1,4 +1,6 @@ export enum Shape { CIRCLE, PLANE, + BOX, + CAPSULE, } diff --git a/src/types/shapes/core.types.ts b/src/types/shapes/core.types.ts index 674936c..9f023b0 100644 --- a/src/types/shapes/core.types.ts +++ b/src/types/shapes/core.types.ts @@ -20,4 +20,20 @@ export type CircleShapeProps = { radius?: number; } & ShapeProps; -export type Shapes = PlaneShapeProps | CircleShapeProps; +export type BoxShapeProps = { + type: Shape.BOX; + width: number; + height: number; +} & ShapeProps; + +export type CapsuleShapeProps = { + type: Shape.CAPSULE; + length: number; + radius: number; +} & ShapeProps; + +export type Shapes = + | PlaneShapeProps + | CircleShapeProps + | BoxShapeProps + | CapsuleShapeProps; diff --git a/src/types/shapes/prefabs.types.ts b/src/types/shapes/prefabs.types.ts index c47d803..de60a8d 100644 --- a/src/types/shapes/prefabs.types.ts +++ b/src/types/shapes/prefabs.types.ts @@ -9,3 +9,23 @@ export type CircleProps = { material?: BodyMaterialProps; }; } & ContainerProps; + +export type BoxProps = { + props: { + color: number; + width: number; + height: number; + mass: number; + material?: BodyMaterialProps; + }; +} & ContainerProps; + +export type CapsuleProps = { + props: { + color: number; + length: number; + radius: number; + mass: number; + material?: BodyMaterialProps; + }; +} & ContainerProps; diff --git a/src/utils/shapes.utils.ts b/src/utils/shapes.utils.ts index 1ac7523..2216d18 100644 --- a/src/utils/shapes.utils.ts +++ b/src/utils/shapes.utils.ts @@ -1,5 +1,7 @@ import p2 from "p2"; import { + BoxShapeProps, + CapsuleShapeProps, CircleShapeProps, PlaneShapeProps, ShapeProps, @@ -20,6 +22,9 @@ const getBaseProps = ({ export const getShape = ({ type, ...props }: Shapes) => { if (type === Shape.CIRCLE) return getCircleShape(props as CircleShapeProps); if (type === Shape.PLANE) return getPlaneShape(props as PlaneShapeProps); + if (type === Shape.BOX) return getBoxShape(props as BoxShapeProps); + if (type === Shape.CAPSULE) + return getCapsuleShape(props as CapsuleShapeProps); }; export const getCircleShape = (props: CircleShapeProps): p2.Circle => @@ -27,3 +32,9 @@ export const getCircleShape = (props: CircleShapeProps): p2.Circle => export const getPlaneShape = (props: PlaneShapeProps): p2.Plane => new p2.Plane(getBaseProps(props)); + +export const getBoxShape = (props: BoxShapeProps): p2.Box => + new p2.Box(getBaseProps(props)); + +export const getCapsuleShape = (props: CapsuleShapeProps): p2.Capsule => + new p2.Capsule(getBaseProps(props)); From e3c67e155d6a4e04b0eefae68c46a6251001810e Mon Sep 17 00:00:00 2001 From: Alberto Quiles Boix Date: Thu, 20 Jun 2024 19:53:34 +0200 Subject: [PATCH 2/2] fix #20 --- examples/example/src/app.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/example/src/app.component.ts b/examples/example/src/app.component.ts index bd966a5..7f21a11 100644 --- a/examples/example/src/app.component.ts +++ b/examples/example/src/app.component.ts @@ -8,6 +8,7 @@ import { global, plane, box, + circle, sprite, world, capsule,