blaze-2d
Version:
A fast and simple WebGL 2 2D game engine written in TypeScript
100 lines • 3.93 kB
JavaScript
import { vec2 } from "gl-matrix";
import Object2D from "../object2d";
import Renderer from "../renderer/renderer";
import Texture from "../texture/texture";
import Color from "../utils/color";
import { applyRotation, applyTranslation } from "../utils/vectors";
const defaultTexture = new Texture(new Color("gray"));
/**
* Represents an arbitrary shape in 2D world space.
*
* A shape is self contained and includes functions to render itself.
*/
export default class Shape extends Object2D {
constructor() {
super();
// protected height: number;
// protected width: number;
this.texture = defaultTexture;
this.cachedPoints = {
points: [],
pos: vec2.fromValues(-Infinity, Infinity),
posSlop: 0.00001,
rotation: Infinity,
rotationSlop: 0.001,
};
this.posDiff = vec2.create();
}
/**
* Renders the shape using the {@link Renderer}.
*
* @param position The x and y position to render the shape at
* @param rotation The rotation to apply to the rendered shape
* @param zIndex The z position of the rendered shape
*/
render(position, rotation, zIndex) {
Renderer.queueShape(this, position, rotation, zIndex);
}
/**
* Calculates the shape's vertices in local space.
*
* @returns The shape's vertices
*/
getVertices() {
const base = this.getBaseVertices();
const translated = applyTranslation(base, this.getPosition());
const rotated = applyRotation(translated, this.getPosition(), this.getRotation());
const final = [];
rotated.forEach((v) => final.push(...v));
return final;
}
/**
* Calculates the shape's vertices relative to the provided origin in world space.
*
* @param origin The origin to calculate the vertices relative to, should be a world position
* @param scale The vector to scale the world space vertices by to obtain clip space values
* @param rotation An optional rotation to apply to the vertices
* @param camera An optional camera to get vertices relative to
* @returns The shape's vertices relative to the provided origin in clip space
*/
getVerticesClipSpace(origin, scale, rotation, camera) {
const pos = camera ? vec2.sub(vec2.create(), origin, camera.getPosition()) : origin;
let world = this.getVerticesWorld(pos, rotation, true);
if (camera)
world = applyRotation(world, vec2.create(), camera.getRotation());
const final = [];
world.forEach((v) => final.push(...v));
return final.map((v, i) => {
if (i % 2 === 0)
return v * scale[0];
else
return v * scale[1];
});
}
/**
* Calculates the bounding points of the {@link Shape} instance.
*
* **NOTE: The shape's vertices are recalculated every time this function is called.**
*
* @returns The bounding points of the box
*/
getPoints() {
// return cached points if they are valid
if (vec2.sqrLen(vec2.sub(this.posDiff, this.getPosition(), this.cachedPoints.pos)) <= this.cachedPoints.posSlop &&
Math.abs(this.getRotation() - this.cachedPoints.rotation) <= this.cachedPoints.rotationSlop) {
// console.log("using cached points");
return this.cachedPoints.points;
}
const vertices = this.getVerticesWorld(vec2.create());
const points = [];
for (let i = 1; i < vertices.length; i += 2) {
points.push(vec2.fromValues(vertices[i - 1], vertices[i]));
}
// cache points
this.cachedPoints.points = points;
vec2.copy(this.cachedPoints.pos, this.getPosition());
this.cachedPoints.rotation = this.getRotation();
return points;
}
}
//# sourceMappingURL=shape.js.map