UNPKG

gibbon.js

Version:

Actor/Component system for use with pixi.js.

196 lines 5.7 kB
import { GridCell } from './grid-cell'; import { GridRange } from './grid-range'; /** * Grid for tracking Actor location and hit tests. */ export class Grid { rows; cols; _cells; width; height; cellWidth; cellHeight; constructor(props) { this.width = props.width; this.height = props.height; this.rows = props.rows ?? 20; this.cols = props.cols ?? 20; this.cellWidth = this.width / this.cols; this.cellHeight = this.height / this.rows; this._cells = this.initTiles(); } /** * Add items to range of grid cells. * @param range * @param item */ addToRange(range, item) { const maxR = range.maxRow; const maxC = range.maxCol; for (let r = range.minRow; r <= maxR; r++) { for (let c = range.minCol; c <= maxC; c++) { this._cells[r][c].addItem(item); } } } removeFromRange(range, item) { const maxR = range.maxRow; const maxC = range.maxCol; for (let r = range.minRow; r <= maxR; r++) { for (let c = range.minCol; c <= maxC; c++) { this._cells[r][c].removeItem(item); } } } /** * Get hits matching item. * @param results */ getHits(item, results = [], range) { range = range ?? this.getRange(item); for (let r = range.minRow; r <= range.minRow; r++) { for (let c = range.minCol; c <= range.maxCol; c++) { this._cells[r][c].getHits(item, results); } } return results; } /** * Get the range of an item. * @param item * @param result - Optional grid range in which to place results. */ getRange(item, result) { result = result ?? new GridRange(); let v = Math.floor((item.y - item.height / 2) / this.cellHeight); if (v < 0) { v = 0; } else if (v >= this.rows) { v = this.rows - 1; } result.minRow = v; v = Math.floor((item.y + item.height / 2) / this.cellHeight); if (v < 0) { v = 0; } else if (v >= this.rows) { v = this.rows - 1; } result.maxRow = v; v = Math.floor((item.x - item.width / 2) / this.cellWidth); if (v < 0) { v = 0; } else if (v >= this.cols) { v = this.cols - 1; } result.minCol = v; v = Math.floor((item.x + item.width / 2) / this.cellWidth); if (v < 0) { v = 0; } else if (v >= this.cols) { v = this.cols - 1; } result.maxCol = v; return result; } /** * Get objects within grid range. * @param range * @param results */ getItems(range, results = []) { const maxR = range.maxRow; const maxC = range.maxCol; for (let r = range.minRow; r <= maxR; r++) { for (let c = range.minCol; c <= maxC; c++) { this._cells[r][c].getItems(results); } } return results; } addItem(item) { let minRow = Math.floor((item.y - item.height / 2) / this.cellHeight); if (minRow < 0) { minRow = 0; } else if (minRow >= this.rows) { minRow = this.rows - 1; } let maxRow = Math.floor((item.y + item.height / 2) / this.cellHeight); if (maxRow < 0) { maxRow = 0; } else if (maxRow >= this.rows) { maxRow = this.rows - 1; } let minCol = Math.floor((item.x - item.width / 2) / this.cellWidth); if (minCol < 0) { minCol = 0; } else if (minCol >= this.cols) { minCol = this.cols - 1; } let maxCol = Math.floor((item.x + item.width / 2) / this.cellWidth); if (maxCol < 0) { maxCol = 0; } else if (maxCol >= this.cols) { maxCol = this.cols - 1; } for (let r = minRow; r <= maxRow; r++) { for (let c = minCol; c <= maxCol; c++) { this._cells[r][c].addItem(item); } } } removeItem(go) { let minRow = Math.floor((go.y - go.height / 2) / this.cellHeight); if (minRow < 0) { minRow = 0; } else if (minRow >= this.rows) { minRow = this.rows - 1; } let maxRow = Math.floor((go.y + go.height / 2) / this.cellHeight); if (maxRow < 0) { maxRow = 0; } else if (maxRow >= this.rows) { maxRow = this.rows - 1; } let minCol = Math.floor((go.x - go.width / 2) / this.cellWidth); if (minCol < 0) { minCol = 0; } else if (minCol >= this.cols) { minCol = this.cols - 1; } let maxCol = Math.floor((go.x + go.width / 2) / this.cellWidth); if (maxCol < 0) { maxCol = 0; } else if (maxCol >= this.cols) { maxCol = this.cols - 1; } for (let r = minRow; r <= maxRow; r++) { for (let c = minCol; c <= maxCol; c++) { this._cells[r][c].removeItem(go); } } } initTiles() { const a = new Array(this.rows); for (let r = 0; r < this.rows; r++) { const b = a[r] = new Array(this.cols); for (let c = 0; c < this.cols; c++) { b[c] = new GridCell(); } } return a; } } //# sourceMappingURL=grid.js.map