User Tag List

Page 1 of 2 1 2 LastLast
Results 1 to 10 of 13

Thread: best practices with managing sidescroller enemy movement?

  1. #1
    Clicker Fusion 2.5 (Steam)Fusion 2.5 Developer (Steam)Fusion 2.5+ DLC (Steam)Android Export Module (Steam)HTML5 Export Module (Steam)iOS Export Module (Steam)Universal Windows Platform Export Module (Steam)
    Volnaiskra's Avatar
    Join Date
    Jan 2014
    Location
    www.sprykegame.com
    Posts
    2,299
    Mentioned
    94 Post(s)
    Tagged
    0 Thread(s)

    best practices with managing sidescroller enemy movement?

    So far Spryke has only had a few rudimentary enemies. These are either simplistic placeholders with very barebones code behind them, or else they are more complex but each have bespoke spaghetti code that won't be very reusable for future enemies. So I'm finally starting to build a proper enemy system now. My thinking was that I should make one sort of 'proto-enemy' that will be used for all the main enemies in the game. This proto-enemy would contain all the code and detectors needed to run, chase, jump, walk on ceilings, walk on walls, change animation, and all the other things that an enemy might do. Then when I want to make different enemy types that have different abilities, I would create an instance of this proto-enemy, give it a unique skin object, and turn some of these parameters and modules on/off as desired.

    I started off thinking that my proto-enemy would have a bunch of detectors that help it navigate the environment. But once I started thinking through all the things it'd need to do, I realised that I'd need at least 14 detector objects for each instance of the enemy! For example, I want the enemies to be able to hop up a small step if they come to one. For this, it seems I'd need 3 different detectors - shown as red, purple and green in the pic (plus 3 more for the other side, so 6 in total)



    And I want the enemies to be able to jump over narrow steep gaps, drop down wide shallow gaps (like descending steps), and avoid wide deep gaps that would cause them to fall to their death. For this, 2 more detectors seem to be needed per side (so 4 in total):



    And then there are separate little slope detectors for sloped ground, plus a detector that triggers the enemy to start chasing you if you touch it, plus a detector for sticking to the ceiling, for colliding with the player, etc. Having this many detectors per enemy seems crazy, both in terms of code complexity and in terms of performance. Which got me thinking that there must be a better way. Then it occured to me that you could probably do away with many of them, but instead place little invisible markers in the level that guide any enemy that collides with it. For example, one marker would signal that the enemy should jump X number of pixels, another marker would signal that a cliff has been reached and the enemy should turn around, and so on.

    It also made me realise that there's probably a great deal that I haven't thought through properly, and that I should probably seek the advice of those who have more experience with this sort of thing.

    So, how do you guys manage your enemy movement? Do you use detectors, or hidden markers? or perhaps do your enemies 'map out' their surroundings when they spawn once and store them somehow? How do you manage critters that can walk not just on the floor but on walls and/or ceiling? Do you use bouncing ball movement for enemies, or a custom fast-loop solution, or a combination of both, or something else? Do you use a single 'proto-enemy' object? Any other advice you'd give someone who's about to embark on making a system for enemies that have various abilities?

    Thanks!

  2. #2
    Clicker Fusion 2.5 Mac
    Fusion 2.5 (Steam)Fusion 2.5 Developer (Steam)Fusion 2.5+ DLC (Steam)Android Export Module (Steam)HTML5 Export Module (Steam)iOS Export Module (Steam)Universal Windows Platform Export Module (Steam)

    Join Date
    Jan 2015
    Location
    Australia
    Posts
    188
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    I tend to use the built-in physics engine for platformer enemies, since it handles gravity automatically for objects. There's a bit of tweaking needed for enemies like collision shape, friction, density, fixed angle etc. but once it's set up its easy enough. I usually then store other enemy behaviours as strings on the individual enemy, so that they can be scoped down from the qualifier if needed (2.5 has made this a *lot* easier for me). Using a circle collision box means enemies can automatically walk up stairs (provided the stairs are short enough) without any dramas

    (click for big)


    I calculate the distance the enemy is to the player - if they're "within range" (just offscreen) then it calculates a few other things (current xspeed/yspeed, x/y distances from player, a 1/0 value if the player is looking at the enemy or not)

    For an enemy that walks left/right, I use something like this:


    The "state" is just a text field that stores a current action the enemy is currently doing, and changes if it hits a wall or after a certain amount of time. If the enemy's xSpeed and ySpeed are both 0 (and it has a "walk" state and not an "idle" state) then I just run a quick check to see if the collision mask immediately to the left/right and switch it to the next state.

    I don't have any enemies that walk on ceilings just yet, but I do intend of having enemies that act like "bats" and stick to ceilings/swoop down. I think the way I'll handle that is just by adding in a seperate physics engine with gravity the opposite direction, and switching between multiple movements

    As far as enemies jumping at predetermined points in your level like pits/gaps... I think whether you have this built into the level or the enemy itself depends on the kind of game you're making. It's probably easier effort-wise (but more time) to manually plot out parts of the level enemies interact/jump/etc over, and this is probably more suited for a game with handmade levels or static pieces. If you're doing procgen levels or levels can change dynamically by having the player/enemies affect terrain, then having these behaviours built into the enemies themselves would probably be better.

  3. #3
    Clicker Fusion 2.5 (Steam)Fusion 2.5+ DLC (Steam)

    Join Date
    Aug 2010
    Location
    Sweden
    Posts
    99
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    I use pretty much what you described in your first post. Although, I use internal detectors as I feel that there would be just too many objects otherwise. The main problems with internal detectors are the animations, but it's completely doable. Although, I wish there was an built-in detector system so we wouldn't have to create or own systems.

    I stopped using invisible markers early as that didn't work for me in an environment that changes. Just as in your example picture with the first jump detectors, I use three internal detectors for detecting different heights for jumps. If an enemy runs into something that is 3 blocks high then the enemy would just change direction. If it ran into something 2 blocks high it would perform a high jump and if it ran into a single block it would make a small jump. So, if the blocks the enemy run into can be destroyed I want the enemy to recognize that and if 3 blocks became 2 blocks the enemy can now perform a high jump. If I would have used invisible markers I wouldn't have been able to also have an changeable/destructible environment (I think).

    My enemies that I make now are also more like a proto-enemy. For example, all my SMB enemies and powerups are just one enemy with Alt Values that I can change if I want it to behave different. I have several Alterable Value Behaviors for my enemies, one is "Behavior Edges" that I can set to 0, 1 or 2 or something else. 0 is that nothing happens at edges, the enemy will just walk and fall. Value 1 is that the enemy will change its direction and value 2 is that the enemy will make a jump.

    I also have an Alt Val called "Object Type" which is used to force the enemy direction to the Object Type value (to force a specific enemy animation).
    2019-12-01 13_06_07-E SMB Walkers.jpg


    This is how I manage my detectors. Frame 15 is just all the detectors combined and is not triggering anything. Otherwise the frames are looped through and each frame is a different detector.
    For example:
    D1 = Right D 1
    D2 = Right D 2
    D3 = Right D 3
    D7 = Left D 1
    D8 = Left D 2
    D9 = Left D 3
    D5 = Ground D 1 (Small)
    D11 = Ground D 2 (Large)
    D4 = Right Down Jump/Change Direction
    D6 = Left Down Jump/Change Direction
    D10 = Top 1 (Stop movement)
    D12 = Top 2 (Jump available)
    D13 = Other Enemy D Left
    D14 = Other Enemy D Right
    2019-12-01 13_06_53-E SMB Walkers.jpg


    So, all of these spawners (yellow thingies) creates the same enemy, just with different Alt Values.
    2019-12-01 13_09_42-Clickteam Fusion 2.5+ - [SMBF BETA - 0.9.9X - ENGINE SCREEN_].png


    As you can see here, the Alt Values dictates what kind of enemy/object is produced.
    2019-12-01 13_15_04-Greenshot.jpg

  4. #4
    Clicker Fusion 2.5 (Steam)Fusion 2.5 Developer (Steam)Fusion 2.5+ DLC (Steam)Android Export Module (Steam)HTML5 Export Module (Steam)iOS Export Module (Steam)Universal Windows Platform Export Module (Steam)
    Volnaiskra's Avatar
    Join Date
    Jan 2014
    Location
    www.sprykegame.com
    Posts
    2,299
    Mentioned
    94 Post(s)
    Tagged
    0 Thread(s)
    Fantastic responses. Thanks very much for sharing - I'm learning a lot from reading them.
    @vSv : what is the Frame 15 for? Do you first test to see if it overlaps anything at all, and if not, you don't bother testing the other 14 frames?

  5. #5
    Clicker Fusion 2.5 (Steam)Fusion 2.5+ DLC (Steam)

    Join Date
    Aug 2010
    Location
    Sweden
    Posts
    99
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Frame 15 is just reserved for myself, for getting a full picture of how the detectors look. I could probably delete it, but at the same time I think it's nice to have if I want to add any more detector or change a current detector in the future.

    Only the first 14 frames are tested for collisions each frame and it's only when E SMB Walkers animation Hitbox is playing + Current frame of E SMB Walkers Frame is equal to [anything between 1 and 14] that something happens.


    Sometimes I do things differently, usually if there's just two or three internal detectors. Then I will just make new animations for each detector, like this:

    Internal Detector Animations:
    2019-12-02 10_29_45-E Batman Mobile Tracker.jpg

    2019-12-02 10_29_49-E Batman Mobile Tracker.jpg

    Code:
    2019-12-02 10_28_15-Clickteam Fusion 2.5+ - [SMBF BETA - 0.9.9X - ENGINE SCREEN].jpg

    2019-12-02 10_28_28-Clickteam Fusion 2.5+ - [SMBF BETA - 0.9.9X - ENGINE SCREEN].jpg

  6. #6
    Clicker Fusion 2.5 (Steam)Fusion 2.5+ DLC (Steam)

    Join Date
    Nov 2017
    Posts
    97
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    vSv, for animations, are you just having the enemy revert back to the animation and frame within the same loop after the "detector" animation frame has played? I imagine this way, you can still use the usual "Play X Animation," instead of having to manually play animations and frames in events.

    I say this, because originally I had a system where the enemy would, within a loop, switch to a detector frame to test for overlap but I got too fed up with dealing with animations, so I switched to a parent-guide/child-mask system... and I've just realised I could probably have made it resume the current animation and restore frame all in the same loop! I also like how you've handled detecting ledges etc.

  7. #7
    Clicker Fusion 2.5 (Steam)Fusion 2.5+ DLC (Steam)

    Join Date
    Aug 2010
    Location
    Sweden
    Posts
    99
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    For all animations, I use alterable values as well. For example, if the Walking animation has three frames I set that Alt Val to 3. If the Jump animation have two frames I set that Alt Val to 2, and so on.

    I also have set the initial speed of all animations to 0 so they don't move by themselves. And in the code I just do something like this for a specific animation, in this instance, the "Hurt"-animation:
    2019-12-02 13_48_30-Clickteam Fusion 2.5+ - [SMBF BETA - 0.9.9X - ENGINE SCREEN].jpg


    I'll attach the Batman enemy as an example!
    Attached files Attached files

  8. #8
    Clicker Fusion 2.5 (Steam)Fusion 2.5+ DLC (Steam)

    Join Date
    Nov 2017
    Posts
    97
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Great example... quite similar to what I was trying to do. In an ideal world, you'd still want to be able to play animations as per normal (i.e When X then play animation Blah) and not worry about the internal detectors interfering - I'm thinking just inserting an action within the loop to put the animation back to what it was and restore the frame. Perhaps always store the current animation being played (by index? Can you do this?) and it's frame and have it revert back to both within the loop and none of this would be visible to the player.

    Then, this method would be perfect. Like I said, I got fed up with having to manually advance animations in events. For some reason, I didn't think of trying what I'm suggesting above. I'm not able to mess with it right now - have you played around with this?

  9. #9
    Clicker Fusion 2.5 (Steam)Fusion 2.5 Developer (Steam)Fusion 2.5+ DLC (Steam)Android Export Module (Steam)HTML5 Export Module (Steam)iOS Export Module (Steam)Universal Windows Platform Export Module (Steam)
    Volnaiskra's Avatar
    Join Date
    Jan 2014
    Location
    www.sprykegame.com
    Posts
    2,299
    Mentioned
    94 Post(s)
    Tagged
    0 Thread(s)
    I think I'll use a system similar to yours, vSv, with internal detectors. Though with a separate object for animation, as that will probably slot in best with my existing systems.

    I think that the #4639 event is unecessary. If you delete it, and move the "change the animation sequence to Hurt" action to the parent event, I believe it will work the same way. If Hurt is already playing, I think Fusion will just ignore that action, rather than forcing it to the first frame. This might save you a tiny bit of performance.


    Quote Originally Posted by Progject View Post
    .....Perhaps always store the current animation being played (by index? Can you do this?) and it's frame and have it revert back to both within the loop and none of this would be visible to the player...
    I think it would be. Fusion lets you read and set an object's animation sequence and frame via expressions. A potential (though perhaps insignificant?) drawback would be that interrupting an animation - even if you restore it in the same event - might introduce tiny fluctuations to an animation's pacing.

    Unless the speed you've set your animation to happens to coincide exactly with the rate at which Fusion loops the events, you're not going to get a new frame of an animation at every single loop. For example, I've built a little widget for myself that lets me see lots of animation data about an object (using the Animation Info object). You can see in this screenshot that the object I'm looking at is at 'frame 58.21'. The 21 is the little timer that Fusion's animation system uses to determine when to play frames. Once the timer hits 100, it will be time to play the next frame of the animation, which will be frame 59.

    But if I interrupt this animation, quickly change to a detectors animation, then quickly change back, presumably the animation will now be at 58.00 rather than 58.21. This could cause little stutters, or for the animation to play slower than desired. Or maybe it wouldn't make any discernible difference. I don't know and haven't tested it - but thought I'd mention it...


  10. #10
    Clicker

    Fusion 2.5Android Export Module

    Join Date
    Jan 2007
    Posts
    260
    Mentioned
    5 Post(s)
    Tagged
    1 Thread(s)
    Vol, why do you need 14 sensors per instance of enemy?

    Is this because you need to change the sensor sizes/shapes etc. per enemy?

    If you're strictly worried about the number of objects then you can just have 14 sensors total that loop through all instances of your enemies. I use this on every project ever and it works fine and scales infinitely. It might require extra work if you do need to change the sizes/shapes as you will need to get clever with the animation editor, but there is no reason you should need more than 14 objects total.

Page 1 of 2 1 2 LastLast

Similar Threads

  1. 3D Effect on 2D Sidescroller?
    By Devis in forum Fusion 2.5
    Replies: 6
    Last Post: 27th February 2015, 03:01 PM
  2. KALABAN - A sidescroller survival horror [WIP]
    By SirRandom in forum WIP & Released Games & Apps
    Replies: 4
    Last Post: 22nd January 2015, 07:33 PM
  3. sidescroller help!!!
    By Mostafa in forum Multimedia Fusion 2 - Technical Support
    Replies: 2
    Last Post: 15th July 2013, 04:28 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •