diff --git a/examples/polygon.js b/examples/polygon.js new file mode 100644 index 000000000..6b0dcd284 --- /dev/null +++ b/examples/polygon.js @@ -0,0 +1,40 @@ +kaboom( +) + +// Add a thing that follows the mouse +var CURSOR = "cursor" + +const cursor = add([ + circle(10), + area(), + pos(), + CURSOR, +]) + +cursor.onMouseMove(pos => { + cursor.pos = pos +}) + +// Make a weird shape +const poly = add([ + polygon([ + vec2(300,300), + vec2(500,300), + vec2(350,600), + vec2(300,400), + ]), + pos(80, 120), + outline(4), + area(), + color(rgb(255,0,0)), + opacity(0.2), +]) + +// Change the color when the cursor object collides with the polygon +poly.onCollide(CURSOR, () => { + poly.color = poly.color.lighten(100) +}) + +poly.onCollideEnd(CURSOR, obj => { + poly.color = poly.color.darken(100) +}) diff --git a/src/kaboom.ts b/src/kaboom.ts index 5046ad9df..8aea9b878 100644 --- a/src/kaboom.ts +++ b/src/kaboom.ts @@ -177,6 +177,8 @@ import type { MaskComp, Mask, Outline, + PolygonComp, + PolygonCompOpt, } from "./types" import beanSpriteSrc from "./assets/bean.png" @@ -3951,6 +3953,25 @@ export default (gopt: KaboomOpt = {}): KaboomCtx => { } + function polygon(pts: Vec2[], opt: PolygonCompOpt = {}): PolygonComp { + if(pts.length < 3) throw new Error(`Polygon's need more than two points, ${pts.length} points provided`) + return { + id: "polygon", + pts, + draw(this: GameObj) { + drawPolygon(Object.assign(getRenderProps(this), { + pts: this.pts, + })) + }, + renderArea(this: GameObj) { + return new Polygon(this.pts) + }, + inspect() { + return this.pts.map(p => `[${p.x},${p.y}]`).join(",") + }, + } + } + function rect(w: number, h: number, opt: RectCompOpt = {}): RectComp { return { id: "rect", @@ -6278,6 +6299,7 @@ export default (gopt: KaboomOpt = {}): KaboomCtx => { area, sprite, text, + polygon, rect, circle, uvquad, diff --git a/src/types.ts b/src/types.ts index 4df328292..ed4c4ccae 100644 --- a/src/types.ts +++ b/src/types.ts @@ -250,6 +250,21 @@ export interface KaboomCtx { * ``` */ text(txt: string, options?: TextCompOpt): TextComp, + /** + * Render as a polygon. + * + * @example + * ```js + * // Make a square the hard way + * add([ + * pos(80, 120), + * polygon([vec2(0,0), vec2(50,0), vec2(50,50), vec2(0,50)]), + * outline(4), + * area(), + * ]) + * ``` + */ + polygon(pts: Vec2[], opt?: PolygonCompOpt): PolygonComp, /** * Render as a rectangle. * @@ -4576,6 +4591,7 @@ export interface RectCompOpt { fill?: boolean, } +export type PolygonCompOpt = Omit export interface RectComp extends Comp { draw: Comp["draw"], /** @@ -4596,6 +4612,20 @@ export interface RectComp extends Comp { renderArea(): Rect, } +export interface PolygonComp extends Comp { + draw: Comp["draw"], + + /** + * Points in the polygon + * @since 3000.1.13 + */ + pts: Vec2[] + /** + * @since 3000.1.13 + */ + renderArea(): Polygon, +} + export interface CircleCompOpt { /** * If fill the circle (useful if you only want to render outline with outline() component).