LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

Wall Collision

Root / Programming Questions / [.]

UltraPhoenix4Created:
Like the title says, how can I create collision between sprites and walls so Players can't go through them?

One way is to make it so that if the sprite is at a certain area, then it stops
IF X>80 THEN X=80

That works in some scenarios but I mean for an RPG like game with lots of collisions.

I'm kinda struggling with this concept as well, but here's what I have to recommend If you're on a strictly grid-like engine, it's as simple as restricting movement based on the wall collision. For example...
IF BG_COLLISION_ARRAY[PlayerX, PlayerY-1]==Whatever you use to indicate that it is a wall.
This is a test to see if the BG tile upwards you is a wall. If it comes out false, then you can let the character move upwards. If you have a free-roaming movement engine like A Link to the Past, then it's much harder, but pretty similar. By using many, many more logic questions that check your position on a tile and your position relative to nearby walls, you can definitely make a complex collision system. Alternatively, there may be something you can do with sprite collision detection, but I haven't dabbled in that very much, so I can't help you there. Whichever you use, it's important to have a map array that contains all the details about BG collision.

BGGet(X,Y,F) return the cell on the coordinate X,Y. X,Y could be pixel unit if F == 1 or tile unit if F == 0. The first 12 bits represent the tile, the rest are used for transformation. You could do something like this:
// SP is the management number of the sprite
// VX and VY are the speed in pixel unit
// Return true if the sprite overlap a tile different to 0

DEF collisionWithBG(SP,VX,VY)
 VAR X,Y,W,H,C

 C=0
  
 SPCOL SP OUT X,Y,W,H
 INC X,VX
 INC X,VY
 INC W,VX
 INC H,VY

 INC C,BGGET(X,Y,1)
 INC C,BGGET(X+W,Y,1)
 INC C,BGGET(X,Y+H,1)
 INC C,BGGET(X+W,Y+H,1)

 RETURN C
END
The code above get the collider of the sprite and then check if it overlap a tile different to 0(Empty). If you want to know if the collider is overlapping certain tile then you could do something like this.
// SP is the management number of the sprite
// VX and VY are the speed in pixel unit
// T is the tile id without transformation.
// Return true if the sprite overlap a tile T.

DEF collisionWIthTileT(T,SP,VX,VY)
 VAR X,Y,W,H,C
 VAR FILTER=&B111111111111

 C=0
  
 SPCOL SP OUT X,Y,W,H
 INC X,VX
 INC X,VY
 INC W,VX
 INC H,VY

 INC C, (BGGET(X,Y,1) AND FILTER)==T 
 INC C, (BGGET(X+W,Y,1) AND FILTER)==T
 INC C, (BGGET(X,Y+H,1) AND FILTER)==T
 INC C, (BGGET(X+W,Y+H,1) AND FILTER)==T

 RETURN C
END
A quote from when I asked this.

Thanks A L O T!

no problem glad we could all help :)

There were some mistake with that code(Because I wrote it without doing testing). Here is the code that work:
// SP is the management number of the sprite
// VX and VY are the speed in pixel unit
// Return true if the sprite overlap a tile different to 0

DEF collisionWithBG(SP,VX,VY)
 VAR X,Y,W,H,C

 C=0
 SPOFS SP OUT X,Y
 SPCOL SP OUT ,,W,H

 IF W+H==0 THEN
  ? "SPRITE DOESNT HAVE COLLIDER"
  STOP
 ENDIF

 INC X,VX
 INC Y,VY
 INC W,VX
 INC H,VY

//this code work for the layer 0, but you can pass that as an argument if you want.
 INC C,BGGET(0,X,Y,1)
 INC C,BGGET(0,X+W,Y,1)
 INC C,BGGET(0,X,Y+H,1)
 INC C,BGGET(0,X+W,Y+H,1)

 RETURN C
END




// SP is the management number of the sprite
// VX and VY are the speed in pixel unit
// T is the tile id without transformation.
// Return true if the sprite overlap a tile T.
DEF collisionWIthTileT(T,SP,VX,VY)
 VAR X,Y,W,H,C
 VAR FILTER=&B111111111111

 C=0
 SPOFS SP OUT X,Y
 SPCOL SP OUT ,,W,H //You can leave the output without some variables.

 IF W+H==0 THEN
  ? "SPRITE DOESNT HAVE COLLIDER"
  STOP
 ENDIF


 INC X,VX
 INC Y,VY
 INC W,VX
 INC H,VY

//this code work for the layer 0, but you can pass that as an argument if you want.
 INC C, (BGGET(0,X,Y,1) AND FILTER)==T 
 INC C, (BGGET(0,X+W,Y,1) AND FILTER)==T
 INC C, (BGGET(0,X,Y+H,1) AND FILTER)==T
 INC C, (BGGET(0,X+W,Y+H,1) AND FILTER)==T

 RETURN C
END



//This is an example on how to use that function. The following will detect collition with the tile C(Or any image using that position).
IF collisionWIthTileT(ASC("C"),0,VX,VY)>0 THEN
 VX=0
 VY=0
END

And here is the key to see it in action: NDS4S343 I don't know how long i will leave this file uploaded, because I don't have a gold membership.

is it still up?

Yes, it's still up. If I delete the program, then I'll erase that key too(Unless I forget that I published that key here).

can you put that back up so I can use it?

Just copy the code by hand.

yeah I will try

could someone repost that key please?

could someone repost that key please?
Just copy the code by hand.

i try'd.

well me too, dident work, but if you watch petit professors video on it it helped me a lot and worked too

I'll try to upload the code again.

I'll try to upload the code again.
so...when?

Well, I've been busy with other things but here is the key. Key: [DFDEES3] I didn't get time to put commentaries on the code but you can ask me if you don't understand something.