@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
123 lines (98 loc) • 3.13 kB
JavaScript
import { CellMatcherAnd } from "../logic/CellMatcherAnd.js";
import { GridPatternMatcherCell } from "./GridPatternMatcherCell.js";
import { CellMatcher } from "../CellMatcher.js";
export class CellMatcherGridPattern extends CellMatcher {
/**
* NOTE: All rules have local coordinates
* @type {GridPatternMatcherCell[]}
*/
rules = [];
/**
*
* @param {GridPatternMatcherCell[]} rules
* @returns {CellMatcherGridPattern}
*/
static from(rules) {
const r = new CellMatcherGridPattern();
r.rules = rules;
return r;
}
initialize(grid, seed) {
const rules = this.rules;
const n = rules.length;
for (let i = 0; i < n; i++) {
const rule = rules[i];
rule.rule.initialize(grid, seed);
}
}
/**
*
* @param {number} x
* @param {number} y
* @param {CellMatcher} rule
*/
addRule(x, y, rule) {
const existingRule = this.getRuleByPosition(x, y);
if (existingRule !== undefined) {
//rule already exists, modify it
existingRule.rule = CellMatcherAnd.from(existingRule.rule, rule);
} else {
const cellTagRule = new GridPatternMatcherCell();
cellTagRule.position.set(x, y);
cellTagRule.rule = rule;
this.rules.push(cellTagRule);
}
}
/**
*
* @param {number} x
* @param {number} y
* @return {undefined|GridPatternMatcherCell}
*/
getRuleByPosition(x, y) {
const rules = this.rules;
const n = rules.length;
for (let i = 0; i < n; i++) {
const tagRule = rules[i];
if (tagRule.position.x === x && tagRule.position.y === y) {
return tagRule;
}
}
return undefined;
}
/**
*
* @param {GridData} grid
* @param {number} x
* @param {number} y
* @param {number} rotation
* @returns {boolean}
*/
match(grid, x, y, rotation) {
/**
*
* @type {GridPatternMatcherCell[]}
*/
const rules = this.rules;
const n = rules.length;
const sin = Math.sin(rotation);
const cos = Math.cos(rotation);
for (let i = 0; i < n; i++) {
const tagRule = rules[i];
const position = tagRule.position;
const local_y = position.y;
const local_x = position.x;
//rotate rule position
const rotated_local_x = local_x * cos - local_y * sin
const rotated_local_y = local_x * sin + local_y * cos;
const target_x = Math.round(x + rotated_local_x);
const target_y = Math.round(y + rotated_local_y);
const match = tagRule.rule.match(grid, target_x, target_y, rotation);
if (!match) {
//rule failed
return false;
}
}
return true;
}
}