Like the title says, how can I create collision between sprites and walls so Players can't go through them?
Wall Collision
Root / Programming Questions / [.]
UltraPhoenix4Created:
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:A quote from when I asked 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 ENDThe 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
Thanks A L O T!
There were some mistake with that code(Because I wrote it without doing testing). Here is the code that work:
NDS4S343
I don't know how long i will leave this file uploaded, because I don't have a gold membership.
// 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 ENDAnd here is the key to see it in action: