Timers to regulate enemy AI

Hi all, I've got a question regarding timers. Please keep in mind that I'm super-new to this, so this stuff may be obvious, or I may have misunderstood the basics :)

I am building a side scrolling shoot em game (basically, I'm just playing around with expanding on the tutorial from the cookbook). I want an enemy to move up or down every 2 seconds, and fire two times every time he does.

I created a self attribute for the enemy called EnemyY, and made a rule that says:

Every 2 seconds...
a) if self.position.y is <= 174, set self.EnemyY to self.position.y and interpolate self.position.y to self.EnemyY+100 for 1 second
b) if self.position.y is >= 175, set self.EnemyY to self.position.y and interpolate self.position.y to self.EnemyY-100 for 1 second

That seems to be working okay. The firing part doesn't work. Here's my rule...

Every 0 seconds...
a) if self.position.y != self.EnemyY
i) Every 1 second, spawn actor Enemy Bullet

I've got the enemy bullet set up right - it's been tested without the timer rules and it work. But inside this rule, it doesn't.

Can you guys see what is broken here? Also, if there's a more efficient way to do what I'm trying to do, please let me know. I'm not familiar with all the concepts in GameSalad yet, but I'm learning as I go :)

Thanks!

Comments

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    Your interpolate rule looks good. Your timer within a timer rule looks messy. Why not just spawn an Enemy Bullet when you interpolate each time (e.g. If self.position.y <= 174 then spawn Enemy Bullet; If self.position.y >= 175 then spawn Enemy Bullet)?

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • wirelesstkdwirelesstkd Member Posts: 75
    Putting the spawn action in the rule about interpolating makes more sense, thanks!

    I'm not sure how I can get it to fire off twice during the interpolation, though, without using a timer.

    Am I correct that a timer is the only way to constantly check a game attribute?
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    I'm not sure how I can get it to fire off twice during the interpolation, though, without using a timer.
    The way I suggested would cause it to fire a bullet at the extremes of the actor's positions. I though that's what you were trying to achieve. If not, maybe you can explain when you want the two bullets to spawn.
    Am I correct that a timer is the only way to constantly check a game attribute?
    Yes, but... rules are triggered when attributes change values so if you can change an attribute to trigger the bullets, that would alleviate the need for a timer. Timers are generally pretty bad for performance but they can be used if no other solution exists.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • wirelesstkdwirelesstkd Member Posts: 75

    The way I suggested would cause it to fire a bullet at the extremes of the actor's positions. I though that's what you were trying to achieve. If not, maybe you can explain when you want the two bullets to spawn.
    Well, I'm going to spawn multiple enemies at random Y positions... I think your method will only work is they always start and end at a known position. Maybe there's a way to incorporate that in, though...
    Yes, but... rules are triggered when attributes change values so if you can change an attribute to trigger the bullets, that would alleviate the need for a timer. Timers are generally pretty bad for performance but they can be used if no other solution exists.
    So when a game attribute changes, does the game communicate this with all actors that have a rule relating to that value? Or do the actors have to query the value to know it changed?
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    @wirelesstkd You can keep track of initial Y positions (Change Attribute self.OriginalY to self.position.Y) but if you post a sketch/screenshot/video maybe we can get a better idea of what you're doing and offer a better way.

    Rules with attribute conditions (e.g. When [attribute] game.whatever = 25) trigger whenever the condition changes its boolean value. You can think of each rule as having a boolean value, true or false. So if game.whatever is 25, the rule will trigger once because the condition is true. If game.whatever then changes to 28 (false) and then back to 25 (true), it will trigger a second time. No need for a timer.

    What some people have trouble with is the idea that the condition value has to change. If your rule is When game.whatever > 24, it will trigger when game.whatever changes from a number less than 24 (false) to 25 (true). But when game.whatever changes from 25 (true) to 28 (true), it will NOT trigger the rule because the condition value (the state of the rule if you will) has not changed.

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • wirelesstkdwirelesstkd Member Posts: 75
    @tatiang, that makes a lot of sense... I think I've got it now :) I'll post back if I run in to a road block.
  • chicopchicop Member Posts: 263
    this is cool info guys, thanks.

    i decided to try it out this bit:

    a) if self.position.y is <= 174, set self.EnemyY to self.position.y and interpolate self.position.y to self.EnemyY+100 for 1 second
    b) if self.position.y is >= 175, set self.EnemyY to self.position.y and interpolate self.position.y to self.EnemyY-100 for 1 second

    however the actor sometimes changes direction smoothly but more often jumps into y translation randomly causing a big pop in the movement so basically in it can pop from bottom screen to top.

    i created a real on the actor called translateY

    then a rule when attribute self.position.y < 174
    change att self.translateY to self.position.y
    interpolate att self.posiition.y to self.translateY+100
    duration 1

    then a rule when attribute self.position.y > 174
    change att self.translateY to self.position.y
    interpolate att self.posiition.y to self.translateY-100
    duration 1

    any tips would be greatly appreciated

    thanks!
  • The_Gamesalad_GuruThe_Gamesalad_Guru Member Posts: 9,922
    In these cases I'd rather use a move to behavior as it's more fluid but they can be tricky to use in this way. Interpolate is a brute force move and renders things like collisions useless. I prefer move to as it keeps collisions in place and is smoother. By keeping collisions in place you enemy will move around obstacles.
  • StormyStudioStormyStudio United KingdomMember Posts: 3,989
    @FryingBaconStudios

    Definately a place for either at times. I did work out some cool work arounds to make interpolate be affected by collisions and stop on its paths at any given point.
  • chicopchicop Member Posts: 263
    seems there are quite a few ways to do this, i switched to T-shirt booth's version of pacing a char which works great for a simple direct way, all though it does not do to well with a random but the day is still young :-)
Sign In or Register to comment.