Source: sg2d-tilebody.js

"use strict";

import SG2DConsts from "./sg2d-consts.js";
import SG2DUtils from "./sg2d-utils.js";
import SG2DTile from "./sg2d-tile.js";
import SG2DClusters from "./sg2d-clusters.js";

/**
 * Тайл с физическим телом
 * @alias SG2D.TileBody
 */
class SG2DTileBody extends SG2DTile {
	initialize(properties, thisProps, options) {
		
		this.body = this.bodyCreate(properties.position, properties.angle);
		if (this.body) {
			this.body.tile = this;
		}
		
		super.initialize.apply(this, arguments);
		
		if (this.body) {
			Matter.Composite.add(SG2D.matter.world, this.body);
		}
		
		SG2D.Clusters.bodies.add(this);
	}
	
	/**
	 * Конструктор физического тела по умолчанию (квадрат). Можно переопределить.
	 * @param {object} [position={ x: 0, y: 0 }] - Координаты тела в пикселях
	 * @param {object} [angle=0] - Поворот тела в градусах
	 */
	bodyCreate(position = { x: 0, y: 0 }, angle = 0) {
		
		this.body = Matter.Bodies.rectangle(position.x, position.y, SG2D.Consts.CELLSIZEPIX - 1, SG2D.Consts.CELLSIZEPIX - 1, {
			isStatic: true,
			frictionStatic: this.constructor.MATTER.FRICTIONSTATIC,
			restitution: this.constructor.MATTER.RESTITUTION,
			slop: this.constructor.MATTER.SLOP
		});
		
		if (this.properties.angle) {
			Matter.Body.setAngle(this.body, angle * SG2D.Math.PI180);
		}
		
		return this.body;
	}
	
	_onGeometric() { // overrided
		/*this.calcBoundsPX(); => bounds формируется MatterJS*/
		this._calcCXY();
		this._calcClustersBody();
	}
	
	/**
	 * Получить список физических тел тайлов рядом с точкой pxy
	 * @param {object} pxy - Координаты точки, рядом с которой ищутся физические тела, например, {x: 250, y: 7200}
	 * @param {number} [cells_indent=1] - Ширина поиска в кластерах
	 * @param {array} [bodies=[]] - Результирующий массив
	 */
	getBodiesAround(pxy, cells_indent = 1, bodies = []) {
		bodies.length = 0;
		var cluster;
		var cx = SG2DUtils.PXtoCX(pxy.x), cy = SG2DUtils.PXtoCX(pxy.y);
		for (var x = cx - cells_indent; x <= cx + cells_indent; x++) {
			for (var y = cy - cells_indent; y <= cy + cells_indent; y++) {
				if (cluster = SG2DClusters.getCluster(x, y)) {
					for (var tile of cluster.bodies) {
						if (tile !== this && tile.body && bodies.indexOf(tile.body) === -1) {
							bodies.push(tile.body);
						}
					}
				}
			}
		}
		return bodies;
	}
	
	destroy() {
		if (this.body) {
			Matter.Composite.remove(SG2D.matter.world, this.body);
		}
		SG2D.Clusters.bodies.delete(this);
		this.body = null;
		super.destroy();
	}
}

SG2DTileBody.isBody = true;

/** Default MatterJS parameters */
SG2DTileBody.MATTER = {
	DENSITY: 1,
	FRICTION: 0,
	FRICTIONAIR: 0.1,
	FRICTIONSTATIC: 1,
	RESTITUTION: 0,
	SLOP: 0.05
};

export default SG2DTileBody;