Author Topic: Enemy Timers  (Read 3954 times)

0 Members and 1 Guest are viewing this topic.

Max

  • Sr. Member
  • ****
  • Posts: 277
    • View Profile
Enemy Timers
« on: March 14, 2018, 02:52:46 AM »
Hey, question. So timers associated with an enemy are destroyed when enemy:on_restarted() is called. However, enemy:on_restarted is called when the enemy is damaged, right? Therefore, it seems impossible to create a timer that sends an enemy through phases without you interrupting the phases whenever you hit the enemy.

For example, how would we have an enemy that becomes invulnerable after 10 seconds? You'd need to start that timer in enemy:on_restarted(), but that timer would be destroyed and restarted every time you damage the enemy.

Has anyone done anything like this in designing enemies?

Diarandor

  • Hero Member
  • *****
  • Posts: 1062
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: Enemy Timers
« Reply #1 on: March 14, 2018, 07:54:14 AM »
It is still doable but a bit tricky. You will need to use variables to store custom states and other info, so that the event "on_restarted" will make different things depending on the state.
“If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you.”

Max

  • Sr. Member
  • ****
  • Posts: 277
    • View Profile
Re: Enemy Timers
« Reply #2 on: March 15, 2018, 12:27:19 AM »
That makes sense. It seems like it has some limits to its ability though- for example, if the state you've saved is something like "charging", to charge up a big attack, you're potentially be able to keep the boss in its charging state forever if you kept attacking it and therefore restating the timer.

If there's no way to code around that, it's just good to know so I can design around it. For example, it seems like it might be best practice to cause enemies to attack right at the beginning of on_restarted() (if the hero is within range), rather than after a delay, and if you want the delay, have it be called after the attack instead of before.

Diarandor

  • Hero Member
  • *****
  • Posts: 1062
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: Enemy Timers
« Reply #3 on: March 15, 2018, 05:12:06 AM »
You can make the enemy invincible for a chosen delay when on_restarted is called. That will avoid the infinite loop, and the enemy will be able to attack.
“If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you.”

llamazing

  • Full Member
  • ***
  • Posts: 221
    • View Profile
Re: Enemy Timers
« Reply #4 on: March 15, 2018, 05:46:16 AM »
There's another way to get around it. When you start a timer that you don't want aborted, save the timestamp when the timer started:
Code: (lua) [Select]
local start_time = sol.main.get_elapsed_time()
Then in your on_restarted() function, since you know the timer was destroyed, start a new timer with however much time was remaining on the original timer:
Code: (lua) [Select]
local remaining_time = start time + TIMER_DURATION - sol.main.get_elapsed_time()
if remaining_time > 0 then
sol.timer.start(self, remaining_time, some_function)
end --otherwise timer expired before enemy was hit so do nothing
Where TIMER_DURATION is a constant equal to however long the timer is.

Christopho

  • Administrator
  • Hero Member
  • *****
  • Posts: 1195
    • View Profile
Re: Enemy Timers
« Reply #5 on: March 15, 2018, 10:14:57 AM »
Another way is to attach the timer to another object than the enemy (like the map).

Diarandor

  • Hero Member
  • *****
  • Posts: 1062
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: Enemy Timers
« Reply #6 on: March 15, 2018, 12:02:12 PM »
Be careful because apart from timers there are other things reseted (like the animation and current frame of the sprites). I suggest to create a function to re-initialize the state when an enemy is restarted. Making the enemy invincible for a while (0.5s or 1s) would be enough to allow a counterattack from the enemy, forcing the hero to move away temporarily before attacking again.
“If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you.”

Max

  • Sr. Member
  • ****
  • Posts: 277
    • View Profile
Re: Enemy Timers
« Reply #7 on: March 17, 2018, 04:52:19 AM »
Another way is to attach the timer to another object than the enemy (like the map).

I thought of this too- it will work great for bosses (you know what map they'll be on). I plan to trying this method out a couple times in my game, I was just curious if there was a more obvious way that I was missing.

Thanks for the feedback, guys!