UNPKG

react-simple-game-engine

Version:

[WIP] not able to use in currently. <!-- Document cumming soon... -->

606 lines (605 loc) 26.3 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; import { WorldManagement } from "./world-management"; import { copyProperties, createAssetImage, createAssetSound, parallel, tick, } from "../utils"; import { Sound } from "./sound"; import { SoundType } from "../export-enums"; var MAX_ASSET_PARALLEL_LOAD = 4; var Scene = /** @class */ (function () { function Scene() { this.nativeEventsUnsubscribes = function () { }; this.entityPropsChangeListeners = {}; this.soundBackgroundOptionsChangeListeners = []; this.soundOnceOptionsChangeListeners = []; this.processStateChangeListeners = []; this.joystickActionListeners = []; this.prefabs = []; this.sounds = []; this.sprites = []; this.sessionId = "".concat(Math.random(), "-").concat(new Date().getTime()); this.assetsDelay = 0; this.tag = this.constructor.tag; this.ui = this.constructor.ui; this.soundsDecor = this.__proto__.soundsDecor || []; this.spritesDecor = this.__proto__.spritesDecor || []; this._loadedAssets = false; this.onBorn(); } Object.defineProperty(Scene.prototype, "renderer", { get: function () { return this._renderer; }, set: function (_renderer) { if (this._renderer) { console.warn("Not allow to change renderer of scene"); return; } this._renderer = _renderer; }, enumerable: false, configurable: true }); Object.defineProperty(Scene.prototype, "worldManagement", { get: function () { return this._worldManagement; }, enumerable: false, configurable: true }); Object.defineProperty(Scene.prototype, "renderAssetsFail", { get: function () { return this._renderAssetsFail; }, enumerable: false, configurable: true }); Object.defineProperty(Scene.prototype, "UI", { get: function () { var Ui = this.ui || (function () { return null; }); return Ui; }, enumerable: false, configurable: true }); Object.defineProperty(Scene.prototype, "soundBackgroundOptions", { get: function () { return Sound.Management[SoundType.BACKGROUND]; }, set: function (options) { copyProperties(Sound.Management[SoundType.BACKGROUND], options); for (var _i = 0, _a = this.soundBackgroundOptionsChangeListeners; _i < _a.length; _i++) { var listener = _a[_i]; listener(Sound.Management[SoundType.BACKGROUND]); } }, enumerable: false, configurable: true }); Object.defineProperty(Scene.prototype, "soundOnceOptions", { get: function () { return Sound.Management[SoundType.ONCE]; }, set: function (options) { copyProperties(Sound.Management[SoundType.ONCE], options); for (var _i = 0, _a = this.soundOnceOptionsChangeListeners; _i < _a.length; _i++) { var listener = _a[_i]; listener(Sound.Management[SoundType.ONCE]); } }, enumerable: false, configurable: true }); Scene.prototype.bootSoundOptions = function () { var options = this.getSoundOptions(); copyProperties(Sound.Management[SoundType.ONCE], options[SoundType.ONCE] || {}); copyProperties(Sound.Management[SoundType.BACKGROUND], options[SoundType.BACKGROUND] || {}); }; Scene.prototype.getSoundOptions = function () { return {}; }; Scene.prototype.onBorn = function () { }; Scene.prototype.getComponents = function (simpleCamera) { return []; }; Scene.prototype.getUIProps = function () { return {}; }; Scene.prototype.getInitialConfigs = function () { return {}; }; Object.defineProperty(Scene.prototype, "loadedAssets", { get: function () { return this._loadedAssets; }, set: function (loadedAssets) { var _a; this._loadedAssets = loadedAssets; (_a = this.loadAssetsListener) === null || _a === void 0 ? void 0 : _a.call(this, loadedAssets); }, enumerable: false, configurable: true }); Object.defineProperty(Scene.prototype, "loadedAssetsError", { set: function (errors) { var _a; (_a = this.loadAssetsListener) === null || _a === void 0 ? void 0 : _a.call(this, this._loadedAssets, errors); }, enumerable: false, configurable: true }); Scene.prototype.onProcessStateChangeListener = function (func) { var listeners = this.processStateChangeListeners; listeners.push(func); return function () { var index = listeners.indexOf(func); if (index > -1) { listeners.splice(index, 1); } }; }; Scene.prototype.onSoundOnceOptionsChange = function (func) { var listeners = this.soundOnceOptionsChangeListeners; listeners.push(func); return function () { var index = listeners.indexOf(func); if (index > -1) { listeners.splice(index, 1); } }; }; Scene.prototype.onSoundBackgroundOptionsChange = function (func) { var listeners = this.soundBackgroundOptionsChangeListeners; listeners.push(func); return function () { var index = listeners.indexOf(func); if (index > -1) { listeners.splice(index, 1); } }; }; Scene.prototype.onJoystickAction = function (func) { var listeners = this.joystickActionListeners; listeners.push(func); return function () { var index = listeners.indexOf(func); if (index > -1) { listeners.splice(index, 1); } }; }; Scene.prototype.onEntityPropsChange = function (name, func) { var listeners = (this.entityPropsChangeListeners[name] = this.entityPropsChangeListeners[name] || []); listeners.push(func); return function () { var index = listeners.indexOf(func); if (index > -1) { listeners.splice(index, 1); } }; }; Scene.prototype.emitJoystickActionEvent = function (data) { var listeners = this.joystickActionListeners; for (var _i = 0, listeners_1 = listeners; _i < listeners_1.length; _i++) { var listener = listeners_1[_i]; listener(data); } }; Scene.prototype.emitProcessStateChangeEvent = function (isForeground) { var listeners = this.processStateChangeListeners; for (var _i = 0, listeners_2 = listeners; _i < listeners_2.length; _i++) { var listener = listeners_2[_i]; listener(isForeground); } }; Scene.prototype.emitEntityPropsChangeEvent = function (name, value) { var listeners = this.entityPropsChangeListeners[name] || []; for (var _i = 0, listeners_3 = listeners; _i < listeners_3.length; _i++) { var listener = listeners_3[_i]; listener(value); } }; Scene.prototype.onLoadAssetNotify = function (func) { this.loadAssetsListener = func; }; Scene.prototype.destructor = function () { this.nativeEventsUnsubscribes(); this._worldManagement.destructor(); for (var _i = 0, _a = this.sounds; _i < _a.length; _i++) { var sound = _a[_i]; sound.stop(); } }; Scene.prototype.switchToScene = function (tag) { this.manager.gotoScene(tag); }; Scene.prototype.loadSprites = function () { return __awaiter(this, void 0, void 0, function () { var _this_1 = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, parallel(this.spritesDecor, function (decor) { return __awaiter(_this_1, void 0, void 0, function () { var sprite; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!decor.src) return [3 /*break*/, 2]; return [4 /*yield*/, createAssetImage(decor.src)]; case 1: sprite = _a.sent(); this[decor.propertyKey] = sprite; this.sprites.push(sprite); _a.label = 2; case 2: return [2 /*return*/]; } }); }); }, MAX_ASSET_PARALLEL_LOAD)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; Scene.prototype.loadSounds = function () { return __awaiter(this, void 0, void 0, function () { var _i, _a, decor, sound; return __generator(this, function (_b) { switch (_b.label) { case 0: _i = 0, _a = this.soundsDecor; _b.label = 1; case 1: if (!(_i < _a.length)) return [3 /*break*/, 4]; decor = _a[_i]; if (!decor.src) return [3 /*break*/, 3]; return [4 /*yield*/, createAssetSound(decor.src, decor.type)]; case 2: sound = _b.sent(); if (decor.volume) { sound.volume = decor.volume; } this[decor.propertyKey] = sound; this.sounds.push(sound); _b.label = 3; case 3: _i++; return [3 /*break*/, 1]; case 4: return [2 /*return*/]; } }); }); }; Scene.prototype.createSprites = function () { var _this_1 = this; var sources = []; for (var _i = 0; _i < arguments.length; _i++) { sources[_i] = arguments[_i]; } return parallel(sources, function (source) { return __awaiter(_this_1, void 0, void 0, function () { var src, sprite; return __generator(this, function (_a) { switch (_a.label) { case 0: src = (typeof source === "string" ? { src: source } : source).src; return [4 /*yield*/, createAssetImage(src)]; case 1: sprite = _a.sent(); this.sprites.push(sprite); return [2 /*return*/, sprite]; } }); }); }, MAX_ASSET_PARALLEL_LOAD); }; Scene.prototype.createSounds = function () { var sources = []; for (var _i = 0; _i < arguments.length; _i++) { sources[_i] = arguments[_i]; } return __awaiter(this, void 0, void 0, function () { var sounds, _a, sources_1, source, _b, volume, src, _c, type, sound; return __generator(this, function (_d) { switch (_d.label) { case 0: sounds = []; _a = 0, sources_1 = sources; _d.label = 1; case 1: if (!(_a < sources_1.length)) return [3 /*break*/, 4]; source = sources_1[_a]; _b = typeof source === "string" ? { src: source, volume: undefined, type: undefined } : source, volume = _b.volume, src = _b.src, _c = _b.type, type = _c === void 0 ? SoundType.ONCE : _c; return [4 /*yield*/, createAssetSound(src, type)]; case 2: sound = _d.sent(); if (volume) { sound.volume = volume; } sounds.push(sound); this.sounds.push(sound); _d.label = 3; case 3: _a++; return [3 /*break*/, 1]; case 4: return [2 /*return*/, sounds]; } }); }); }; Scene.prototype.mapSprites = function () { var sources = []; for (var _i = 0; _i < arguments.length; _i++) { sources[_i] = arguments[_i]; } return __awaiter(this, void 0, void 0, function () { var spritesDecor; var _this_1 = this; return __generator(this, function (_a) { switch (_a.label) { case 0: spritesDecor = this.spritesDecor.filter(function (decor) { return !decor.src; }); return [4 /*yield*/, parallel(sources, function (src, _a) { var realIndex = _a.realIndex; return __awaiter(_this_1, void 0, void 0, function () { var decor, sprite; return __generator(this, function (_b) { switch (_b.label) { case 0: decor = spritesDecor[realIndex]; if (!decor) return [3 /*break*/, 2]; return [4 /*yield*/, createAssetImage(src)]; case 1: sprite = _b.sent(); this[decor.propertyKey] = sprite; this.sprites.push(sprite); _b.label = 2; case 2: return [2 /*return*/]; } }); }); }, MAX_ASSET_PARALLEL_LOAD)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; Scene.prototype.mapSounds = function () { var sources = []; for (var _i = 0; _i < arguments.length; _i++) { sources[_i] = arguments[_i]; } return __awaiter(this, void 0, void 0, function () { var soundsDecor, index, _a, soundsDecor_1, decor, src, sound; return __generator(this, function (_b) { switch (_b.label) { case 0: soundsDecor = this.soundsDecor.filter(function (decor) { return !decor.src; }); index = 0; _a = 0, soundsDecor_1 = soundsDecor; _b.label = 1; case 1: if (!(_a < soundsDecor_1.length)) return [3 /*break*/, 4]; decor = soundsDecor_1[_a]; src = sources[index++]; return [4 /*yield*/, createAssetSound(src, decor.type)]; case 2: sound = _b.sent(); if (decor.volume) { sound.volume = decor.volume; } this[decor.propertyKey] = sound; this.sounds.push(sound); _b.label = 3; case 3: _a++; return [3 /*break*/, 1]; case 4: return [2 /*return*/]; } }); }); }; Scene.prototype.loadAssets = function (delay, _a) { var _b = _a === void 0 ? {} : _a, _c = _b.skip, skip = _c === void 0 ? false : _c, render = _b.render; return __awaiter(this, void 0, void 0, function () { var resultLoadSound, result, hasErrors, errors_1; return __generator(this, function (_d) { switch (_d.label) { case 0: if (delay != null) { this.assetsDelay = delay; } // if delay less than 0, it will wait forever return [4 /*yield*/, tick(this.assetsDelay < 0 ? undefined : this.assetsDelay)]; case 1: // if delay less than 0, it will wait forever _d.sent(); this.loadedAssets = false; return [4 /*yield*/, this.loadSounds().catch(function (err) { return { error: true, type: "load-sound", detail: err, }; })]; case 2: resultLoadSound = _d.sent(); if ((resultLoadSound === null || resultLoadSound === void 0 ? void 0 : resultLoadSound.error) && !skip) { this._renderAssetsFail = function () { return render ? render([resultLoadSound]) : [resultLoadSound]; }; this.loadedAssetsError = [resultLoadSound]; return [2 /*return*/]; } return [4 /*yield*/, Promise.all([ this.loadSprites().catch(function (err) { return { error: true, type: "load-sprite", detail: err, }; }), this.onLoadAssets().catch(function (err) { return { error: true, type: "load-extends", detail: err, }; }), ])]; case 3: result = _d.sent(); hasErrors = result.some(function (rs) { return rs === null || rs === void 0 ? void 0 : rs.error; }); if (hasErrors && !skip) { errors_1 = result.filter(function (rs) { return !!(rs === null || rs === void 0 ? void 0 : rs.error); }); // this.loadedAssets = false; this._renderAssetsFail = function () { return render ? render(errors_1) : errors_1; }; this.loadedAssetsError = errors_1; } else { // when don't have error or skip error this.loadedAssets = true; } return [2 /*return*/]; } }); }); }; Scene.prototype.onLoadAssets = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/]; }); }); }; Scene.prototype.getPrefab = function (Class) { return this.prefabs.find(function (pf) { return pf instanceof Class; }); }; Scene.prototype.listenNativeEvents = function () { var _this = this; function onVisibilitychange() { _this.emitProcessStateChangeEvent(window.Renderer.isForeground); } window.document.addEventListener("visibilitychange", onVisibilitychange); this.nativeEventsUnsubscribes = function () { window.document.removeEventListener("visibilitychange", onVisibilitychange); }; }; Scene.prototype.onBootstrapDone = function (simpleCamera) { }; Scene.prototype.bootstrapDone = function (simpleCamera) { this.onBootstrapDone(simpleCamera); }; Scene.prototype.bootstrap = function (simpleCamera) { var _this_1 = this; this._renderer = window.Renderer; this.listenNativeEvents(); this.bootSoundOptions(); this.onProcessStateChangeListener(function (isForeground) { if (isForeground) { if (window.Renderer.running) { for (var _i = 0, _a = _this_1.sounds; _i < _a.length; _i++) { var sound = _a[_i]; // only resume background sounds if (sound.type === SoundType.BACKGROUND) { sound.resume(); } } } } else { // pause all sounds for (var _b = 0, _c = _this_1.sounds; _b < _c.length; _b++) { var sound = _c[_b]; sound.pause(); } } }); this._worldManagement = new WorldManagement(simpleCamera, this); var components = this.getComponents(simpleCamera); var layerIndex = 0; for (var _i = 0, components_1 = components; _i < components_1.length; _i++) { var component = components_1[_i]; component.worldManagement = this._worldManagement; component.layerIndex = layerIndex++; if (component.isPrefab) { this.prefabs.push(component); } else { var entity = component.output(); this._worldManagement.addEntity(entity); } } this._worldManagement.bootstrapCompleted(); this.bootstrapDone(simpleCamera); }; Scene.prototype.onDraw = function () { }; Scene.prototype.onUpdate = function () { }; Scene.prototype.mouseMove = function () { if (this._worldManagement) { this._worldManagement.iterateEntities(function (entity) { entity.onMouseMove(); }); } }; Scene.prototype.mousePressed = function () { if (this._worldManagement) { this._worldManagement.iterateEntities(function (entity) { entity.onMousePressed(); }); } }; Scene.prototype.mouseRelease = function () { if (this._worldManagement) { this._worldManagement.iterateEntities(function (entity) { entity.onMouseRelease(); }); } }; Scene.prototype.action = function () { if (Renderer.running && Renderer.isForeground) { this.onUpdate(); this._worldManagement.update(); } Renderer.background(41, 41, 41); this.onDraw(); this._worldManagement.draw(); }; return Scene; }()); export { Scene };