UNPKG

javascript-entity-component-system

Version:
3 lines (2 loc) 7.44 kB
!function(){const t=new class{constructor(){this.components=[],this.processors=[],this.entities=[]}getProcessors(){return this.processors}getComponents(){return this.components}getEntities(){return this.entities}getProcessor(t){if(!this.hasProcessor(t))throw new Error(`getProcessor(): processor "${t}" not found.`);return this.processors.find((e=>e.name===t))}getComponent(t){if(!this.hasComponent(t))throw new Error(`getComponent(): component "${t}" not found.`);return this.components.find((e=>e.name===t))}getEntity(t){if(!this.hasEntity(t))throw new Error(`getEntity(): entity "${t}" not found.`);return this.entities.find((e=>e.name===t))}getEntitiesByName(t){const e=[],o=this.entities.length;for(let s=0;s<o;s++){const o=this.entities[s];o.name===t&&e.push(o)}return e}getEntityComponents(t,e){const o=[],s=t.components.length;for(let n of e)for(let e=0;e<s;e++){const s=t.components[e];s.name===n&&o.push(s)}return o}hasProcessor(t){let e=!1;for(let o of this.processors)o.name===t&&(e=!0);return e}hasComponent(t){let e=!1;for(let o of this.components)o.name===t&&(e=!0);return e}hasEntity(t){let e=!1;for(let o of this.entities)o.name===t&&(e=!0);return e}createEntity(t,e,o){const s=t,n=[],r=[];return e.forEach((t=>{const e=this.getComponent(t),o=JSON.parse(JSON.stringify(e));o.onAttach&&e.onAttach(),n.push(o)})),o.forEach((t=>{const e=this.getProcessor(t);r.push(e)})),{name:s,components:n,processors:r}}entityHasComponent(t,e){const o=t.components.length;for(let s=0;s<o;s++)if(t.components[s].name===e)return!0;return!1}entityHasProcessor(t,e){const o=t.processors.length;for(let s=0;s<o;s++)if(t.processors[s].name===e)return!0;return!1}removeComponentFromEntity(t,e){if(!this.entityHasComponent(t,e))throw new Error(`removeComponentFromEntity(): component ${e} not found in entity ${t.name}`);let o=null;const s=t.components.length;for(let n=0;n<s;n++)if(t.components[n].name===e){o=n;break}t.components.splice(o,1)}removeProcessorFromEntity(t,e){if(!this.entityHasProcessor(t,e))throw new Error(`removeProcessorFromEntity(): Processor ${e} not found in entity ${t.name}`);let o=null;const s=t.processors.length;for(let n=0;n<s;n++)if(t.processors[n].name===e){o=n;break}t.processors.splice(o,1)}addComponentToEntity(t,e){if(this.entityHasComponent(t,e))throw new Error(`addComponentToEntity(): Can't add component ${e} - this entity already has this component.`);if(!this.hasComponent(e))throw new Error(`addComponentToEntity(): You can't add component ${e} to entity ${t.name}, because the component is not registered.`);t.components.push(this.getComponent(e))}addProcessorToEntity(t,e){if(this.entityHasProcessor(t,e))throw new Error(`addProcessorToEntity(): Can't add processor ${e} - this entity already this processor.`);if(!this.hasProcessor(e))throw new Error(`addProcessorToEntity(): You can't add processor ${e} to entity ${t.name}, because the processor is not registerd.`);t.processors.push(this.getProcessor(e))}addEntity(t){this.entities.push(t)}addComponent(t){const e=t;e.onAttach&&e.onAttach(),this.components.push(e)}addProcessor(t){this.processors.push(t)}removeEntity(t){const e=this.entities.length;for(let o=0;o<e;o++)if(this.entities[o]===t)return void this.entities.splice(o,1);throw new Error(`removeEntity(): entity "${t.name}" not found.`)}removeAllEntities(){this.entities=[]}getEntitiesFromRequiredComponents(t){const e=[];let o=this.entities.length;for(let s=0;s<o;s++){const o=this.entities[s];let n=!0;for(let e=0;e<t.length;e++){const s=t[e];if(!this.entityHasComponent(o,s)){n=!1;break}}n&&e.push(o)}return e}runProcessors(){this.processors.forEach((t=>{const e=this.getEntitiesFromRequiredComponents(t.required),o=e.length;for(let s=0;s<o;s++){const o=e[s];if(this.entityHasProcessor(o,t.name)){const e=this.getEntityComponents(o,t.required);t.update(o,e,t)}}}))}update(){this.runProcessors()}},e={name:"gravity_processor",required:["position","mass"],update(t,e,o){const[s,n]=e;n.state.velocityY+=n.state.mass,s.state.y+=n.state.velocityY,s.state.x+=n.state.velocityX}},o={name:"shape_draw_processor",required:["position","shape"],update(t,e,o){const[s,n]=e;c.translate(s.state.x,s.state.y),c.fillStyle=n.state.color,c.fillRect(0,0,n.state.size,n.state.size),c.translate(-s.state.x,-s.state.y)}},s={name:"edge_collision_processor",required:["position","collision","shape"],update(t,e,o){const[s,n,r]=e,c=s.state.x,a=s.state.y,h=r.state.size;c<=0||c+h>=i.width?n.state.collisionX=!0:n.state.collisionX=!1,a<=0||a+h>=i.height?n.state.collisionY=!0:n.state.collisionY=!1}},n={name:"bounce_processor",required:["position","collision","mass"],update(t,e,o){const[s,n,r]=e;n.state.collisionY&&(r.state.velocityY=-r.state.velocityY),n.state.collisionX&&(r.state.velocityX=-r.state.velocityX)}},r={name:"jitter_processor",required:["position"],update(t,e,o){const[s]=e;s.state.x+=10*Math.random()-5,s.state.y+=10*Math.random()-5}};t.addComponent({name:"position",state:{x:0,y:0}}),t.addComponent({name:"mass",state:{mass:.2,velocityX:1,velocityY:0}}),t.addComponent({name:"shape",state:{size:10,color:"red"}}),t.addComponent({name:"collision",state:{collisionX:!1,collisionY:!1}}),t.addProcessor(e),t.addProcessor(o),t.addProcessor(s),t.addProcessor(n),t.addProcessor(r);const i=document.querySelector("canvas"),c=i.getContext("2d"),a=()=>{c.clearRect(0,0,i.width,i.height),t.update(),requestAnimationFrame(a)};let h=!0,d=!0,m=!1;const p=()=>{const e=["shape_draw_processor","bounce_processor"];h&&e.push("gravity_processor"),d&&e.push("edge_collision_processor"),m&&e.push("jitter_processor");const o=t.createEntity("box",["position","mass","shape","collision"],e);t.addEntity(o)},l=e=>{const o=["shape_draw_processor","bounce_processor"];h&&o.push("gravity_processor"),d&&o.push("edge_collision_processor"),m&&o.push("jitter_processor");for(let s=0;s<e;s++){const e=t.createEntity("box",["position","mass","shape","collision"],o),[s,n,r]=t.getEntityComponents(e,["position","shape","mass"]),c=["green","blue","orange","red","white"],a=c[Math.floor(Math.random()*c.length)],h=.5*Math.random()+.1,d=15*Math.random(),m=Math.random()*i.width,p=Math.random()*i.height,l=2*Math.random()-1;s.state.x=m,s.state.y=p,n.state.color=a,n.state.size=d,r.state.mass=h,r.state.velocityX=l,t.addEntity(e)}},y=document.getElementById("gravity-checkbox"),u=document.getElementById("collision-checkbox"),f=document.getElementById("jitter-checkbox");y.addEventListener("change",(()=>{const e=y.checked,o=t.getEntitiesByName("box");if(!e){h=!1;for(let e of o)t.removeProcessorFromEntity(e,"gravity_processor")}if(e){h=!0;for(let e of o)t.addProcessorToEntity(e,"gravity_processor")}})),u.addEventListener("change",(()=>{const e=u.checked,o=t.getEntitiesByName("box");if(!e){d=!1;for(let e of o)t.removeProcessorFromEntity(e,"edge_collision_processor")}if(e){d=!0;for(let e of o)t.addProcessorToEntity(e,"edge_collision_processor")}})),f.addEventListener("change",(()=>{const e=f.checked,o=t.getEntitiesByName("box");if(!e){m=!1;for(let e of o)t.removeProcessorFromEntity(e,"jitter_processor")}if(e){m=!0;for(let e of o)t.addProcessorToEntity(e,"jitter_processor")}}));const E=document.getElementById("random-box-button"),g=document.getElementById("random-box-button-50"),v=document.getElementById("reset-button");E.addEventListener("click",(()=>{l(1)})),g.addEventListener("click",(()=>{l(50)}));v.addEventListener("click",(()=>{t.removeAllEntities(),p()})),p(),a()}(); //# sourceMappingURL=index.bca4918e.js.map