How do I know which tile is being hit on collision

0 favourites
From the Asset Store
Piano tiles
$9.99 USD
Template for a piano tiles game, fully documented in comments and video
  • I did some tests and it appears that with the physics behavior, a projectile will bounce without overlapping the tile so in this case your solution won't work.

    While using the physics behavior, I managed to target the closest tile on my project -with the surrounding tiles thing- but I increased the projectile speed and now it's less accurate.

    Most of the time it works :

    [attachment=0:1mxo79dp][/attachment:1mxo79dp]

    Some of the surrounding tiles (under the blue overlay square) aren't empty so I can target a closest non empty tile when the projectile collides with the wall. The red square is the returned tile from the projectile position with positionToTile.

    But sometimes, quite often, it won't work with my fast projectile :

    [attachment=2:1mxo79dp][/attachment:1mxo79dp]

    The tile returned from the projectile coordinates is one tile farthest from the green wall than it should be.

    No surrounding tiles are overlapping the green wall so my events won't work because it needs to target a close non empty tile.

    I avoided this new issue by increasing the radius of the tested surrounding tiles from 1 square :

    [attachment=1:1mxo79dp][/attachment:1mxo79dp]

    Now I can find the closest tile that is not empty.

    That's an ugly solution thought

  • I don't know the Physics behaviour that well, so if there is another way to do it, I really don't know. But if your works I guess its fine. But what if two tiles are equal range, won't it bug? for instant if you shoot in the corner below where your shot is on the pictures, then the bottom tile and the right tile will be of equal range, or don't you calculate it that precise, so its not likely to happen?

  • Seems like we ought to be able to get collision points using a trigger condition, instead of crazy workarounds. It also seems like we should have some kind of raycasting collision testing. It can't be that much harder to test a ray against a polygon than it is to test two polygons.

    Maybe it's time for someone to read the source and add a line to the physics behavior so that it triggers a condition when it computes a collision, then stores coordinates of the collision.

  • oops, same post.

  • I don't know the Physics behaviour that well, so if there is another way to do it, I really don't know. But if your works I guess its fine. But what if two tiles are equal range, won't it bug? for instant if you shoot in the corner below where your shot is on the pictures, then the bottom tile and the right tile will be of equal range, or don't you calculate it that precise, so its not likely to happen?

    I did some tests about it and you're right, it doesn't work the right way.

    Here the projectile collides with the purple square but the detected closest square is a green one.

    [attachment=0:13dqkpft][/attachment:13dqkpft]

    I guess I could instead check for the distance between each tile and the projectile instead of the tile behind the projectile. I should just be sure that I won't use the projectile center coordinates because the tiles origin is, if I'm not wrong, on their upper left corner. Or something like that. That's too bad there is no straightforward solution to this…

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • bladedpenguin - Yeah. You are getting on to something. Physics needs raycasting, the base system class needs raycasting, and the overlap methods needs updating to be a little more situationally robust. (you should tell ashley as I am sure he has heard it enough from me, lol)

    I have read the source code for both box2d (which is the code runs the physics behavior) and as much of the core classes that runs construct 2 as I can. Changing the physics behavior is perfectly possible. It would be quite easy to add raycasting (most box2d features are easy to add). But you can't mod the system files for construct, so you would have to create a different behavior to handle raycasting vs. solids. This can be done fairly easily as the algorithms for raycasting are easy to find on google.

    But, the biggest problem with all of this is the fact that the tile map generates collision polys in a smart manner. For example: if you have a bunch of square collision tiles, the tilemap will group those up and make it so it uses as few collision shapes as possible. This is awsome for optimization, but this means when you hit a poly, and that poly is a large one that makes up an entire group of tiles, finding the tile still requires some mucking about.

    This actually becomes a sort of dichotomy between performance and a particular function. Does this all make sense? I am saying that the solution to this problem is going to be, somewhat more nuanced than it appears at first look.

  • Hrm this is going to be tricky to work with the optimization that C2 already does, and especially to do it in a way that does not break with updates. My project mostly doesn't use physics, so I would be raycasting against the collision poly. The functions to get that poly aren't in the SDK, so even after finding them, they might change or put the engine in an odd state. I'm content to give it a rest for now. My knowledge of the engine isn't up to this.

  • nimos100

    I am wondering how do we erase/change a range of tiles on a collision with a bullet. For instance, a bullet hits a tile, and then it should trigger a change of 8 tiles around the one that was hit. Let's say we erase those 9 tiles of tilemap 1 and replace them with tiles of tilemap 2 (the red one).

    I only managed to erase and set a tile that was hit , but no luck with erasing and setting neighboring tiles.

    Haven't read all the replies. So this might not be what you mean, but how I understood the original question. But in that case you can just ignore it

    Here is a simple example of how to get the tile.

    (Be advise that the tilemap at row 0 for both X and Y is empty so its not an error that it seems like it should be tile 3,7, its just me that didn't put any tiles in that row, so the white area around the tiles are actually row 0)

    If you want the coordinate in X,Y you can just convert the TileX and TileY to that.

  • nimos100

    I am wondering how do we erase/change a range of tiles on a collision with a bullet. For instance, a bullet hits a tile, and then it should trigger a change of 8 tiles around the one that was hit. Let's say we erase those 9 tiles of tilemap 1 and replace them with tiles of tilemap 2 (the red one).

    I only managed to erase and set a tile that was hit , but no luck with erasing and setting neighboring tiles.

    Since you know which tile the hit takes place you can use this to change the surrounding tiles, simply by passing these coordinates to a function that will replace the correct tiles with the new ones, like this.

  • Thanks nimos100,

    Is tile 12 a red one that replaces 9 tiles?

    Here is what i tried but it does not trigger the change

    here is how it looks as the base

    and this is what i want to achieve

  • Thanks nimos100,

    Is tile 12 a red one that replaces 9 tiles?

    Yes this example only use one tilemap.

    Without the Capx it im not 100% certain.

    But think the wait 3 seconds might be causing the problem as you destroy the bullet, but want to pass it to the function 3 seconds later, im not certain if that is working well or how it works, as i tend to avoid waits. But you have to remember that the rest of your program doesn't pause while this wait is going on. If i remember correct objects that are destroyed will be removed from the game at the next tick. Meaning that the bullet you are trying to pass to the function doesn't exist anymore when you actually need the tile position, and since you are waiting 3 seconds which is 180 ticks a lot of things can go on in the meantime. But anyway im not 100% certain, but regardless of that, i think such situations are best to be avoided because you lack overview of whats going on with waits in your programs.

    So i would use the bomb you create to spawn at the correct Tile (Where the bullet hit) and then add a timer behaviour to that and set it to 3 second, store the Tile position in the bomb or you can generate it later when the timer is up, then use the bomb tile position with the function. Meaning you pass the bomb coordinates to the function rather than the bullet. Think that will solve the problem.

    Otherwise try to add the capx.

  • > Thanks nimos100,

    > Is tile 12 a red one that replaces 9 tiles?

    >

    >

    Yes this example only use one tilemap.

    Without the Capx it im not 100% certain.

    But think the wait 3 seconds might be causing the problem as you destroy the bullet, but want to pass it to the function 3 seconds later, im not certain if that is working well or how it works, as i tend to avoid waits. But you have to remember that the rest of your program doesn't pause while this wait is going on. If i remember correct objects that are destroyed will be removed from the game at the next tick. Meaning that the bullet you are trying to pass to the function doesn't exist anymore when you actually need the tile position, and since you are waiting 3 seconds which is 180 ticks a lot of things can go on in the meantime. But anyway im not 100% certain, but regardless of that, i think such situations are best to be avoided because you lack overview of whats going on with waits in your programs.

    So i would use the bomb you create to spawn at the correct Tile (Where the bullet hit) and then add a timer behaviour to that and set it to 3 second, store the Tile position in the bomb or you can generate it later when the timer is up, then use the bomb tile position with the function. Meaning you pass the bomb coordinates to the function rather than the bullet. Think that will solve the problem.

    Otherwise try to add the capx.

    I passed the bomb coordinates to the function and it worked! Thank you.

  • nimos100,

    There is one problem with setting a new tile to a range of tiles around the hit. As long as it is always a square that fills the whole new area, it adds unnecessary tiles like I highlighted (crossed) in your picture.

    So, imagine that we hit at what an arrow points out

    How should we deal with changing tiles without adding unnecessary ones?

    I guess we should add some kind of loop that goes through all the tilemap making a check against a tile that is not empty and then changing only those tiles, but it seems wacky combining it with functions. Uhh..

  • Yeah you can do it with a loop. And just comparing what type of tile is influence and then based on that change them. There are no difference really whether its in a function or not. Except functions makes it easier to work with your project in general so a function whenever its possible

    Since you already know the starting point of which tiles to check meaning the impact tile X,Y and if you want the 8 tiles surrounding that you just have to start at that position (X,Y) - 1 so (X-1, Y-1). So you can do it like this:

    Since a tilemap will return -1 if there are no tile you can use that.

  • nimos100,

    Strange, but it did not worked for me. Nothing happens except that Bomb object is erased.

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