react-simple-game-engine
Version:
[WIP] not able to use in currently. <!-- Document cumming soon... -->
289 lines (288 loc) • 12.5 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { Bodies, Body } from "matter-js";
import { ColorSprite } from "../sprites/color.sprite";
import { EntitySuit } from "./entity-suit";
import { copyProperties, genId } from "../../utils";
import { Sensor } from "../sensor";
var Entity = /** @class */ (function (_super) {
__extends(Entity, _super);
function Entity() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this._props = {};
_this.timerJobListeners = [];
_this._isTerminate = false;
_this.keepVisible = false;
_this.debugSensor = false;
_this.sensors = [];
_this.enabledGravity = true;
return _this;
}
Object.defineProperty(Entity.prototype, "isTerminate", {
get: function () {
return this._isTerminate;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Entity.prototype, "sprite", {
get: function () {
return this._sprite;
},
set: function (sprite) {
this._sprite = sprite;
this._sprite.entity = this;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Entity.prototype, "position", {
get: function () {
return this._body.position;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Entity.prototype, "body", {
get: function () {
return this._body;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Entity.prototype, "props", {
get: function () {
return this._props;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Entity.prototype, "havePhysicBody", {
get: function () {
var body = this._body;
return body.id != null && !!body.force;
},
enumerable: false,
configurable: true
});
/**
* @param {TerminateOptions} options
* #duration: time to disappear from the world in milliseconds, default: 200 milliseconds
* #effect: effect to showing on duration time
* @void
*/
Entity.prototype.terminate = function (options) {
var _this = this;
var _a;
if (options) {
var _b = options.duration, duration = _b === void 0 ? 200 : _b, effect = options.effect, _c = options.keepVisible, keepVisible = _c === void 0 ? false : _c;
this._isTerminate = true;
this.keepVisible = keepVisible;
if (this.havePhysicBody) {
Body.setVelocity(this.body, {
y: 0,
x: 0,
});
}
if (effect) {
this.addChild(effect);
}
setTimeout(function () {
var _a;
_this.worldManagement.removeEntity(_this);
(_a = _this.onTerminate) === null || _a === void 0 ? void 0 : _a.call(_this);
}, duration);
}
else {
this.worldManagement.removeEntity(this);
(_a = this.onTerminate) === null || _a === void 0 ? void 0 : _a.call(this);
}
};
/**
* @param {number} interval in milliseconds
* @param {TimerJobListener} job function that run per #interval
* @param {TimerOptions} options
* @void
*/
Entity.prototype.onTimer = function (interval, job, _a) {
var _this = this;
var _b = _a === void 0 ? {} : _a, _c = _b.defaultRun, defaultRun = _c === void 0 ? false : _c, _d = _b.once, once = _d === void 0 ? false : _d, startFrom = _b.startFrom, onRegisterDone = _b.onRegisterDone;
var listener = {
timeCounter: startFrom != null ? new Date().getTime() - startFrom : 0,
interval: interval,
job: job,
defaultRun: defaultRun,
};
this.timerJobListeners.push(listener);
var unSub = function () {
var index = _this.timerJobListeners.indexOf(listener);
if (index > -1) {
_this.timerJobListeners.splice(index, 1);
}
};
if (once) {
listener.job = function () {
job();
unSub();
};
}
if (onRegisterDone) {
onRegisterDone(startFrom !== null && startFrom !== void 0 ? startFrom : new Date().getTime()); //todo: this may not invoke correctly
}
return {
remove: unSub,
reset: function () {
listener.timeCounter = 0;
},
};
};
Entity.prototype.removeSensor = function (sensor) {
var delIndex = this.sensors.indexOf(sensor);
if (delIndex > -1) {
this.sensors.splice(delIndex);
this.worldManagement.removeBody(sensor.body);
}
};
/**
* @param {Point} position delta position of sensor base on entity position
* @param {string} name name of sensor
* @param {"rect"|"circle"} shape type of shape of physical body, ex: "rect"|"circle"
* @param {number} width width of sensor, apply when in "rect" shape
* @param {number} height height of sensor, apply when in "rect" shape
* @param {number} radius radius of sensor, apply when in "circle" shape
* @param {boolean} debug allow to show sensor for debug purpose, have to enable entity.debugSensor = true first
* @param {boolean} debugColor allow to change sensor color
* @void
*/
Entity.prototype.addSensor = function (_a, debug, debugColor) {
var relativePosition = _a.relativePosition, name = _a.name, _b = _a.shape, shape = _b === void 0 ? "rect" : _b, width = _a.width, height = _a.height, radius = _a.radius;
if (debug === void 0) { debug = false; }
name = name || genId();
relativePosition = relativePosition || { x: 0, y: 0 };
var pos = {
x: this.position.x + relativePosition.x,
y: this.position.y + relativePosition.y,
};
var sensor;
if (shape === "rect") {
sensor = new Sensor(this, name, relativePosition, { width: width, height: height }, shape, Bodies.rectangle(pos.x, pos.y, width, height, {
isSensor: true,
}), debug, debugColor);
}
else {
sensor = new Sensor(this, name, relativePosition, { width: radius * 2, height: radius * 2 }, shape, Bodies.circle(pos.x, pos.y, radius, {
isSensor: true,
}), debug, debugColor);
}
this.sensors.push(sensor);
this.worldManagement.addBody(sensor.body);
};
Entity.prototype.createBody = function (enabledPhysicBody, transform, options) {
this._body = this.onCreateBody(enabledPhysicBody, transform, options);
this._body.entity = this;
return this._body;
};
Entity.prototype.initial = function (_a) {
var transform = _a.transform, spriteComponent = _a.sprite, bodyOptions = _a.bodyOptions, _b = _a.props, props = _b === void 0 ? {} : _b, params = __rest(_a, ["transform", "sprite", "bodyOptions", "props"]);
var _c = this.onInitial(), _d = _c.transform, _e = _d === void 0 ? {} : _d, _f = _e.x, x = _f === void 0 ? 0 : _f, _g = _e.y, y = _g === void 0 ? 0 : _g, dfTransform = __rest(_e, ["x", "y"]), dfBodyOptions = _c.bodyOptions, dfSpriteComponent = _c.sprite, _h = _c.props, dfProps = _h === void 0 ? {} : _h, dfParams = __rest(_c, ["transform", "bodyOptions", "sprite", "props"]);
copyProperties(this._props, __assign(__assign({}, dfProps), props));
var _j = this.onPrepare(), transformAlt = _j.transform, bodyOptionsAlt = _j.bodyOptions, spriteComponentAlt = _j.sprite, _k = _j.props, propsAlt = _k === void 0 ? {} : _k, _l = _j.enabledPhysicBody, enabledPhysicBody = _l === void 0 ? true : _l, paramsAlt = __rest(_j, ["transform", "bodyOptions", "sprite", "props", "enabledPhysicBody"]);
this.createBody(enabledPhysicBody, __assign(__assign(__assign({ x: x, y: y }, dfTransform), transform), transformAlt), __assign(__assign(__assign({}, dfBodyOptions), bodyOptions), bodyOptionsAlt));
copyProperties(this._props, __assign({}, propsAlt));
copyProperties(this, __assign(__assign(__assign({}, dfParams), params), paramsAlt));
//@ts-ignore
this.sprite =
(dfSpriteComponent === null || dfSpriteComponent === void 0 ? void 0 : dfSpriteComponent.output()) ||
(spriteComponent === null || spriteComponent === void 0 ? void 0 : spriteComponent.output()) ||
(spriteComponentAlt === null || spriteComponentAlt === void 0 ? void 0 : spriteComponentAlt.output()) ||
new ColorSprite();
};
/**
* invoke before entity setup completed, this is need to provide information of name, sprite, animation, animator, transform,...
* @void
*/
Entity.prototype.onPrepare = function () {
return {};
};
Entity.prototype.update = function () {
if (!this._isTerminate) {
this.onUpdate();
}
for (var _i = 0, _a = this.timerJobListeners; _i < _a.length; _i++) {
var jobListener = _a[_i];
var timeCounter = jobListener.timeCounter, interval = jobListener.interval, job = jobListener.job, defaultRun = jobListener.defaultRun;
if (defaultRun || timeCounter >= interval) {
timeCounter = 0;
job();
jobListener.defaultRun = false;
}
timeCounter += Renderer.deltaTime;
jobListener.timeCounter = timeCounter;
}
};
/**
* invoke in every frame, this is necessary for logic that need to run in every frame
* @void
*/
Entity.prototype.onUpdate = function () { };
Entity.prototype.draw = function () {
if (!this._isTerminate) {
this.sprite.draw();
this.onDraw();
}
else {
if (this.keepVisible) {
this.sprite.draw();
this.onDraw();
}
}
};
/**
* invoke in every frame, this is necessary for draw that need to run in every frame
* @void
*/
Entity.prototype.onDraw = function () { };
Entity.prototype.onCollision = function (target) { };
Entity.prototype.onCollisionEnd = function (target) { };
Entity.prototype.onCollisionActive = function (target) { };
Entity.prototype.onSensorCollision = function (sensor, target) { };
Entity.prototype.onSensorCollisionEnd = function (sensor, target) { };
Entity.prototype.onSensorCollisionActive = function (sensor, target) { };
return Entity;
}(EntitySuit));
export { Entity };