'use strict';
/**
* @module Factory
*/
const Map = require('../util/Map');
/**
*
* @param {*} x
* @param {*} y
* @param {*} bounds
* @return {boolean}
* @function
*/
function withinBounds(x, y, bounds) {
for (let i = 0; i < bounds.length; i ++) {
if (x >= bounds[i][0].x && x <= bounds[i][1].x
&& y >= bounds[i][0].y && y <= bounds[i][1].y) {
return true;
}
}
return false;
}
/**
*
* @param {*} bounds
* @return {Object}
* @function
*/
function randInBounds(bounds) {
let b = bounds[game.rnd.integerInRange(0, bounds.length -1 )];
return {
x: game.rnd.integerInRange(b[0].x, b[1].x),
y: game.rnd.integerInRange(b[0].y, b[1].y),
};
}
/**
*
*
* @param {any} entity
* @param {any} group
* @param {Array} bounds
* @param {number=} limit
* @constructor Factory
*/
function Factory(entity, group, bounds, limit) {
if (entity === undefined || bounds === undefined) {
throw new TypeError('Undefined type?');
}
this.Entity = entity;
this.group = group;
this.bounds = bounds;
this.limit = limit || Infinity;
this.generated = 0;
}
/**
* This will return a new `Entity` if the number of existing
* `Entities` has not exceeded the `limit`.
*
* @param {number} x
* @param {number} y
* @param {any} key
* @return {Entity}
*/
Factory.prototype.next = function(x, y, key) {
/**
* Return nothing if limit has been reached
*/
let living = this.group.countLiving();
if ( living >= this.limit) return;
if (x === null || y === null || !withinBounds(x, y, this.bounds)) {
let o = randInBounds(this.bounds);
x = o.x;
y = o.y;
}
/**
* Else, return a new entity and add it to the list.
*/
let sprite = new this.Entity(x, y, key);
this.group.add(sprite);
sprite.setDirection(Math.floor(Math.random() * 4) + 1);
sprite.idleHere();
return sprite;
};
module.exports = Factory;