@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
225 lines (171 loc) • 5.37 kB
JavaScript
import { assert } from "../../core/assert.js";
import Vector2 from "../../core/geom/Vector2.js";
import Vector3 from "../../core/geom/Vector3.js";
import { Transform } from "../../engine/ecs/transform/Transform.js";
import { GridCellAction } from "../placement/action/GridCellAction.js";
import { MarkerNode } from "./MarkerNode.js";
export class GridCellActionPlaceMarker extends GridCellAction {
/**
*
* @type {String}
*/
type = null;
/**
*
* @type {Transform}
*/
transform = new Transform();
/**
*
* @type {String[]}
*/
tags = [];
properties = {};
size = 0;
/**
*
* @type {MarkerNodeTransformer[]}
*/
transformers = [];
/**
*
* @type {number}
*/
priority = 0;
/**
*
* @type {Vector2}
*/
offset = new Vector2();
initialize(data, seed) {
super.initialize(data, seed);
const transformers = this.transformers;
const n = transformers.length;
for (let i = 0; i < n; i++) {
const nodeTransformer = transformers[i];
nodeTransformer.initialize(data, seed);
}
}
/**
*
* @param {String} tag
* @returns {boolean}
*/
addTag(tag) {
assert.isString(tag, 'tag');
if (this.tags.indexOf(tag) !== -1) {
return false;
}
this.tags.push(tag);
return true;
}
/**
*
* @param {MarkerNodeTransformer} transformer
*/
addTransformer(transformer) {
assert.equal(transformer.isMarkerNodeTransformer, true, 'transformer.isMarkerNodeTransformer !== true');
this.transformers.push(transformer);
}
/**
*
* @param {String} type
* @param {number} [size=0]
* @param {MarkerNodeTransformer[]} [transformers]
* @param {string[]} [tags]
* @param {Transform} [transform]
* @param {*} [properties]
* @param priority
* @return {GridCellActionPlaceMarker}
*/
static from({
type,
size = 0,
transformers = [],
tags = [],
transform,
properties,
priority = 0
}) {
assert.isString(type, 'type');
assert.isNumber(size, 'size');
assert.greaterThanOrEqual(size, 0, 'size must be non-negative');
const r = new GridCellActionPlaceMarker();
r.type = type;
r.size = size;
if (transform !== undefined) {
r.transform.copy(transform);
}
for (let i = 0; i < transformers.length; i++) {
r.addTransformer(transformers[i]);
}
for (let i = 0; i < tags.length; i++) {
r.addTag(tags[i]);
}
if (properties !== undefined) {
r.properties = properties;
}
r.priority = priority;
return r;
}
/**
*
* @param {GridData} data
* @param {number} x
* @param {number} y
* @param {number} rotation
* @returns {MarkerNode}
*/
buildNode(data, x, y, rotation) {
let node = new MarkerNode();
const sin = Math.sin(rotation);
const cos = Math.cos(rotation);
//rotate offset position
const offset = this.offset;
const offsetY = offset.y;
const offsetX = offset.x;
const rotated_local_offset_x = offsetX * cos - offsetY * sin
const rotated_local_offset_y = offsetX * sin + offsetY * cos;
const target_x = rotated_local_offset_x + x;
const target_y = rotated_local_offset_y + y;
node.position.set(target_x, target_y);
node.type = this.type;
node.size = this.size;
const transform = data.transform;
node.transform.position.set(
target_x * transform.scale_x + transform.offset_x,
0,
target_y * transform.scale_y + transform.offset_y
);
node.transform.rotation.fromAxisAngle(Vector3.down, rotation);
node.transform.multiplyTransforms(node.transform, this.transform);
//add tags
const tags = this.tags;
const tag_count = tags.length;
const node_tags = node.tags;
for (let i = 0; i < tag_count; i++) {
const tag = tags[i];
node_tags.push(tag);
}
//write properties
Object.assign(node.properties, this.properties);
node.priority = this.priority;
//apply transformations
const transformers = this.transformers;
const transformer_count = transformers.length;
for (let i = 0; i < transformer_count; i++) {
const transformer = transformers[i];
node = transformer.transform(node, data);
}
return node;
}
execute(data, x, y, rotation) {
const node = this.buildNode(data, x, y, rotation);
data.addMarker(node);
}
}
/**
* @readonly
* @type {boolean}
*/
GridCellActionPlaceMarker.prototype.isGridCellActionPlaceMarker = true;