Detecting collision (or lack of) of blocks next to each other.

redpesto

  • Posts: 134
Hi all,

I have 9 blocks like this:


When you click on a brown block is kills its self. I've been trying to get the blue block to detect when one of the brown blocks disappears and which one(s) have been removed. In my design the blocks are actually perfect squares rather than the wonky sketch above.

Can someone point me in the right direction to do this? The new 2.0 collisions are confusing me a lot.

Lets say you click the brown block above the blue and then the one to the right, how do I go about reporting that via an attribute?

Many thanks, as always!

captaincomic

  • *
  • Posts: 6109
Maybe instead of using collisions you could try with regions.
When you want to detect if the actor next to you exists, create a region around the area where you expect him, and use the "for each actor in region" block to check if an actor is there.

redpesto

  • Posts: 134
But then I would have to create the regions dynamically. The idea is, that if the blue block detects there is no brown block above it, it moves into that space & the collision routine starts again. I don't think regions is the way to go.

Anyone know how to make this work please?

captaincomic

  • *
  • Posts: 6109
Yes, you would have to create the regions dynamically or move them around. I don't know how efficient this would be. Depending on what else in your game needs collisions, you might get away without Box2d at all (disabling physics for all actors), then I think the region approach might be more efficient.

Sunflower

  • Posts: 591
[obvious advertising] Do you, by any chance, want to do something like in this game? ;) [/obvious advertising]

If you want all the blocks to be snapped to some sort of grid, I'd go for Lightweight Actors (that is, with physics turned off completely) and work on 2D Arrays instead. IMHO Box 2D was meant to do more complex tasks, and this might only slow your game down.


hansbe

  • Posts: 262
Use "trigger behaviour in actor" perhaps, to say to the actors that they must react.

However I don't think there is any neat way of reporting things like neighbor square to north, ... unless you make those as attributes and then assign the correct neighbours for every square you put in the scene. This method would however easily end up in a lot of bugs.

It would be easier (IMO) to do both actor creation and triggering from a scene behaviour in code-mode, though it depends perhaps on the scale of the problem (how big is this grid?). The fast & optimized way would be to have all the actors in a 2D array, and calculate the grid index from the mouse coordinate, e.g. column=(mouse_x-left_of_grid)/pitch_of_grid; Another option is to use the getActorsAtPoint function. In block mode there is to my knowledge no such function, but you could create a region dynamically (surrounding the center actor) and use the "for each actor inside region" as captaincomic mentioned.


captaincomic

  • *
  • Posts: 6109
I think there's no getActorsAtPoint for iOS, that's why I suggested using regions. But the 2D array might actually be the best idea.

redpesto

  • Posts: 134
Wow, this has gone way over my head! haha.

Lets reframe this and cover the basics:

Why doesn't it work when I attached a ' NOT colliding top' to the blue block and the brown block above is clicked/killed. The way I thought this was going to work was...


Tell blue block that if the block around it is removed then nothing is colliding top/bottom/right/left  and to print top/bottom/right/left in the console.

Is the problem to do with the updating or due to the blocks laying next to each other are not actually touching?

hansbe

  • Posts: 262
If you want to use collision shapes (might be very slow), you could perhaps make two boxes or a polygon that looks like a cross, that extends a few pixels outside the actor. The actor collision shape should be of type sensor.

It's difficult to say much more if you don't show the code that's not working.

redpesto

  • Posts: 134
I tried the cross that extends outside of the actor but it doesn't accept negative values so I can't place it above and to the left of the actor.

I'll put the code and example up in an hour when I get back home.

Sunflower

  • Posts: 591
Again, can these blocks have irregular coordinates (like 357,204 and 109,43) or do they form some sort of grid (like 64,96 and 160,64 for grid of size 32x32)? If the latter, I strongly recommend you stop wondering about typical collision system and use 2D-Array based one (if you don't want to ask later how to reduce the lag, that is ;) ). I can even give you example of such collision system if you want. ^^'

(in fact I already made something like that for recently published Snake Kit, so you might want to search on Forge to see how it looks like)

redpesto

  • Posts: 134
Attached is an example. All I want to happen is, if you click a brown square up/down/left/right of the blue square, the blue square detects this and moves itself into the empty place.



hansbe

  • Posts: 262
If the blue square is always the same you can use an actor attribute for it. Then in the when clicked behaviour you can use the slide tween to move the blue square to the x and y of the brown square.
You still need to test that the blue square is in a legal position for this to happen. I recommend using the x and y coordinates rather than collisions to determine this. Depending on the game rules, and whether the squares are all the same size, that might be done differently.

redpesto

  • Posts: 134
You still need to test that the blue square is in a legal position for this to happen. I recommend using the x and y coordinates rather than collisions to determine this.

Care to elaborate?
Does the blue square check the relative x,y to the right to see if there is still a brown square there? Using what command to do that actual 'check'.

(Thanks for your help all so far, this idea seemed so simple to me this weekend lol)

hansbe

  • Posts: 262
Well, if the x of the blue square and the x of the brown (clicked) square is the same they are on the same column. So then, if the (y of the blue square - y of the brown square) is smaller than a maximum distance, and larger than the negative of the maximum distance, then you can use the tween.
Same thing would go for the rows, except you must swap x and y.

Note: if you want to check coordinates like above without converting them to a position in the grid, you must be careful that the coordinates match exactly when you place them in the scene editor.