From a75ebdecb92d18f517b5e2ebc50d74d6ccffdf26 Mon Sep 17 00:00:00 2001 From: Marc Flerackers Date: Fri, 24 May 2024 18:43:39 +0900 Subject: [PATCH] Support for textured polygons --- CHANGELOG.md | 3 ++ examples/polygonuv.js | 82 +++++++++++++++++++++++++++++++++++++++++++ src/kaboom.ts | 12 +++++-- src/types.ts | 28 +++++++++++++-- 4 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 examples/polygonuv.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 66956aed..2431feb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## v3001.0 +- added global raycast function and raycast method to level +- added support for textured polygons + ## v3000.2 - added `loadMusic()` to load streaming audio (doesn't block in loading screen) diff --git a/examples/polygonuv.js b/examples/polygonuv.js new file mode 100644 index 00000000..6b702779 --- /dev/null +++ b/examples/polygonuv.js @@ -0,0 +1,82 @@ +// Adding game objects to screen + +// Start a kaboom game +kaboom(); + +// Load a sprite asset from "sprites/bean.png", with the name "bean" +loadSprite("bean", "/sprites/bean.png"); +loadSprite("ghosty", "/sprites/ghosty.png"); + +// A "Game Object" is the basic unit of entity in kaboom +// Game objects are composed from components +// Each component gives a game object certain capabilities + +// add() assembles a game object from a list of components and add to game, returns the reference of the game object +const player = add([ + sprite("bean"), // sprite() component makes it render as a sprite + pos(120, 80), // pos() component gives it position, also enables movement + rotate(0), // rotate() component gives it rotation + anchor("center"), // anchor() component defines the pivot point (defaults to "topleft") +]); + +// .onUpdate() is a method on all game objects, it registers an event that runs every frame +player.onUpdate(() => { + // .angle is a property provided by rotate() component, here we're incrementing the angle by 120 degrees per second, dt() is the time elapsed since last frame in seconds + player.angle += 120 * dt(); +}); + +// Make sure all sprites have been loaded +onLoad(() => { + // Get the texture and uv for ghosty + const data = getSprite("ghosty").data; + const tex = data.tex; + const quad = data.frames[0]; + // Add multiple game objects + for (let i = 0; i < 3; i++) { + // generate a random point on screen + // width() and height() gives the game dimension + const x = rand(0, width()); + const y = rand(0, height()); + + add([ + pos(x, y), + { + q: quad.clone(), + pts: [ + vec2(-32, -32), + vec2(32, -32), + vec2(32, 32), + vec2(-32, 32), + ], + // Draw the polygon + draw() { + const q = this.q; + drawPolygon({ + pts: pts, + uv: [ + vec2(q.x, q.y), + vec2(q.x + q.w, q.y), + vec2(q.x + q.w, q.y + q.h), + vec2(q.x, q.y + q.h), + ], + tex: tex, + }); + }, + // Update the vertices each frame + update() { + pts = [ + vec2(-32, -32), + vec2(32, -32), + vec2(32, 32), + vec2(-32, 32), + ].map((p, index) => + p.add( + 5 * Math.cos((time() + index * 0.25) * Math.PI), + 5 * Math.sin((time() + index * 0.25) * Math.PI), + ) + ); + }, + }, + ]); + } +}); diff --git a/src/kaboom.ts b/src/kaboom.ts index d2f015d3..07ed5d4a 100644 --- a/src/kaboom.ts +++ b/src/kaboom.ts @@ -1924,7 +1924,7 @@ export default (gopt: KaboomOpt = {}): KaboomCtx => { // TODO: gradient for rounded rect // TODO: drawPolygon should handle generic rounded corners if (opt.radius) { - // maxium radius is half the shortest side + // maximum radius is half the shortest side const r = Math.min(Math.min(w, h) / 2, opt.radius); pts = [ @@ -2186,7 +2186,9 @@ export default (gopt: KaboomOpt = {}): KaboomCtx => { const verts = opt.pts.map((pt, i) => ({ pos: new Vec2(pt.x, pt.y), - uv: new Vec2(0, 0), + uv: opt.uv + ? opt.uv[i] + : new Vec2(0, 0), color: opt.colors ? (opt.colors[i] ? opt.colors[i].mult(color) : color) : color, @@ -2202,7 +2204,7 @@ export default (gopt: KaboomOpt = {}): KaboomCtx => { verts, opt.indices ?? indices, opt.fixed, - gfx.defTex, + opt.uv ? opt.tex : gfx.defTex, opt.shader, opt.uniform, ); @@ -4254,11 +4256,15 @@ export default (gopt: KaboomOpt = {}): KaboomCtx => { id: "polygon", pts, colors: opt.colors, + uv: opt.uv, + tex: opt.tex, radius: opt.radius, draw(this: GameObj) { drawPolygon(Object.assign(getRenderProps(this), { pts: this.pts, colors: this.colors, + uv: this.uv, + tex: this.tex, radius: this.radius, fill: opt.fill, })); diff --git a/src/types.ts b/src/types.ts index ccdfd6c3..70579230 100644 --- a/src/types.ts +++ b/src/types.ts @@ -3848,11 +3848,23 @@ export type DrawPolygonOpt = RenderProps & { */ radius?: number; /** - * The color of each vertice. + * The color of each vertex. * * @since v3000.0 */ colors?: Color[]; + /** + * The uv of each vertex. + * + * @since v3001.0 + */ + uv?: Vec2[]; + /** + * The texture if uv are supplied. + * + * @since v3001.0 + */ + tex?: Texture; }; export interface Outline { @@ -5048,9 +5060,21 @@ export interface PolygonComp extends Comp { */ radius?: number; /** - * The color of each vertice. + * The color of each vertex. */ colors?: Color[]; + /** + * The uv of each vertex. + * + * @since v3001.0 + */ + uv?: Vec2[]; + /** + * The texture used when uv coordinates are present. + * + * @since v3001.0 + */ + tex?: Texture; renderArea(): Polygon; }