"For Each" Help

0 favourites
  • 11 posts
From the Asset Store
Game with complete Source-Code (Construct 3 / .c3p) + HTML5 Exported.
  • I cannot figure out why these lines of codes only work ~90% of the time when multiple enemies are on the screen and affected by this.

    <img src="http://stevemazzaro.com/FrostNova.png" border="0" />

    Basically what is happening is when the enemy is hit by FrostNova, if it's not already frozen (Freeze = -9999), it spawns an iceblock on an enemy and "Freezes" it for 3 seconds. Once the 3 seconds is up, it destroys the iceblock and unfreezes the enemy.

    If there is only 1 enemy on the screen, it works perfect every time, but the second you introduce 1+, it seems to get more complicated. With 2, it will usually delete both of them, but randomly will leave 1 undeleted while the enemy acts unfrozen.

    Can anyone see anything wrong with this? Thanks.

  • Are you sure you need that 'For each'? Most events work for each instance automatically.

  • I actually don't need the for each, but regardless of whether or not it is there, it still seems to have this issue.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • You don't need the top For-Each block:

    The relevant trigger is 'On collision'. Getting rid of the For-Each will cut a lot of un-needed processing.

    Since you threw in the 'once ever .1 sec' condition, and thus 'Freeze' can only ever change at that frequency, I would rewrite it with that as the primary event trigger, which should reduce processing overhead, and furthermore, I would change the destroying of the ice block(s) as shown:

    Event: Sys: Every .1 sec

    • -> subEvent: Enemies: Freeze > 0: Sub 1 from Freeze
    • -> subEvent: Enemies: Freeze = 0: do stuff...

    --> subSubEvent: Pick all IceBlocks && IceBlock.PinnedUID = Enemies.UID: destroy IceBlock

  • Oh, and it is not quite clear what your problem precisely is...

    You said:

    With 2, it will usually delete both of them, but randomly will leave 1 undeleted while the enemy acts unfrozen.

    'delete both of them' refers to what exactly?

    'leave 1 undeleted' refers to what exactly?

    I assumed IceBlocks...

    And also, are you saying the enemy fails to freeze for 30 secs, randomly, in the cases of two or more enemies?

    In both cases, it is pointing to a failure to pick precisely what you want to affect.

    I think the code change I suggested above will fix the IceBlock issue, if I assumed correctly.

  • Hey Jaycephus,

    Your assumption is correct - it's not deleting all of the iceblocks. The enemy is always frozen as it should be, but occasionally when the 3 seconds is up, one of the iceblocks will NOT be deleted. I can't figure out a way to trigger the bug, either.

    Just curious (I'm not at home to test this yet), but if I change the code to "Pick all IceBlocks", won't it delete them all instead of each one individually once the freeze timer is up? (ie. if an enemy is hit by frostnova, and a further enemy is hit by frost nova 1 second later, they should each have their own timer for when iceblock is deleted so they are NOT deleted at the same time).

    Let me know if I'm not making any sense.


  • Your last event needs a 'For each enemies' before 'For each IceBlock' otherwise you're only picking the IceBlock that's pinned to the first enemy with Freeze = 0.

  • So I wrote:

    --> subSubEvent: Pick all IceBlocks && IceBlock.PinnedUID = Enemies.UID: destroy IceBlock

    This was my short-hand for two conditions:

    ---> subSubEvent: Cond1: Pick all IceBlocks

    ----------------> Cond2: IceBlock.Pin.PinnedUID = Enemies.UID

    --------------------------> Action: Destroy IceBlock

    So just to be precise, there are multiple conditions:

    1st the .1 second timer triggers.

    2nd, a specific enemy is being processed at a given instant, and only from the subset of enemies that have their Freeze variable equal to 0, be that 0, 1, or 13 different enemies at once...

    Then the Pick All IceBlocks has a second condition that you also use above in your code, which discards any IceBlocks that are not pinned to the specific enemy being processed at that moment, meaning it only does this action on one IceBlock, or none if for some reason no IceBlock is pinned to the specific enemy being processed. Of course, if somehow two enemies are selected because they each are at Freeze = 0 state, then they will still be processed in turn, and only one IceBlock will be destroyed in turn for each enemy.

  • Jaycephus 'IceBlock.Pin.PinnedUID = Enemies.UID' is a 'System: Compare two values' event. It doesn't do any picking so you need the 'For each IceBlock' before it.

  • Yes, you are right. I was thinking of the 'Compare Instance Variable' condition of a Sprite, but then he would have to store the Enemies UID in an instance variable of IceBlock to facilitate that. I just shy away from doing For-Eaches on every tick if it can easily be avoided.

  • Adding "For Each Enemies" above "For Each IceBlock" seems to have fixed the issue.

    Thank you guys!

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)