]>
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 GrabAreaComponent
from '../components/grab_area';
14 import GrabbableComponent
from '../components/grabbable';
15 import GrabComponent
from '../components/grab';
16 import MaxVelocityComponent
from '../components/max_velocity';
17 import PositionComponent
from '@serpentity/components.position';
18 import PixiContainerComponent
from '../components/pixi_container';
20 import PixiFactory
from '../factories/pixi';
21 import Config
from '../config';
24 kNoEntityError: 'Entity Not Found: This method requires entityA and entityB to be set in the config.',
25 kEntityHasNoBodyError: 'Entity Has No Body: This method requires entities have a BodyComponent.'
29 * Factory object that contains many methods to create prefab entities.
37 * Creates a sumo entity and adds it to the engine. Can override
38 * position in the config object
40 * @function createSumo
41 * @memberof SumoFactory
42 * @param {external:Serpentity} [engine] the serpentity engine to attach
43 * to. If not sent, it will not be attached.
44 * @param {object} [config] the config to override the entity, accepts
45 * the key `position` as an object with an x and y property.
46 * @return {external:Serpentity.Entity} the created entity
48 createSumo(engine
, config
= {}) {
50 const entity
= new Entity();
54 entity
.addComponent(new PositionComponent(config
.position
));
55 const position
= entity
.getComponent(PositionComponent
);
57 entity
.addComponent(new AngleComponent(config
.angle
));
58 const angle
= entity
.getComponent(AngleComponent
);
60 entity
.addComponent(new ForceComponent(config
.force
));
62 config
.maxVelocity
= {
65 entity
.addComponent(new MaxVelocityComponent(config
.maxVelocity
));
67 // CONTROLS & ABILITIES
69 entity
.addComponent(new DashComponent(config
.dash
));
75 const container
= config
.container
|| {
76 container: PixiFactory
.createSumo({ radius
})
78 container
.container
.position
.x
= position
.x
;
79 container
.container
.position
.y
= position
.y
;
80 container
.container
.rotation
= angle
.angle
;
81 entity
.addComponent(new PixiContainerComponent(container
));
85 const frictionAir
= 0.02;
86 const friction
= 0.01;
87 const frictionStatic
= 0.01;
88 const restitution
= 1;
91 const body
= Bodies
.circle(position
.x
/ Config
.meterSize
, position
.y
/ Config
.meterSize
, radius
/ Config
.meterSize
, {
100 entity
.addComponent(new BodyComponent({ body
}));
104 const areaSizeFactor
= 2; // Multiplier vs the radius
105 const area
= Bodies
.circle(position
.x
/ Config
.meterSize
, position
.y
/ Config
.meterSize
, (radius
* areaSizeFactor
) / Config
.meterSize
, {
106 label: 'Sumo Grab Area',
110 entity
.addComponent(new GrabAreaComponent({ area
}));
111 entity
.addComponent(new GrabComponent({ body
}));
112 entity
.addComponent(new GrabbableComponent({ body
}));
115 engine
.addEntity(entity
);
122 * Creates a rubber band entity and adds it to the engine.
124 * @function createRubberBand
125 * @memberof SumoFactory
126 * @param {external:Serpentity} [engine] the serpentity engine to attach
127 * to. If not sent, it will not be attached.
128 * @param {object} [config] the config to override the entity, it
129 * must include entityA and entityB which will be tied by it. If they
130 * are not sent or don't have a physics body, this will throw.
131 * @return {external:Serpentity.Entity} the created entity
133 createRubberBand(engine
, config
= {}) {
135 const entity
= new Entity();
137 if (!config
.entityA
|| !config
.entityB
) {
138 throw new Error(internals
.kNoEntityError
);
141 if (!config
.entityA
.hasComponent(BodyComponent
) || !config
.entityB
.hasComponent(BodyComponent
)) {
142 throw new Error(internals
.kEntityHasNoBodyError
);
147 const container
= config
.container
|| {
148 container: PixiFactory
.createEmptyGraphic()
150 entity
.addComponent(new PixiContainerComponent(container
));
154 const bodyA
= config
.entityA
.getComponent(BodyComponent
).body
;
155 const bodyB
= config
.entityB
.getComponent(BodyComponent
).body
;
157 const length
= 100 / Config
.meterSize
;
158 const stiffness
= 0.001;
160 const body
= Constraint
.create({
167 entity
.addComponent(new BodyComponent({ body
}));
169 entity
.addComponent(new CoupledEntitiesComponent({
170 coupledEntities: [config
.entityA
, config
.entityB
]
173 entity
.addComponent(new ElasticComponent());
176 engine
.addEntity(entity
);
183 * Creates a controllable sumo entity and adds it to the engine. Can override
184 * position in the config object
186 * @function createControllableSumo
187 * @memberof SumoFactory
188 * @param {external:Serpentity} [engine] the serpentity engine to attach
189 * to. If not sent, it will not be attached.
190 * @param {object} [config] the config to override the entity, accepts
191 * the key `position` as an object with an x and y property.
192 * @return {external:Serpentity.Entity} the created entity
194 createControllableSumo(engine
, config
= {}) {
196 const entity
= this.createSumo(null, config
);
198 entity
.addComponent(new ControlMapComponent({
203 index: 37 // left arrow
206 component: ForceComponent
,
208 value: (value
) => -Number(value
)
214 index: 39 // right arrow
217 component: ForceComponent
,
219 value: (value
) => Number(value
)
225 index: 38 // up arrow
228 component: ForceComponent
,
230 value: (value
) => -Number(value
)
236 index: 40 // down arrow
239 component: ForceComponent
,
241 value: (value
) => Number(value
)
250 component: DashComponent
,
260 component: GrabComponent
,
268 engine
.addEntity(entity
);
275 * Creates a static harness entity
277 * @function createHarness
278 * @memberof SumoFactory
279 * @param {external:Serpentity} [engine] the serpentity engine to attach
280 * to. If not sent, it will not be attached.
281 * @param {object} [config] the config to override the entity, accepts
282 * the key `position` as an object with an x and y property.
283 * @return {external:Serpentity.Entity} the created entity
285 createHarness(engine
, config
= {}) {
287 const entity
= new Entity();
291 entity
.addComponent(new PositionComponent(config
.position
));
292 const position
= entity
.getComponent(PositionComponent
);
298 const container
= config
.container
|| {
299 container: PixiFactory
.createHarness({ radius
})
301 container
.container
.position
.x
= position
.x
;
302 container
.container
.position
.y
= position
.y
;
303 entity
.addComponent(new PixiContainerComponent(container
));
308 const frictionStatic
= 0;
309 const restitution
= 1;
311 const body
= Bodies
.circle(position
.x
/ Config
.meterSize
, position
.y
/ Config
.meterSize
, radius
/ Config
.meterSize
, {
313 label: 'Harness body',
318 entity
.addComponent(new BodyComponent({ body
}));
321 engine
.addEntity(entity
);
328 * Creates a static arena entity
330 * @function createArena
331 * @memberof SumoFactory
332 * @param {external:Serpentity} [engine] the serpentity engine to attach
333 * to. If not sent, it will not be attached.
334 * @param {object} [config] the config to override the entity, accepts
335 * the key `position` as an object with an x and y property.
336 * @return {external:Serpentity.Entity} the created entity
338 createArena(engine
, config
= {}) {
340 const entity
= new Entity();
344 entity
.addComponent(new PositionComponent(config
.position
));
345 const position
= entity
.getComponent(PositionComponent
);
351 const container
= config
.container
|| {
352 container: PixiFactory
.createArena({ radius
})
354 container
.container
.position
.x
= position
.x
;
355 container
.container
.position
.y
= position
.y
;
356 entity
.addComponent(new PixiContainerComponent(container
));
359 engine
.addEntity(entity
);
366 * Creates an invisible block
368 * @function createInvisibleBlock
369 * @memberof SumoFactory
370 * @param {external:Serpentity} [engine] the serpentity engine to attach
371 * to. If not sent, it will not be attached.
372 * @param {object} [config] the config to override the entity, accepts
373 * the key `position` as an object with an x and y property.
374 * @return {external:Serpentity.Entity} the created entity
376 createInvisibleBlock(engine
, config
= {}) {
378 const entity
= new Entity();
382 entity
.addComponent(new PositionComponent(config
.position
));
383 const position
= entity
.getComponent(PositionComponent
);
388 const frictionStatic
= 0;
389 const restitution
= 1;
391 const body
= Bodies
.rectangle(position
.x
/ Config
.meterSize
,
392 position
.y
/ Config
.meterSize
,
393 config
.width
/ Config
.meterSize
,
394 config
.height
/ Config
.meterSize
,
397 label: 'Invisible Block',
402 entity
.addComponent(new BodyComponent({ body
}));
405 engine
.addEntity(entity
);