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) |
