LoginLogin
Might make SBS readonly: thread

4 Line BG Collision Tutorial (No Vsync)

Root / Submissions / [.]

MochaProbablyCreated:
I am aware that Randomousecrap recently did an extensive tutorial on this topic, and i have not tried it just yet, but i will show you how to implement easy collision in just about 4 lines of code. This collision if practically perfect and can be applied to pretty much any type of 2d game, from RPGs to Platformers. The only thing that i will say is somewhat buggy is outer corners of tiles, but it’s super minimal and unnoticeable with actual gameplay. We will be using a sprite for the player and BG tiles & layers for what we be colliding with.

The Basics

You will be using a sprite of any size for this to work, it does not matter the size just requires some number adjusting which is not hard. BG tiles will act as our map, realistically you only need one layer for this but if you want to have a layer in which the player may interact with things that works with this too, just some modifications to it will be optimal. We want the sprite to collide with BG tiles, so we just have to check the BG tiles where the player is in screen coordinates.

The code

So we have to use the BGGET command, that is not too hard. It’s syntax is BGGET(Layer#, Screen X, Screen Y[, Coordinate system flag]) For Layer# choose the layer with all he stuff you want the player to collide with. Screen X and Screen Y is where the player is in screen coordinates (0-399,0-239). And set Coordiante system flag to one, this tells the system to check screen coordinates not any other type of coordinates. It sholuld something like:
BGGET(1,200,120,1)
We are saying “Detect BG tiles in the center of the screen” Now we must put this into an IF statement. This will ask the system every frame if there is a BG tile here on layer# do this.
IF BGGET(1,200,120,1) THEN
Now if we detect something in the center of the screen ( making our statement true ) we can tell it to do something.Now before we go further we must understand we have to make collission for every side of the Layer, so we can have collission around all sides of the tiles.I find the sweet spot is to add or subtract 7 from the X or the Y coordinate in the BGGET command. For this portion of the collision i will be using collision for the top of the BG tiles, but it is applicable to all sides of the tile. For adding/subtracting 7 from the BGGET command here is a quick guide showing you where you should add and subtract 7 as well as if your going to do so on the X or the Y: TOP:
BGGET(Layer#,X,Y+7,1)
BOTTOM:
BGGET(Layer#,X,Y-7,1)
RIGHT:
BGGET(Layer#,X+7,Y,1)
LEFT:
BGGET(Layer#,X-7,Y,1)
Ok now let’s add in what will happen when there is a tile within the coordinates we have set on our screen.
IF BGGET(1,200,120+7,1) THEN DEC PY,1
PY would be Player Y. You will have noticed i used DEC and PY for this one, this is specific to top collision, you’d use other combinations for the other sides: BOTTOM:
INC PY,1
LEFT:
INC PX,1
RIGHT:
DEC PX,1
A complete collision block should look like:
IF BGGET(1,200,120+7,1) THEN DEC PY,1

IF BGGET(1,200,120-7,1) THEN INC PY,1

IF BGGET(1,200+7,120,1) THEN INC PX,1

IF BGGET(1,200-7,120,1) THEN DEC PX,1

Your code is highly inefficient. You can easily cut the code length a lot by simply removing lines that aren't needed
IF BGGET(1,200,120+7,1) THEN
 DEC PY,1
ENDIF

IF BGGET(1,200,120-7,1) THEN
 INC PY,1
ENDIF

IF BGGET(1,200+7,120,1) THEN
 DEC PX,1
ENDIF

IF BGGET(1,200-7,120,1) THEN
 DEC PY,1
ENDIF

I haven't used smilebasic for a while but I remember that BGGET has a bug if you use it with pixel coordinates. That bug make that BGGET return the tile on the position (X,Y) on the screen, not on the map itself. Example: Given the following map: AB BA If you use BGGET on position (16,0) then you will get the tile B. However, if the background is positioned at the coordinate (16,0), then BGGET will return the tile A. I just put this if someone want to use the example uploaded by Warrior along with background scrolling.

Replying to:MasterR3C0RD
Your code is highly inefficient. You can easily cut the code length a lot by simply removing lines that aren't needed
IF BGGET(1,200,120+7,1) THEN
 DEC PY,1
ENDIF

IF BGGET(1,200,120-7,1) THEN
 INC PY,1
ENDIF

IF BGGET(1,200+7,120,1) THEN
 DEC PX,1
ENDIF

IF BGGET(1,200-7,120,1) THEN
 DEC PY,1
ENDIF
Ah ok. The code i included in the post didn’t have too much thought put into it because it was mostly an overhaul of the collision system Picy used in AfterWar, i kinda built off his original framework for the collision, the version i included is much more compact than his, and now yours is more compact than mine :> Thanks! EDIT: Oh and should i revise the post to use your simplified version?

Replying to:MasterR3C0RD
Your code is highly inefficient. You can easily cut the code length a lot by simply removing lines that aren't needed
IF BGGET(1,200,120+7,1) THEN
 DEC PY,1
ENDIF

IF BGGET(1,200,120-7,1) THEN
 INC PY,1
ENDIF

IF BGGET(1,200+7,120,1) THEN
 DEC PX,1
ENDIF

IF BGGET(1,200-7,120,1) THEN
 DEC PY,1
ENDIF
Yeah, you should change it. The old one is slower, longer, and inefficient.

"Randomousecrap" uhhh two things 1. lumage changed their name to randomous 2. incorrect spelling

Replying to:IAmRalsei
"Randomousecrap" uhhh two things 1. lumage changed their name to randomous 2. incorrect spelling
1. It’s the name he’s known by everywhere, name change or not. 2. Memes

Replying to:raimondz
I haven't used smilebasic for a while but I remember that BGGET has a bug if you use it with pixel coordinates. That bug make that BGGET return the tile on the position (X,Y) on the screen, not on the map itself. Example: Given the following map: AB BA If you use BGGET on position (16,0) then you will get the tile B. However, if the background is positioned at the coordinate (16,0), then BGGET will return the tile A. I just put this if someone want to use the example uploaded by Warrior along with background scrolling.
It's supposed to do that. If you want to use pixel coordinates and ignore the offset, you can just divide by 16 and use tile mode instead.