]>
git.r.bdr.sh - rbdr/sumo/blob - lib/factories/sumo.js
1 import { Bodies
, Constraint
} from 'matter-js';
2 import { Entity
} from '@serpentity/serpentity';
6 import AngleComponent
from '../components/angle';
7 import BodyComponent
from '../components/body';
8 import ControlMapComponent
from '../components/control_map';
9 import CoupledEntitiesComponent
from '../components/coupled_entities';
10 import DashComponent
from '../components/dash';
11 import ElasticComponent
from '../components/elastic';
12 import ForceComponent
from '../components/force';
13 import MaxVelocityComponent
from '../components/max_velocity';
14 import PositionComponent
from '@serpentity/components.position';
15 import PixiContainerComponent
from '../components/pixi_container';
17 import PixiFactory
from '../factories/pixi';
18 import Config
from '../config';
21 kNoEntityError: 'Entity Not Found: This method requires entityA and entityB to be set in the config.',
22 kEntityHasNoBodyError: 'Entity Has No Body: This method requires entities have a BodyComponent.'
26 * Factory object that contains many methods to create prefab entities.
34 * Creates a sumo entity and adds it to the engine. Can override
35 * position in the config object
37 * @function createSumo
38 * @memberof SumoFactory
39 * @param {external:Serpentity} [engine] the serpentity engine to attach
40 * to. If not sent, it will not be attached.
41 * @param {object} [config] the config to override the entity, accepts
42 * the key `position` as an object with an x and y property.
43 * @return {external:Serpentity.Entity} the created entity
45 createSumo(engine
, config
= {}) {
47 const entity
= new Entity();
51 entity
.addComponent(new PositionComponent(config
.position
));
52 const position
= entity
.getComponent(PositionComponent
);
54 entity
.addComponent(new AngleComponent(config
.angle
));
55 const angle
= entity
.getComponent(AngleComponent
);
57 entity
.addComponent(new ForceComponent(config
.force
));
59 config
.maxVelocity
= {
62 entity
.addComponent(new MaxVelocityComponent(config
.maxVelocity
));
64 // CONTROLS & ABILITIES
66 entity
.addComponent(new DashComponent(config
.dash
));
72 const container
= config
.container
|| {
73 container: PixiFactory
.createSumo({ radius
})
75 container
.container
.position
.x
= position
.x
;
76 container
.container
.position
.y
= position
.y
;
77 container
.container
.rotation
= angle
.angle
;
78 entity
.addComponent(new PixiContainerComponent(container
));
82 const frictionAir
= 0.02;
84 const frictionStatic
= 1;
85 const restitution
= 1;
88 const body
= Bodies
.circle(position
.x
/ Config
.meterSize
, position
.y
/ Config
.meterSize
, radius
/ Config
.meterSize
, {
97 entity
.addComponent(new BodyComponent({ body
}));
100 engine
.addEntity(entity
);
107 * Creates a rubber band entity and adds it to the engine.
109 * @function createRubberBand
110 * @memberof SumoFactory
111 * @param {external:Serpentity} [engine] the serpentity engine to attach
112 * to. If not sent, it will not be attached.
113 * @param {object} [config] the config to override the entity, it
114 * must include entityA and entityB which will be tied by it. If they
115 * are not sent or don't have a physics body, this will throw.
116 * @return {external:Serpentity.Entity} the created entity
118 createRubberBand(engine
, config
= {}) {
120 const entity
= new Entity();
122 if (!config
.entityA
|| !config
.entityB
) {
123 throw new Error(internals
.kNoEntityError
);
126 if (!config
.entityA
.hasComponent(BodyComponent
) || !config
.entityB
.hasComponent(BodyComponent
)) {
127 throw new Error(internals
.kEntityHasNoBodyError
);
132 const container
= config
.container
|| {
133 container: PixiFactory
.createEmptyGraphic()
135 entity
.addComponent(new PixiContainerComponent(container
));
139 const bodyA
= config
.entityA
.getComponent(BodyComponent
).body
;
140 const bodyB
= config
.entityB
.getComponent(BodyComponent
).body
;
142 const length
= 100 / Config
.meterSize
;
143 const stiffness
= 0.001;
145 const body
= Constraint
.create({
152 entity
.addComponent(new BodyComponent({ body
}));
154 entity
.addComponent(new CoupledEntitiesComponent({
155 coupledEntities: [config
.entityA
, config
.entityB
]
158 entity
.addComponent(new ElasticComponent());
161 engine
.addEntity(entity
);
168 * Creates a controllable sumo entity and adds it to the engine. Can override
169 * position in the config object
171 * @function createControllableSumo
172 * @memberof SumoFactory
173 * @param {external:Serpentity} [engine] the serpentity engine to attach
174 * to. If not sent, it will not be attached.
175 * @param {object} [config] the config to override the entity, accepts
176 * the key `position` as an object with an x and y property.
177 * @return {external:Serpentity.Entity} the created entity
179 createControllableSumo(engine
, config
= {}) {
181 const entity
= this.createSumo(null, config
);
183 entity
.addComponent(new ControlMapComponent({
188 index: 37 // left arrow
191 component: ForceComponent
,
193 value: (value
) => -Number(value
)
199 index: 39 // right arrow
202 component: ForceComponent
,
204 value: (value
) => Number(value
)
210 index: 38 // up arrow
213 component: ForceComponent
,
215 value: (value
) => -Number(value
)
221 index: 40 // down arrow
224 component: ForceComponent
,
226 value: (value
) => Number(value
)
235 component: DashComponent
,
243 engine
.addEntity(entity
);
250 * Creates a static harness entity
252 * @function createHarness
253 * @memberof SumoFactory
254 * @param {external:Serpentity} [engine] the serpentity engine to attach
255 * to. If not sent, it will not be attached.
256 * @param {object} [config] the config to override the entity, accepts
257 * the key `position` as an object with an x and y property.
258 * @return {external:Serpentity.Entity} the created entity
260 createHarness(engine
, config
= {}) {
262 const entity
= new Entity();
266 entity
.addComponent(new PositionComponent(config
.position
));
267 const position
= entity
.getComponent(PositionComponent
);
273 const container
= config
.container
|| {
274 container: PixiFactory
.createHarness({ radius
})
276 container
.container
.position
.x
= position
.x
;
277 container
.container
.position
.y
= position
.y
;
278 entity
.addComponent(new PixiContainerComponent(container
));
283 const frictionStatic
= 0;
284 const restitution
= 1;
286 const body
= Bodies
.circle(position
.x
/ Config
.meterSize
, position
.y
/ Config
.meterSize
, radius
/ Config
.meterSize
, {
288 label: 'Harness body',
293 entity
.addComponent(new BodyComponent({ body
}));
296 engine
.addEntity(entity
);
303 * Creates a static arena entity
305 * @function createArena
306 * @memberof SumoFactory
307 * @param {external:Serpentity} [engine] the serpentity engine to attach
308 * to. If not sent, it will not be attached.
309 * @param {object} [config] the config to override the entity, accepts
310 * the key `position` as an object with an x and y property.
311 * @return {external:Serpentity.Entity} the created entity
313 createArena(engine
, config
= {}) {
315 const entity
= new Entity();
319 entity
.addComponent(new PositionComponent(config
.position
));
320 const position
= entity
.getComponent(PositionComponent
);
326 const container
= config
.container
|| {
327 container: PixiFactory
.createArena({ radius
})
329 container
.container
.position
.x
= position
.x
;
330 container
.container
.position
.y
= position
.y
;
331 entity
.addComponent(new PixiContainerComponent(container
));
334 engine
.addEntity(entity
);