2D scroller enemy that chases player across multiple layouts

0 favourites
  • 12 posts
From the Asset Store
Players follower. use it for anything which follows the player
  • I have a global enemy that is set to chase the player upon being activated.

    I am struggling with adding some sort of latency to the enemy's re-appearance when player runs through multiple layouts.

    How should I efficiently go about this to make it seem like you are slowly losing the enemy behind? Make the AI smarter as to say.

    The player is able to use teleportation points in the layouts to teleport to somewhere even further, they could even run in "circles" so bumping into the enemy again at a realistic position/layout should be possible. like so;

    Map A > Map B > Map C > Back to Map A

    Due to the teleportation, the player doesn't always necessarily appear at the far ends of the layouts either.

    Could anyone share some examples that could possibly work with this idea of mine?

  • you could store the distance the enemy has to the player when changing the layout and delay the spawn of the enemy something like this:

    on start of layout, wait for: storedDistance/enemy.speed seconds

    spawn enemy

    Tbh I am not exactly sure if this works depending on the type of game you are going for.

  • I have a variable that is storing the distance between player and enemy and use it to set a wait x seconds before appearing.

    And it worked okay in my project for a while, but I'm looking to upgrade it,

    because the problem with this is that since I used pixels between the enemy and the player to calculate latency, and the enemy is a global object, this calculation will get messed up the longer the chase is and the more player changes through multiple layouts.. It's difficult to explain like this, I'll try recording a video to demonstrate asap.

  • on layout change set float chaseDistance to distance(player.x,player.y,enemy.x.enemy.y)

    Every seconds if bool enemyNotSpawned = true subtract enemySpeed from chaseDistance

    if chaseDistance < 0 spawn Enemy

    This should work even with layout changes before the enemy spawned again.

    Or do you want to achive something like this:

    layoutA>layoutB>LayoutA Enemy is still in layoutA running to layoutB?

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • The latter is more to what I want to achieve,

    Forgot to mention this game is a puzzle adventure,

    hide and avoid enemy type of a game.

    My idea is that there would also be places to hide to avoid the enemy, and during the chase, the more layouts you are "further" from the enemy, the faster it will "forget" about you so you can lose it. Hence I need it to somehow remember the distance in "layouts".

    Once it's forgotten about you it will be invisible and it's AI and collision deactivated.

    It will appear again next time the system rolls a chance for it to appear.

    In case of you running in circles, yes you should be able to bump into it, seeing it still trying to run into the same direction. (From then on it could turn around if you get too close, but that's not the current problem.)

  • Here's a video demonstrating how the enemy is currently chasing me.

    drive.google.com/file/d/1UVwtwqOMdKeW40isB1eANupZmh6FAOUL/view

    And here is another problem; me going to another layout and coming back to that same layout in a second and the darn bunny's gone and already behind me.

    drive.google.com/file/d/1etGaqh_0hp2u4aFeTYwQsMNO-Qs8SB51/view

  • on layout change set float chaseDistance to distance(player.x,player.y,enemy.x.enemy.y)

    Every seconds if bool enemyNotSpawned = true subtract enemySpeed from chaseDistance

    if chaseDistance < 0 spawn Enemy

    This should work even with layout changes before the enemy spawned again.

    Or do you want to achive something like this:

    layoutA>layoutB>LayoutA Enemy is still in layoutA running to layoutB?

    I studied this example and was able to make the enemy's appearance latency more realistic.

    However, the problem of the enemy not staying in the same "room" when I exit and come back is still a headache. I guess I will look into arrays to see if I can find a solution for that. Thanks fedca for helping me out.

    If anyone has suggestions for my latter problem, it'd be greatly appreciated.

  • np!

    You could solve the problem by actually having one large layout and just give the feeling of rooms with camera bounds you change on entering each room. Bacause in that case the enemy would never have to be teleported.

    Is there a specific reason you use different Layouts?

  • Yes, actually, my graphics are quite heavy and as it's a story driven game, the world is also quite big and there are some areas dense in dialogues and other interactable sprites so I wanted to chop the maps to avoid long loading time. I have very few "rest" areas in my game so the enemy could essentially appear anywhere any time, with the varying chances depending on the area. I could group a couple maps in one layout, but in the end, I do need to tackle this layout change problem still. Currently I'm experimenting with the array to create a short term memory for the enemy during the chase.

  • > on layout change set float chaseDistance to distance(player.x,player.y,enemy.x.enemy.y)

    >

    > Every seconds if bool enemyNotSpawned = true subtract enemySpeed from chaseDistance

    >

    > if chaseDistance < 0 spawn Enemy

    >

    >

    > This should work even with layout changes before the enemy spawned again.

    >

    > Or do you want to achive something like this:

    > layoutA>layoutB>LayoutA Enemy is still in layoutA running to layoutB?

    I studied this example and was able to make the enemy's appearance latency more realistic.

    However, the problem of the enemy not staying in the same "room" when I exit and come back is still a headache. I guess I will look into arrays to see if I can find a solution for that. Thanks fedca for helping me out.

    If anyone has suggestions for my latter problem, it'd be greatly appreciated.

    Yes, you could use an array, especially if you use multiple enemy.

    I can see it something like this:

    Add a number to the layouts (ex: level_0_0, level_0_1, level_0_2...etc)

    Calculate the width layout and store it in an array ( 3000,2500,3000...etc)

    On the monster, I think there is a behavior where you can keep the variable as you change the layout. Add that behavior, and make a variable which store in which layout the monster is, same with the distance X player, and a logic global distance.

    Now, the logic would be, if monster is on level 0_0 and you are on level 0_2, since you have the total width of the layout, and the last distance captured between the player and the monster, you can calculate the logic distance between the player and the enemy. If the player is in a greater number layout (you can compare it using actual layout name and monster layout using tokenat), you know if you need to add, or substract the distance. Then, knowing each width layout, you are able to understand where the enemy is. For example, while adding the number to the logic distance, if the enemy falls on 4000 distance, you know that is on level_0_1 and you can place the enemy as soon you get in that level in the exact place as soon the enemy was moving.

    This would allow you to make a logic which says: if logic global distance is grater than 12000 (let's say, you pass 5 layouts), then stop the enemy. Knowing where the enemy is, and the global distance you can easily spawn the enemy when you get back to that layout. You can also store all of this in the array, where each enemy gets it's own row, or simply store it on the sprite instance. Array is helpful to save the progress and then load it easily.

  • I was able to figure some of it out before I saw what Ribis posted, but it's confirming that I am going in the right direction so I am thankful still!

    I'm using arrays and instance variables on my enemy.

    As I only need one global enemy, its instance variables are kept even when I change layouts. I am not familiar with arrays enough to know how to use a 2 dimensional array correctly so I used 2 one-dimensional arrays instead to keep track of my enemy's location and distance.

    So basically, I set two instance var on my enemy, "location" and "distance"

    Then I have "ArrayLocation" and "ArrayDistance"

    I log the LayoutName and distance(player.x,0,enemy.x,0) into these two arrays and then use these values to control the enemy's location and distance variables.

    I made enemy.distance and enemy.location shuffle through their arreys in order from oldest to newest logged values (enemy.distance-enemy.speed every second).

    Then as each time distance <0, enemy.location will change to the next one in line according to the ArrayLocation, and that in turn will give enemy new distance value to subtract its speed from.

    Then I added in some tweaks here and there to stop the "shuffling" from happening when the enemy has reached the player or vice versa.

    Currently it's working okay. I checked in debug mode to see you can bump into the enemy again if you run in circles or if you go back and well.. it is there, on that layout where it's supposed to be, actually, but it seems to have some minor bug, I think I can handle that though.

    I will ask for help again and post screenshots of my eventsheet if I can't figure it out but for now it mostly seems pretty ok!

  • I got it working!

    I ended up making 2 more arrays for logging the enemy's position in each layout before layout change and made an event that would set the enemy's position accordingly if the player runs back to the layout or does a full circle.

    Again, would be more efficient with a two-dimensional array but I'll come back to tidy it up later when I have more experience.

    For now it seems pretty okay in all aspects that I need it to do so that'll do.

    Big thanks for both friends trying to help me.

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