diff options
author | Federico Igne <git@federicoigne.com> | 2022-11-04 22:37:00 +0000 |
---|---|---|
committer | Federico Igne <git@federicoigne.com> | 2022-11-04 23:01:14 +0000 |
commit | 39e97166b83531f3b1da69514653c7dd9e8810ff (patch) | |
tree | 8dd639000a7debf01f48f20c768112ca0946158d | |
parent | c3e8f1aa591acf96bbda8ea6aa66f66433ff3866 (diff) | |
download | raccoon-39e97166b83531f3b1da69514653c7dd9e8810ff.tar.gz raccoon-39e97166b83531f3b1da69514653c7dd9e8810ff.zip |
feat: add force field component/system
This will apply continuous or instantaneus force to any object within a
certain range.
-rw-r--r-- | raccoon.lua | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/raccoon.lua b/raccoon.lua index ed0eaa2..8db51ca 100644 --- a/raccoon.lua +++ b/raccoon.lua | |||
@@ -20,12 +20,27 @@ local util = { | |||
20 | } | 20 | } |
21 | } | 21 | } |
22 | 22 | ||
23 | function util.signum(n) | ||
24 | if n < 0 then | ||
25 | return -1 | ||
26 | elseif n > 0 then | ||
27 | return 1 | ||
28 | else | ||
29 | return 0 | ||
30 | end | ||
31 | end | ||
32 | |||
23 | function util.size(t) | 33 | function util.size(t) |
24 | local count = 0 | 34 | local count = 0 |
25 | for _,_ in pairs(t) do count = count + 1 end | 35 | for _,_ in pairs(t) do count = count + 1 end |
26 | return count | 36 | return count |
27 | end | 37 | end |
28 | 38 | ||
39 | function util.distance(p1,p2) | ||
40 | local vec = { p2.x - p1.x, p2.y - p1.y } | ||
41 | return math.sqrt(math.pow(vec[1], 2) + math.pow(vec[2], 2)), vec | ||
42 | end | ||
43 | |||
29 | --- Class factory. | 44 | --- Class factory. |
30 | -- Creates a new class. A function | 45 | -- Creates a new class. A function |
31 | -- ``` | 46 | -- ``` |
@@ -316,12 +331,46 @@ function Particles:spawn(pos, entities) | |||
316 | end | 331 | end |
317 | end | 332 | end |
318 | 333 | ||
334 | local ForceField = Component() | ||
335 | function ForceField:init(force,range,instant) | ||
336 | self.force = force or 1 | ||
337 | self.range = range or 1 | ||
338 | self.instant = instant | ||
339 | return self | ||
340 | end | ||
319 | 341 | ||
320 | local Metadata = Component() | 342 | local Metadata = Component() |
321 | function Metadata:init(name) | 343 | function Metadata:init(name) |
322 | self.name = name or "Unnamed" | 344 | self.name = name or "Unnamed" |
323 | return self | 345 | return self |
324 | end | 346 | end |
347 | |||
348 | local ForceFieldSystem = System(Pos,ForceField) | ||
349 | function ForceFieldSystem:exec(entity,enemies) | ||
350 | local pos = entity.get_component[Pos] | ||
351 | local ff = entity.get_component[ForceField] | ||
352 | for _,e in pairs(enemies) do | ||
353 | if e.has_component[Pos] and e.has_component[Movement] then | ||
354 | local pos1 = e.get_component[Pos] | ||
355 | local mov = e.get_component[Movement] | ||
356 | local dist,vec = util.distance(pos,pos1) | ||
357 | if dist < ff.range then | ||
358 | if e.has_component[Metadata] then | ||
359 | local meta = e.get_component[Metadata] | ||
360 | trace("Hit " .. meta.name .. " at position " .. pos1.x .. " " .. pos1.y) | ||
361 | else | ||
362 | trace("Hit entity at position " .. pos1.x .. " " .. pos1.y) | ||
363 | end | ||
364 | mov.cur.x = mov.cur.x + util.signum(vec[1]) * ff.force | ||
365 | mov.cur.y = mov.cur.y - ff.force | ||
366 | end | ||
367 | end | ||
368 | end | ||
369 | if ff.instant then | ||
370 | return true, {ff} | ||
371 | end | ||
372 | end | ||
373 | |||
325 | local InputSystem = System(Input) | 374 | local InputSystem = System(Input) |
326 | function InputSystem:exec(entity) | 375 | function InputSystem:exec(entity) |
327 | local input = entity.get_component[Input] | 376 | local input = entity.get_component[Input] |
@@ -547,7 +596,7 @@ local player = Entity() | |||
547 | local pos = entity.get_component[Pos]--:to_screen(lpos) | 596 | local pos = entity.get_component[Pos]--:to_screen(lpos) |
548 | table.insert( | 597 | table.insert( |
549 | game.entities, | 598 | game.entities, |
550 | Entity():with_component(Pos(pos.x,pos.y)):with_component(CircleEffect(20))) | 599 | Entity():with_component(Pos(pos.x,pos.y)):with_component(ForceField(5,10,true)):with_component(CircleEffect(20))) |
551 | end, | 600 | end, |
552 | nil)) | 601 | nil)) |
553 | 602 | ||
@@ -585,6 +634,7 @@ function TIC() | |||
585 | MovementSystem:run(game.entities) | 634 | MovementSystem:run(game.entities) |
586 | ActionSystem:run(game.entities, game) | 635 | ActionSystem:run(game.entities, game) |
587 | EffectSystem:run(game.entities) | 636 | EffectSystem:run(game.entities) |
637 | ForceFieldSystem:run(game.entities, game.entities) | ||
588 | PosAnimSystem:run(game.entities) | 638 | PosAnimSystem:run(game.entities) |
589 | ParticlesSystem:run(game.entities, game) | 639 | ParticlesSystem:run(game.entities, game) |
590 | LevelSystem:run(game.levels, game) | 640 | LevelSystem:run(game.levels, game) |