Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

2D All the way! / How to do a Collision Mask

Author
Message
Derekioh
13
Years of Service
User Offline
Joined: 1st Feb 2009
Location:
Posted: 21st Jun 2012 20:16
A while back, I guy named wildbill suggested i use a collision mask to use as collision since i had a tile system. He said:

Quote: "Since you are using tiles though, one of the easiest ways is to make a collision mask. It actually might be the oldest way too. Make the bottom layer of your tile engine the collision layer. If that tile is red or whatever color you want you have collided with something. Just check the pixel color at the cardinal compass directions from your sprite, if its red you can not move that direction. One of the benifits of a collision mask is that you can make it whatever shape you want and it will still work."


However, I feel tiles are not the most accurate since i only want part of the tile to be collision based. Could someone explain how I might do this?

Pincho Paxton
20
Years of Service
User Offline
Joined: 8th Dec 2002
Location:
Posted: 22nd Jun 2012 02:11 Edited at: 22nd Jun 2012 02:14
Like this....



Will work with any shape.

Derekioh
13
Years of Service
User Offline
Joined: 1st Feb 2009
Location:
Posted: 22nd Jun 2012 05:27
wow, seems simple enough. thank you

Derekioh
13
Years of Service
User Offline
Joined: 1st Feb 2009
Location:
Posted: 22nd Jun 2012 20:16 Edited at: 22nd Jun 2012 20:31
well what if im using a sprite instead of a the cursor?

How do i check what color intersects with the sprite?

EDIT: Nevermind, the point command is the key thanks!

Pincho Paxton
20
Years of Service
User Offline
Joined: 8th Dec 2002
Location:
Posted: 22nd Jun 2012 21:20
You can also put your collision on Bitmap 1, and then switch back to Bitmap 0. That hides the collision graphics.

Derekioh
13
Years of Service
User Offline
Joined: 1st Feb 2009
Location:
Posted: 23rd Jun 2012 00:05
how would i implement this in a scrolling tilemap?

Pincho Paxton
20
Years of Service
User Offline
Joined: 8th Dec 2002
Location:
Posted: 23rd Jun 2012 00:59 Edited at: 23rd Jun 2012 01:00
You would paste the tile sprite on Bitmap 0, and paste the collision tile on Bitmap 1. The tilemap would need a tile, and a collision tile. You can use different colours for different effects.. blue for water, red for a wall. You then use the point command on Bitmap 1 (set current bitmap 1, paste collision tiles, get colour, set current bitmap 0)

Derekioh
13
Years of Service
User Offline
Joined: 1st Feb 2009
Location:
Posted: 23rd Jun 2012 04:57
Im not really following what you are saying...could you post and example r some pseudo code?

Derekioh
13
Years of Service
User Offline
Joined: 1st Feb 2009
Location:
Posted: 23rd Jun 2012 05:00
right now I'm using a tile sheet (PNG file) and cutting it into 32 x 32 squares to paste on the screen with paste image. Should I be pasting sprites instead to paste the tiles? and how would you paste a sprite to a bitmap, and what is the bitmap id be using? Sorry, very confused

Pincho Paxton
20
Years of Service
User Offline
Joined: 8th Dec 2002
Location:
Posted: 23rd Jun 2012 11:40 Edited at: 23rd Jun 2012 12:03
Paste Image is fine, just stick with that way.

The only thing I have changed is that you paste your images to Bitmap 0, and paste your collision to Bitmap 1.

Pseudo Code...
(set current bitmap 1, paste collision tiles, get colour player X/Y, set current bitmap 0, paste image tiles)

Here's a Download.... (Move the mouse over the menu areas)

Attachments

Login to view attachments
Derekioh
13
Years of Service
User Offline
Joined: 1st Feb 2009
Location:
Posted: 23rd Jun 2012 19:11
well i just learned something new about bitmaps! that makes much more sense. thank you. and i think for the tile map i can use smaller collision tile to achieve any shape i like. Thank you very much for your help.

Kevin Picone
20
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 24th Jun 2012 18:03
If all you want to do is pixel level collisions against a tile map, then you don't really need to draw it.

First you work out what tile the point is over, then check the tile. The collision mask/ block data can be stored in mem block avoiding the render pass completely.

Derekioh
13
Years of Service
User Offline
Joined: 1st Feb 2009
Location:
Posted: 24th Jun 2012 20:02
well im not very expirenced in mem blocks, could you give a basic example?

Kevin Picone
20
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 25th Jun 2012 18:36 Edited at: 26th Jun 2012 09:37
The mem block (memory block) is just a chunk of memory. The programmer can conceptually format the chunk however they wish. In this case we're making a set of 8bit blocks.

If the blocks in the map are say 64x*64y pixels and we use a BYTE to present each a pixel in the mask (for simplicity sake), then each one is (64 * 64 )=4096 bytes in size.

If you needed say 1000 tiles, then we create a mem block that (64*64)*1000 bytes in size.

Assuming you already have the tile index from the map, then to peek/poke into the our mask tiles, all we're doing it calculating the address of the first byte in the tile.

TileOffset=(64*64) * Tile

Then assuming the map querying will works in a world space, then to read the pixels from the mask, we use the modulus of the the tiles world position.

PixelX = WorldTileXpos Mod BlockWidth
PixelY = WorldTileYpos Mod BlockHeight

Now we've all the info we need to read a pixel from the mask.

Pixel= MEMBLOCK BYTE(MemblockIndex , TileOffset +( PixelY * BlockWidth) + PixelX )

Assuming the bytes in the mask used say zero for a transparent pixel. Then we can just compare Pixel with zero. If it's not zero, we hit something. A Bytes gives us 256 potential values, so the different types of materials could be represented.

Derekioh
13
Years of Service
User Offline
Joined: 1st Feb 2009
Location:
Posted: 26th Jun 2012 04:14 Edited at: 26th Jun 2012 04:21
Okay, I'm trying to wrap my head around this so bear with me:

1) so this is to replace having to paste the mask images on the screen?
2) Whats the "Tile" represent? Index of current Tile in TileMap?
Quote: "TileOffset=(64*64) * Tile "

3) Im confused by what you mean
Quote: "Then assuming the map querying will works in a world space, then to read the pixels from the mask, we use the modulus of the the tiles world position.

PixelX = WorldTileXpos Mod BlockWidth
PixelY = WorldTileYpos Mod BlockHeight"


Kevin Picone
20
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 26th Jun 2012 09:54
Quote: "1) so this is to replace having to paste the mask images on the screen?"


yep.


Quote: "2) Whats the "Tile" represent? Index of current Tile in TileMap?"


It's the index of the block that you wish to query for a pixel level impact.


Quote: "3) Im confused by what you mean "


When we query the map for an impact, we give the query a world space coordinate. Our collision function then converts this back to map space, working out what tile we're over within the map, grabs that tile index, then work out what pixel we're cover within that tile.

MapX = WorldSpacePointX / BlockWidth
MapY = WorldSpacePointY / BlockHeight

Now we have the 2d coordinate within our map of which tile we're over. Next grab the tile from our 2D MAP ARRAY

Tile = Map(MapX, MapY)


Tile is the block index, now we need to the pixel within the block we've covering. Either subtract or use modulus..

PixelX = WorldSpacePointX Mod BlockWidth
PixelY = WorldSpacePointX Mod BlockHeight


To grab the pixel for the mem block we, calc our offset in the memblock of our tile, then peek the byte from the tile.

TileOffset = (BlockWidth*BlockHeight) * Tile

Pixel= MEMBLOCK BYTE(MemblockIndex , TileOffset +( PixelY * BlockWidth) + PixelX )


Done.

Derekioh
13
Years of Service
User Offline
Joined: 1st Feb 2009
Location:
Posted: 23rd Jul 2012 21:00 Edited at: 23rd Jul 2012 21:26
For this:

Quote: "Now we have the 2d coordinate within our map of which tile we're over. Next grab the tile from our 2D MAP ARRAY

Tile = Map(MapX, MapY)


Tile is the block index,"


how do i get the index of the array Map(MapX, MapY)?

and how would i go about storing all the map in one memblock?

Kevin Picone
20
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 26th Jul 2012 23:46
Quote: "
how do i get the index of the array Map(MapX, MapY)?
"


erm, sorry don't follow you??


Quote: "
and how would i go about storing all the map in one memblock?
"


By writing the pixels into the memblock. Which would the opposite of this.



To write the 'byte' into our chosen mem block, we'd



Derekioh
13
Years of Service
User Offline
Joined: 1st Feb 2009
Location:
Posted: 27th Jul 2012 22:32 Edited at: 27th Jul 2012 22:53
okay, the writing memblock thing makes sense and simple. but what is the index of the block im trying to query? like if im looking at Map(14,13), what is the index? whats stored in position 14, 13 or 14* 13 = 182?

EDIT: I got it fixed without having to use Tile or TileOffset but if the pixel returns a really big negative number am i doing it right?

Derekioh
13
Years of Service
User Offline
Joined: 1st Feb 2009
Location:
Posted: 27th Jul 2012 23:05 Edited at: 27th Jul 2012 23:45
So Now I've just decided to show you the code:



Edit: got it working. Working code is in there! Thank you very much!

Login to post a reply

Server time is: 2022-12-09 05:40:12
Your offset time is: 2022-12-09 05:40:12