UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

104 lines (75 loc) 2.72 kB
import { seededRandom } from "../../../../core/math/random/seededRandom.js"; import { MarkerNodeAction } from "../MarkerNodeAction.js"; import { assert } from "../../../../core/assert.js"; import { binarySearchHighIndex } from "../../../../core/collection/array/binarySearchHighIndex.js"; import { number_compare_ascending } from "../../../../core/primitives/numbers/number_compare_ascending.js"; /** * * @type {number[]} */ const evaluatedWeights = []; export class MarkerNodeActionSelectWeighted extends MarkerNodeAction { /** * * @type {MarkerNodeActionWeightedElement[]} */ elements = []; __random = seededRandom(0); /** * * @returns {MarkerNodeActionSelectWeighted} * @param {MarkerNodeActionWeightedElement[]} elements */ static from(elements) { assert.isArray(elements, 'elements'); const r = new MarkerNodeActionSelectWeighted(); r.elements = elements; return r; } initialize(grid, ecd, seed) { this.__random.setCurrentSeed(seed); const elements = this.elements; const n = elements.length; for (let i = 0; i < n; i++) { /** * * @type {MarkerNodeActionWeightedElement} */ const element = elements[i]; element.initialize(grid, ecd, seed + i); } super.initialize(grid, ecd, seed); } execute(grid, ecd, node) { const elements = this.elements; const n = elements.length; let totalWeight = 0; for (let i = 0; i < n; i++) { /** * * @type {MarkerNodeActionWeightedElement} */ const weightedElement = elements[i]; /** * * @type {CellFilter} */ const weightFilter = weightedElement.weight; /** * * @type {Vector2} */ const nodePosition = node.position; const weightValue = weightFilter.execute(grid, nodePosition.x, nodePosition.y, 0); if (weightValue > 0) { //if the weight is negative, we clamp it to 0 totalWeight += weightValue; } evaluatedWeights[i] = totalWeight; } const targetWeight = this.__random() * totalWeight; const index = binarySearchHighIndex(evaluatedWeights, targetWeight, number_compare_ascending, 0, n - 1); const targetElement = elements[index]; targetElement.action.execute(grid, ecd, node); } }