How to avoid overlapping sprites in Construct 3 when moving to one point? Like in Vampire Survivors

2 favourites
From the Asset Store
Connect the dots in the correct order and draw happy animals!
  • Hi! I want to make a game like vampire survivor, now I am working on the enemies on the forum I found a very good example

    construct.net/en/forum/construct-3/how-do-i-8/move-enemies-vampire-survivors-171628

    But the problem is that this example uses physics behavior that very negatively affects the performance of the game, it is very hard for cell phones to process at least 200 such enemies.

    I tried instead of physics to use bullet behavior, it works well, and has a performance ten times better. But in this case, the enemies overlap each other. If the solution to this problem?

  • You can try to use custom movement behaviour to make them move towards player and solid behaviour to avoid overlapping, probably it will work properly

  • You can try to use custom movement behaviour to make them move towards player and solid behaviour to avoid overlapping, probably it will work properly

    Can you elaborate on that? I tried it and it seems solid doesn't work with custom movment. Custom movment has a push out action solid in that case works, but enemies are teleported instead of pushed.

  • Personally I like to use the physics behavior. It sounds crazy, but it works.

    -Make the enemy physics hitbox a circle

    -Set the enemy physics iterations to something like 2 or 3

    -Set world gravity to 0

    -To move them toward the player, use Set Velocity -> cos(angle(Enemy.X,Enemy.y,player.X,player.Y))*Self.speed for X and sin(angle(Self.X,Self.y,player.X,player.Y))*Self.speed for Y

    Hope this helps!

    EDIT: I am now just seeing you already tried Physics and it was laggy, sorry about that. Although you could try to reduce the physics iterations of enemies, this will make them update less and increase performance.

  • The non-behavior way is to compare the distance between each pair of objects and push them apart and update their velocities if they are too close. That doesn't scale well with such a large amount of objects, so we need to do some kind of spatial hash so we only need to check objects that are nearby. Unfortunately when doing it with events it's hard to get that much of an improvement so JavaScript is better.

    Here's one possible test of that. It handles one object type and treats them all as the same size. Disable the group to compare performance with the physics behavior.

    dropbox.com/scl/fi/ja4hfo7dv9sqq7phs1q25/spatialGridJS.c3p

    With 1400 objects:

    Custom push out: 60fps

    Physics: 10fps

    The example also does it's own physics, but you can just use the spatialGrid() function if you just want push out.

  • The non-behavior way is to compare the distance between each pair of objects and push them apart and update their velocities if they are two close. That doesn't scale well with such a large amount of objects, so we need to do some kind of spatial hash so we only need to check objects that are nearby. Unfortunately if doing it with events it's hard to get that much of an improvement so JavaScript is better.

    Here's one possible test of that. It handles one object type and treats them all as the same size. Disable the group to compare performance with the physics behavior.

    https://www.dropbox.com/scl/fi/ja4hfo7dv9sqq7phs1q25/spatialGridJS.c3p?rlkey=heo2ewlpffq6n6kwusnnefdk8&dl=1

    With 1400 objects:

    Custom push out: 60fps

    Physics: 10fps

    The example also does it's own physics, but you can just use the spatialGrid() function if you just want push out.

    🔥 This is legendary-level programming.

  • The non-behavior way is to compare the distance between each pair of objects and push them apart and update their velocities if they are two close. That doesn't scale well with such a large amount of objects, so we need to do some kind of spatial hash so we only need to check objects that are nearby. Unfortunately if doing it with events it's hard to get that much of an improvement so JavaScript is better.

    Here's one possible test of that. It handles one object type and treats them all as the same size. Disable the group to compare performance with the physics behavior.

    https://www.dropbox.com/scl/fi/ja4hfo7dv9sqq7phs1q25/spatialGridJS.c3p?rlkey=heo2ewlpffq6n6kwusnnefdk8&dl=1

    With 1400 objects:

    Custom push out: 60fps

    Physics: 10fps

    The example also does it's own physics, but you can just use the spatialGrid() function if you just want push out.

    That's really cool! Great job, but can we make the sprites chase another object? I tried it, but it looked weird to me. I'd love it if you could tell me more about your project!

  • You can set the velocity toward the position of the other object.

    So once you get the angle toward a position you can do:

    Vx=speed*cos(angle)

    Vy=speed*sin(angle)

    But there are other ways.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • R0J0 just casually dropping bangers

  • It's incredible!!R0J0 is just Superman!!!

  • R0J0hound I'm sorry to bother you again, I wanted to ask if there is any way to fix this? I'm using your formula to move

    gifyu.com/image/S4J9k

  • R0J0hound your method is interesting. When setting the objects to move toward a position I see about about a 30% performance gain with your method compared to standard construct physics. Your method however does not handle the tracking well and produces rapid movement and overlaps in the objects nearby the point they are moving towards. This could probably be improved by scaling velocity based on distance to the target but I wonder if you think there is a more functional way?

  • MyXpandaZ calminthenight

    The simulation is rather basic so I can lead to instability.

    I'm not sure how you're moving the sprites toward the target, but it's better to set the velocity than setting the position, and better than that is to gradually change the velocity. In general that allows everything to be more stable. Another thing you can do is limit the max speed the objects can move. Another solution is making the push out less rigid. As is it pushes each pair out of each other completely in one go, but changing it so it only moves apart 25% of the way or lower will smooth things out more. Look for the js line that sets dist. There should be a /2 at the end. Change that to /10 to make the pushout softer.

    I probably need to revisit this to clean it up.

    Here's were I tweaked the example from last week but it deviated a fair bit as I was messing around with various ideas.

    https://www.dropbox.com/scl/fi/adgm5izhyk7indhjbqlz4/spatialGridJS2.c3p?rlkey=oafjw813djgai8x9pddbaq6ke&dl=1
  • I stripped it back to a simple project with circles again and fiddled with it and I think the fundamental issue is that it relies on gently massaging speed and angle values. This is amazing as a physics/particle simulation but not so suitable as a collision avoidance system for enemies that have to move toward a target directly.

    Using a static value for speed and vectoring so the sprites move directly towards the target, rather than are steered towards them seems to not work with this model without causing overlaps, even at low values.

    I will keep tinkering though and see if I can get it to work.

    EDIT: I think that the grid pair system struggles to deal with resulting overlaps when things are being forced to move to a location. It's possible that adding in prediction by giving the spatialgrid access to each objects x and y velocities and rechecking for future overlaps would work but it would probably move the performance way back.

    https://1drv.ms/u/s!AkmrWgxeuxlKhKMx9yWgRSvmR0j70g?e=sU32mH

  • There's a bunch of ways you can tweak it. The motion is done with verlet integration currently which just infers the velocity after moving objects apart. We could change that to deal with the velocity change with each collision instead. That probably would fix the explosions where crowded objects end up moving rather far and get a lot unintended velocity because of it.

    Having bigger objects, slower speeds, and simulating in sub steps (kind of like the physics behavior iterations) are also few ways to make it more stable. Even the physics behavior itself has a threshold where it breaks under pressure.

    Utilizing the velocity to do a continuous collision detection is an idea, but it would be more complex and slower to do.

    Also there's no reason this can't handle different sized objects. It just needs some reworking.

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