How do I prevent multiple enemies overlaping in this turn based hex-based pathfinding ?

0 favourites
From the Asset Store
Units do not overlap each other and use different ways if there are several free ways.
  • I've customized an hex-based multiple enemy move pathfinding engine and turned it to turn based. Everything is fine except enemies overlap.

    Enemies are multiple instances of a sprite. Pathfinding is not on the enemy sprite but on a independent sprite the enemy sprite is attached to.

    Obstacles for Enemy pathfinding are : Terrain (here Water hexagons) and all other Enemies' hexagons

    when every Enemy's hexagons are Solid (including current Enemy), pathfinding can not be process because current Enemy's own hex is Solid. Pathfinding stops here. So in order to have Pathfinding to work, I have to disable current Enemy hexagon but keep all the others enemies hex Solid.

    Here is how the sequence is meant to work :

    - The Enemies don't move.

    - *each hexagon where an Enemy instance stands becomes Solid, creating an obstacle map on the game board.*

    - Pathfinding for Enemy instance 1 is calculated

    - Enemy instance 1 moves

    - Enemy instance stops

    - *Hexagon where Enemy instance stops becomes Solid*. Obstacle map changes.

    - Repeat to next Enemy instance until every Enemy has moved.

    Unfortunately, I'm not good enough programming to achieve this.

    Everything is fine except I couldn't find any way to have de steps marked ** to work. Anyone has an idea ?

    Capx is here :

    dropbox.com/s/9ivnc6y16m0sxzz/HexagonMovement_2Enemie_TurnBased.c3p

  • I've customized an hex-based multiple enemy move pathfinding engine and turned it to turn based. Everything is fine except enemies overlap.

    Enemies are multiple instances of a sprite. Pathfinding is not on the enemy sprite but on a independent sprite the enemy sprite is attached to.

    Obstacles for Enemy pathfinding are : Terrain (here Water hexagons) and all other Enemies' hexagons

    when every Enemy's hexagons are Solid (including current Enemy), pathfinding can not be process because current Enemy's own hex is Solid. Pathfinding stops here. So in order to have Pathfinding to work, I have to disable current Enemy hexagon but keep all the others enemies hex Solid.

    Here is how the sequence is meant to work :

    - The Enemies don't move.

    - *each hexagon where an Enemy instance stands becomes Solid, creating an obstacle map on the game board.*

    - Pathfinding for Enemy instance 1 is calculated

    - Enemy instance 1 moves

    - Enemy instance stops

    - *Hexagon where Enemy instance stops becomes Solid*. Obstacle map changes.

    - Repeat to next Enemy instance until every Enemy has moved.

    Unfortunately, I'm not good enough programming to achieve this.

    Everything is fine except I couldn't find any way to have de steps marked ** to work. Anyone has an idea ?

    Capx is here :

    https://www.dropbox.com/s/9ivnc6y16m0sxzz/HexagonMovement_2Enemie_TurnBased.c3p?dl=0

    Just a quick question, doing event "Is moving with path" > Set solid (enable,disbled)

  • Hi Sami424

    Could you be more specific ?

  • I have a slightly different solution that should work but it’s not completed yet.

    Basically it ranks the enemies by their cell distance from the player, then for each one:

    Mark all the other enemy cells as blocked

    Find a path to the player and move one cell.

    I’m opting to not use the pathfinding behavior to avoid the waits. I’m using an event based function that finds a path immediately.

    Anyways, I should be able to finish and post it tomorrow. The events will look very different to yours, but it should run the way you’re after.

  • That sounds promising !

    Would it still have the turn based style and have the possibility to include for each instance a max number of moves by turn ? Both are important for my game

  • I think there is something I miss with my code.

    Each enemy is made out of two sprites combined in a container :

    - the enemy sprite itself

    - an associated EnemyPath sprite that holds the pathfinding behaviour.

    They both have the same UID number.

    The EnemyPath move along found path, and when it overlaps a hexagon, the Enemy sprite is put on the hexagon position.

    What I think I miss is that in my routine, for each Enemy Sprite with a given UID, the EnemyPath sprite with the matching UID has to be used.

    And I guess that this is where the mess is.

    Anyone to have a look ?

  • Ran out of time but here is what I ended up with.

    It finds a path from all locations to one spot, and moves the enemies toward it. The enemies will try to move around other enemies if they are blocked.

    left click to add an enemy to an empty spot. They will try to move toward the mouse.

    dropbox.com/s/17oopqy8qfu20pp/hex_pathfind.capx

    Probably ended up more complex than i anticipated. I have an idea how to make things tighter but it's slower.

    As to your question with your capx, I have no idea. Maybe there is something simple that will allow it to do what you're after, or it's not really possible. I opted to go from scratch instead of figure out what is possible with the pathfinding behavior. From scratch give more control and is a bit quicker to figure out.

    Anyways, maybe my capx is helpful but it's not setup like you have your game.

    cheers

  • Hi R0J0hound

    That's a very interesting approach. It's far from my needs though.

    I took another look at my problem and I think I found out a direction to dig : I forgot that when obstacles move, pathfinding need to refresh the obstacle map. I made some tests and it looks encouraging.

  • Here it is further refined to match your example.

    dropbox.com/s/pcbiajcrf4wsr8p/hex_pathfind2.capx

    It uses a state variable to switch what is happening. Basically it does this:

    *click to find path for payer. All enemies are walls.

    *move player on path

    *loop over each enemy, make all others walls, pathfind to player and move one space.

    -- it does that every 0.25 sec for 0.75 sec.

  • Hi R0J0hound

    Incredible !

    Looks exactly how I was trying to achieve.

    Stuff I have to adapt :

    - Allow enemy to enter player hexagon so that they can fight

    - Allow Player to enter Enemy hexagon, for the same reason

    - Allow Player to move only X hexagons (maxmove)

    - Make enemies move only when Player has used all its maxmove or if End Turn button is clicked.

    I went through your code and came out with this

    https://www.dropbox.com/s/wkzy10rnl7gj6jo/MoveHexChangeFromRojo.c3p?dl=0

    I added :

    - Player can move 5 hex maximum (variable can be adjusted)

    - Player and Enemies move with Move to for smoother translation.

    - I also managed to turn your debug routine to display reachable hexagons.

    - Player moves only when click on hexagon within reaching distance

    Problems so far

    - Reaching distance sometimes fails to work properly when enemies are closed to the player. Some hexagons appear reachable as they are actually not. One of the enemies instance, the last instance (instance #3 when 4 enemies), makes the hexagon it's on funny : this hex has not O written on it as the others (see screencap) and I guess that is the reason why reachable hexagon map around it gets wrong.

    Things I wasn't able to add :

    - I didn't manage to allow player to enter enemy hex and enemies to enter player's hex.

    - also, when the player only moves a number of hex below its max, enemues start to move. Before enemies move, I wanted to let the player move few hex then few more util it's moving points are exhausted but didn't succeed.

    If you have any idea on how to fix this, I'd be grateful.

  • Hi,

    Looks like you did some cool things with it. As your previous edit says, it does look a bit esoteric, but there are probably some ways to simplify thing so that what it's doing is more clear.

    For moving the player repeatedly till it's moves are used up or end turn is clicked I think adding another state would do that. So it would be:

    "show moves", which would highlight the moves in range.

    "wait player", would be largely the same but only allow clicking on in range tiles

    "move player", largely the same, but would subtract from the range as the player moved. if the range wasn't 0 at the end it would go back to "show moves"

    "move enemies", would remain the same.

    I can't edit the cp3 because i don't own c3 and it's beyond the free limits. However the highlighting moves should boil down to something like this:

    if state="show moves"
    	pathfind from player.target
    	unhighlight all hex
    	pick hex with hex.dist>0 and hex.dist<=playerMoves
    		highlight hex
    	set state to "wait player"

    Having the player, and enemies be able to move into each other to attack probably needs some more thought on how we are doing things. Right now when an object moves it thinks of everything else as a wall.

    For player movement: if we click on a tile, and an enemy is on it, we can decide not make that one a wall, since typically we make enemies walls.

    For enemies, we already have that logic in event 38 to do attacking. I just don't do anything, except not move into the tile.

    Anyways, just some ideas. I haven't done any updates to the examples, just referenced them.

  • Had a go at making an updated example. It should cover all the points you were after.

    dropbox.com/s/p7ysobapnmlvlh9/hex_pathfind3.capx

    * pathfinder was updated so it can step onto occupied tiles, but won't go past it. Had to temporarily disable the occupied var of the starting tile to do it.

    * possible moves of the player will be displayed, and hidden after selecting a move.

    * player and enemies can attack each other. An attack counts as a move.

    * player can be moved all at once or in multiple steps.

    * added smooth movement, and things will wait till they stopped moving to move on.

    Other than that i cleaned things up and tried comment everywhere should you need to modify things. Logic is similar but differs a bit.

  • Thank you R0J0hound, that's amazing.

    The game logic is perfect and a lot for me to learn from.

    I managed to create an attack routine but it appears that when Player or a given Enemy attacks, other Enemies continue to act simultaneously. Is there a way to pause their action while attack routine is processed ?

    You wrote that :

    * pathfinder was updated so it can step onto occupied tiles, but won't go past it. Had to temporarily disable the occupied var of the starting tile to do it.

    Do you mean that pathfinding considers occupied tiles but don't allow player or enemy to step in ? Actually, that's precisely the gameplay I was looking for because my planned attack routine was to take place when player and enemy are in the same hexagon. Hexagon state occupation in the game could be : empty, occupied with player, occupied with one enemy, occupied by player and one enemy (in this last case, other enemies wait for their turn outside the player hexagon for the attack to end and can only enter if the enemy inside is defeated).

    There is also something I noticed :

    - When I add a 5th Enemy on the board, when it enters player's avaible hexs, this enemy's hex don't have any number. It has no consequences but it's odd.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • You could change the enemies to move one at a time. Maybe something like this?

    Moving=0
    EnemyMoves>0
    — enemy: moved=0
    — — pick enemy instance 0
    — — — enemy: set moved to 1
    — — — move enemy
    — else
    — — subtract 1 from enemyMoves
    — — enemy: set moved to 0

    Having multiple units be able to be on the same tile would require changes over all the events to handle that. The current events assume only one unit can be on a tile at once. Off hand you could make occupied variable be the count of the objects in it, or maybe have two variables instead occupiedByPlayer and occupiedByEnemy. You’d need to then change how the occupied spaces are temporarily made walls, and maybe the pathfind function would need another parameter saying whether it was for an enemy or player. Just thinking aloud. Maybe that would give ideas.

    As a side idea the pathfinder could be redesigned slightly to eliminate the need to temporarily mark spots as walls. If possible that would simplify events.

    We’ll see how well I triage my time this week.

  • Yes, I was thinking moving one at the time could also be great for the game atmosphere. So, when an enemy moves, Player hexagon have to be considered as non occupied/obstacles so it could be entered and then trigger the Attack routine (this routine in my game would be a complete module with choice for weapon). When attack is resolved, 1) Player is killed, game ends, 2) Enemy is defeated, game goes back to next enemy moves and Attack routine may occur again if it enters Players' hex.

    To let Player enter Enemy hex, Enemies' hex have to be considered non occupied/obstacles. When Players enters, Attack routine is triggered as above and if Player wins, he is allowed to move using his remaining points to move and why not attack another enemy if in range.

    And I want to thank you again for your attention ;)

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