UNPKG

oxygen-core

Version:

Oxygen game engine (Xenon Core for browsers)

530 lines (491 loc) 15.4 kB
import JSONAsset from './asset-loaders/JSONAsset'; import TextAsset from './asset-loaders/TextAsset'; import BinaryAsset from './asset-loaders/BinaryAsset'; import ImageAsset from './asset-loaders/ImageAsset'; import ShaderAsset from './asset-loaders/ShaderAsset'; import SceneAsset from './asset-loaders/SceneAsset'; import AtlasAsset from './asset-loaders/AtlasAsset'; import FontAsset from './asset-loaders/FontAsset'; import SoundAsset from './asset-loaders/SoundAsset'; import MusicAsset from './asset-loaders/MusicAsset'; import ParticleSystemAsset from './asset-loaders/ParticleSystemAsset'; import PackAsset from './asset-loaders/PackAsset'; import SkeletonAsset from './asset-loaders/SkeletonAsset'; import SVGAsset from './asset-loaders/SVGAsset'; import SetAsset from './asset-loaders/SetAsset'; import AssemblyAsset from './asset-loaders/AssemblyAsset'; import PostprocessRackEffectAsset from './asset-loaders/PostprocessRackEffectAsset'; import Camera, { PostprocessPass } from './components/Camera'; import Camera2D from './components/Camera2D'; import CameraDirector2D from './components/CameraDirector2D'; import InputHandler from './components/InputHandler'; import GestureListener from './components/GestureListener'; import Particles from './components/Particles'; import PhysicsBody from './components/PhysicsBody'; import PhysicsWorld from './components/PhysicsWorld'; import PrefabInstance from './components/PrefabInstance'; import RectangleRenderer from './components/RectangleRenderer'; import Script from './components/Script'; import Sprite from './components/Sprite'; import AtlasSprite from './components/AtlasSprite'; import TextRenderer from './components/TextRenderer'; import VerticesRenderer from './components/VerticesRenderer'; import UiSprite from './components/UiSprite'; import UiLayout from './components/UiLayout'; import Skeleton from './components/Skeleton'; import SortedActions from './components/SortedActions'; import DeferredRenderer, { DeferredPipeline } from './components/DeferredRenderer'; import MultipassRenderer, { MultipassPipeline } from './components/MultipassRenderer'; import PostprocessRack, { PostprocessRackPass, PostprocessRackRawEffectPass } from './components/PostprocessRack'; import Shape from './components/Shape'; import PolygonShape from './components/PolygonShape'; import CircleShape from './components/CircleShape'; import RectangleShape from './components/RectangleShape'; import System from './systems/System'; import EntitySystem from './systems/EntitySystem'; import Component from './systems/EntitySystem/Component'; import Entity from './systems/EntitySystem/Entity'; import AssetSystem from './systems/AssetSystem'; import Asset from './systems/AssetSystem/Asset'; import RenderSystem, { RenderTargetWrapper, Command, Pipeline, RenderFullscreenCommand } from './systems/RenderSystem'; import InputSystem from './systems/InputSystem'; import StorageSystem from './systems/StorageSystem'; import AudioSystem from './systems/AudioSystem'; import AssemblySystem from './systems/AssemblySystem'; import Events from './utils/Events'; import { glMatrix, mat2, mat2d, mat3, mat4, quat, vec2, vec3, vec4 } from './utils/gl-matrix'; import { box2d } from './utils'; import AssetLoaders from './asset-loaders'; import Components from './components'; import Systems from './systems'; import Utils from './utils'; export default { AssetLoaders, Components, Systems, Utils, JSONAsset, TextAsset, BinaryAsset, ImageAsset, ShaderAsset, SceneAsset, AtlasAsset, FontAsset, SoundAsset, MusicAsset, ParticleSystemAsset, PackAsset, SkeletonAsset, SVGAsset, SetAsset, AssemblyAsset, PostprocessRackEffectAsset, Camera, PostprocessPass, Camera2D, CameraDirector2D, InputHandler, GestureListener, Particles, PhysicsBody, PhysicsWorld, PrefabInstance, RectangleRenderer, Script, Sprite, AtlasSprite, TextRenderer, VerticesRenderer, UiSprite, UiLayout, Skeleton, SortedActions, DeferredRenderer, DeferredPipeline, MultipassRenderer, MultipassPipeline, PostprocessRack, PostprocessRackPass, PostprocessRackRawEffectPass, Shape, PolygonShape, CircleShape, RectangleShape, System, EntitySystem, Component, Entity, RenderSystem, RenderTargetWrapper, Command, Pipeline, RenderFullscreenCommand, InputSystem, StorageSystem, AssetSystem, Asset, AudioSystem, AssemblySystem, Events, glMatrix, mat2, mat2d, mat3, mat4, quat, vec2, vec3, vec4, box2d }; export { AssetLoaders, Components, Systems, Utils, JSONAsset, TextAsset, BinaryAsset, ImageAsset, ShaderAsset, SceneAsset, AtlasAsset, FontAsset, SoundAsset, MusicAsset, ParticleSystemAsset, PackAsset, SkeletonAsset, SVGAsset, SetAsset, AssemblyAsset, PostprocessRackEffectAsset, Camera, PostprocessPass, Camera2D, CameraDirector2D, InputHandler, GestureListener, Particles, PhysicsBody, PhysicsWorld, PrefabInstance, RectangleRenderer, Script, Sprite, AtlasSprite, TextRenderer, VerticesRenderer, UiSprite, UiLayout, Skeleton, SortedActions, DeferredRenderer, DeferredPipeline, MultipassRenderer, MultipassPipeline, PostprocessRack, PostprocessRackPass, PostprocessRackRawEffectPass, Shape, PolygonShape, CircleShape, RectangleShape, System, EntitySystem, Component, Entity, RenderSystem, RenderTargetWrapper, Command, Pipeline, RenderFullscreenCommand, InputSystem, StorageSystem, AssetSystem, Asset, AudioSystem, AssemblySystem, Events, glMatrix, mat2, mat2d, mat3, mat4, quat, vec2, vec3, vec4, box2d }; export class EventsController { get transform() { return this._transform; } set transform(value) { if (typeof value !== 'boolean') { throw new Error('`value` is not type of Boolean!'); } this._transform = value; } get update() { return this._update; } set update(value) { if (typeof value !== 'boolean') { throw new Error('`value` is not type of Boolean!'); } this._update = value; } get view() { return this._view; } set view(value) { if (typeof value !== 'boolean') { throw new Error('`value` is not type of Boolean!'); } this._view = value; } get gamepads() { return this._gamepads; } set gamepads(value) { if (typeof value !== 'boolean') { throw new Error('`value` is not type of Boolean!'); } this._gamepads = value; } get all() { return this._transform && this._update && this._view && this._gamepads; } set all(value) { if (typeof value !== 'boolean') { throw new Error('`value` is not type of Boolean!'); } this._transform = this._update = this._view = this._gamepads = value; } get none() { return !this._transform && !this._update && !this._view && !this._gamepads; } set none(value) { if (typeof value !== 'boolean') { throw new Error('`value` is not type of Boolean!'); } this._transform = this._update = this._view = this._gamepads = !value; } get accepted() { const result = []; if (!!this._transform) { result.push('transform'); } if (!!this._update) { result.push('update'); } if (!!this._view) { result.push('view'); } if (!!this._gamepads) { result.push('gamepads'); } return result; } set accepted(value) { if (!Array.isArray(value)) { throw new Error('`value` is not type of Array!'); } this._transform = value.indexOf('transform') >= 0; this._update = value.indexOf('update') >= 0; this._view = value.indexOf('view') >= 0; this._gamepads = value.indexOf('gamepads') >= 0; } constructor() { this._transform = true; this._update = true; this._view = true; this._gamepads = true; } } /** * Function used to initialize Oxygen Core engine without any effort. * * @param {*} config - engine configuration options. * @return {EventsController} - instance used to dynamically control events processing. * * @example * lazyInitialization({ * entities: { triggerEvents: true }, * asset: { pathPrefix: 'assets/' }, * render: { screen: 'screen-0' }, * input: { triggerEvents: true }, * store: { id: 'my-game-id' }, * events: { transform: true, update: true, view: true, gamepads: true } * }); */ export function lazyInitialization({ entity, asset, render, input, store, events }) { const entities = System.register('EntitySystem', new EntitySystem( !!entity ? entity.triggerEvents : true )); const assets = System.register('AssetSystem', new AssetSystem( !!asset ? asset.pathPrefix : null, !!asset ? asset.fetchOptions : null, !!asset ? asset.fetchEngine : null )); const renderer = System.register('RenderSystem', new RenderSystem( !!render ? render.screen : null, !!render ? render.optimize : true, !!render ? render.extensions : null, !!render ? render.version : 1, !!render ? render.manualMode : false )); const inputs = System.register('InputSystem', new InputSystem( renderer.canvas, !!input ? input.triggerEvents : true )); const storage = System.register('StorageSystem', new StorageSystem( !!store ? store.id : 'oxygen-data' )); const audio = System.register('AudioSystem', new AudioSystem()); const assembly = System.register('AssemblySystem', new AssemblySystem()); const controller = new EventsController(); controller.transform = !!events ? !!events.transform : true; controller.update = !!events ? !!events.update : true; controller.view = !!events ? !!events.view : true; controller.gamepads = !!events ? !!events.gamepads : true; entities.registerComponent('Camera2D', Camera2D.factory); entities.registerComponent('CameraDirector2D', CameraDirector2D.factory); entities.registerComponent('InputHandler', InputHandler.factory); entities.registerComponent('GestureListener', GestureListener.factory); entities.registerComponent('Particles', Particles.factory); entities.registerComponent('PhysicsBody', PhysicsBody.factory); entities.registerComponent('PhysicsWorld', PhysicsWorld.factory); entities.registerComponent('PrefabInstance', PrefabInstance.factory); entities.registerComponent('RectangleRenderer', RectangleRenderer.factory); entities.registerComponent('Script', Script.factory); entities.registerComponent('Sprite', Sprite.factory); entities.registerComponent('AtlasSprite', AtlasSprite.factory); entities.registerComponent('TextRenderer', TextRenderer.factory); entities.registerComponent('VerticesRenderer', VerticesRenderer.factory); entities.registerComponent('UiSprite', UiSprite.factory); entities.registerComponent('UiLayout', UiLayout.factory); entities.registerComponent('Skeleton', Skeleton.factory); entities.registerComponent('SortedActions', SortedActions.factory); entities.registerComponent('DeferredRenderer', DeferredRenderer.factory); entities.registerComponent('MultipassRenderer', MultipassRenderer.factory); entities.registerComponent('PostprocessRack', PostprocessRack.factory); entities.registerComponent('PolygonShape', PolygonShape.factory); entities.registerComponent('CircleShape', CircleShape.factory); entities.registerComponent('RectangleShape', RectangleShape.factory); assets.registerProtocol('json', JSONAsset.factory); assets.registerProtocol('text', TextAsset.factory); assets.registerProtocol('binary', BinaryAsset.factory); assets.registerProtocol('image', ImageAsset.factory); assets.registerProtocol('shader', ShaderAsset.factory); assets.registerProtocol('scene', SceneAsset.factory); assets.registerProtocol('atlas', AtlasAsset.factory); assets.registerProtocol('font', FontAsset.factory); assets.registerProtocol('sound', SoundAsset.factory); assets.registerProtocol('music', MusicAsset.factory); assets.registerProtocol('particles', ParticleSystemAsset.factory); assets.registerProtocol('pack', PackAsset.factory); assets.registerProtocol('skeleton', SkeletonAsset.factory); assets.registerProtocol('svg', SVGAsset.factory); assets.registerProtocol('set', SetAsset.factory); assets.registerProtocol('wasm', AssemblyAsset.factory); assets.registerProtocol('postprocess', PostprocessRackEffectAsset.factory); assets.events.on('load', asset => { const { protocol, filename, data } = asset; if (protocol === 'image' || protocol === 'svg') { renderer.registerTexture( filename, data, !!asset.options && !!asset.options.mipmap ); } else if (protocol === 'shader') { renderer.registerShader( filename, data.vertex, data.fragment, data.layout, data.uniforms, data.samplers, data.blending, data.extensions ); } else if (protocol === 'sound') { audio.registerSound(filename, data); } else if (protocol === 'music') { audio.registerMusic(filename, data); } else if (protocol === 'particles') { Particles.registerProcessor(filename, data); } else if (protocol === 'wasm') { assembly.registerAssembly( filename, data, !!asset.options && !!asset.options.imports ? (assembly.getImports(asset.options.imports) || {}) : null ); } }); assets.events.on('unload', asset => { const { protocol, filename } = asset; if (protocol === 'image' || protocol === 'svg') { renderer.unregisterTexture(filename); } else if (protocol === 'shader') { renderer.unregisterShader(filename); } else if (protocol === 'sound') { audio.unregisterSound(filename); } else if (protocol === 'music') { audio.unregisterMusic(filename); } else if (protocol === 'particles') { Particles.unregisterProcessor(filename); } else if (protocol === 'wasm') { assembly.unregisterAssembly(filename); } }); renderer.events.on('render', (context, renderer, deltaTime) => { !!controller.transform && entities.updateTransforms(); !!controller.update && entities.performAction('update', deltaTime); !!controller.view && entities.performAction('view', context, renderer, deltaTime); !!controller.gamepads && inputs.scanForGamepads(); }); System.events.on('change-scene', path => { const asset = assets.get(path); if (!asset) { throw new Error(`There is no asset loaded: ${path}`); } if (!(asset instanceof SceneAsset)) { throw new Error(`Asset is not type of SceneAsset: ${path}`); } entities.root = entities.buildEntity(asset.data); }); System.events.on('clear-scene', () => { entities.root = null; }); return controller; }