Page 1 of 2
Collision problem
Posted: Thu Aug 23, 2007 10:31 pm
by ChebbyShabby
i'm coding a game and i currently have this in the main event code:
Code: Select all
If SpriteCollision(#Player, x, Y, #Platform, xX, yY) And x + SpriteWidth(#Player) > xX And Y<yY
x = xX - SpriteWidth(#Platform)
EndIf
where x and y are the coordinates of the player while xX and yY are the coordinates of the platform. the code basically checks if the player has collided with the platform from the left.
and this too (for movement)...
Code: Select all
If KeyboardPushed(#PB_Key_Right)
x + 5
EndIf
the problem is that when the player collides with the platform from the left, he moves inside the block and when the user lets go of the right key button he stops. how do i stop this?
Posted: Thu Aug 23, 2007 10:49 pm
by Kaeru Gaman
if you already compare x with xX and y with yY, you don't need ne collision anymore.
you should not set the coordinate of the player directly on collision,
better just manipulate it, to keep it possible to move tha player further.
Posted: Thu Aug 23, 2007 11:35 pm
by ChebbyShabby
what do you mean? note that the comparison of the x and xX and y and YY are only half. that is, if a player was anywhere to the left of or underneath the box it would still count as a collision.
Posted: Fri Aug 24, 2007 2:22 am
by Kaeru Gaman
then complete the coordinate check.
it is surely better, because you want to react if the feet of the player hit the elevator, not if his head does.
and you don't need to request the width of the sprite, it is a fixed value,
so better carry it in a variable, it's faster then a function-call.
and the main problem still is, you set x to a fix value there,
so your player will move to that new position, every time the condition is true.
Posted: Fri Aug 24, 2007 3:17 am
by Rook Zimbabwe
Kaeru, do you mean that the player should BOUNCE BACK?
I do miss the built in collision system in BB!
Posted: Fri Aug 24, 2007 9:25 am
by Kaeru Gaman
I dunno what he wants to do exactly. it's just too little information.
but I can say, that it's most times not useful, to set an absolut position as reaction to a collision.
and I can say, that four coordinate-checks are better than one collision check plus two coordinate checks.
> I do miss the built in collision system in BB!
I don't know what it can, but would it be that difficult, to implement such things?
you are talking about 2D, do you?
Posted: Fri Aug 24, 2007 10:55 am
by ChebbyShabby
you don't understand -- everything works perfectly; the consequences you claim, such as "the main problem still is, you set x to a fix value there,
so your player will move to that new position, every time the condition is true", do not happen. instead, the player stops where he's supposed to. the main problem is that before the player stops, he moves into the block.
lemme try to explain this better: when the player collides into a platform, he goes into it first, and when the user lets go of the keyboard, THEN the player moves where he's supposed to.
and 4-point coordinate checks give me the same result anyway.
Posted: Fri Aug 24, 2007 3:53 pm
by Demivec
ChebbyShabby wrote:lemme try to explain this better: when the player collides into a platform, he goes into it first, and when the user lets go of the keyboard, THEN the player moves where he's supposed to
It seems as if your display is out of sequence.
Code: Select all
You are using:
* Calculate new positions
* display updated positions
* check for collisions and correct new positions if something collided.
You should use:
* Calculate new positions
* check for collisions and correct new positions if something collided.
* display updated positions
According to your words, the detection works fine. If that is true why are you asking for help on the detection? You would need a larger snippet of your code that includes display as well as calculation to demonstrate the problem you're having so you could get the needed input (from the forum).
Posted: Sat Aug 25, 2007 3:18 pm
by ChebbyShabby
give me your email and i'll send the file to you (if this isn't a problem). i can't find any free upload sites which don't require creating an account.
but here is the main code:
Code: Select all
; Platform scroller example
; 2007
; Adam Boulfoul
;
;-Physics variables
Gravity.f = 0.5
;-Load the level
Procedure CountLines(file$)
If ReadFile(0,file$)
l = Lof(0)
m = AllocateMemory(l)
ReadData(0,m,l)
m$ = PeekS(m)
FreeMemory(m)
CloseFile(0)
EndIf;
ProcedureReturn CountString(m$,Chr(10))
EndProcedure;
n = CountLines("Level.txt")
Dim pX.l(n)
Dim pY.l(n)
ReadFile(1,"Level.txt")
While Eof(1) = 0
a + 1
If a & 1
pX(a) = Val(ReadString(1))
Else
pY(a) = Val(ReadString(1))
EndIf
Wend
CloseFile(1)
;-Prepare the screen
InitKeyboard()
InitSprite()
OpenScreen(640,480,32,"")
SetFrameRate(60)
;-Prepare the sprites
Enumeration
#Player
#Platform
EndEnumeration
LoadSprite(#Player,"Eraser.bmp")
LoadSprite(#Platform,"Platform.bmp")
x = 30
Repeat
FlipBuffers()
ClearScreen(RGB(0,0,0))
;-Display the level
For i = 0 To n
If i & 1
xX = pX(i)
yY = pY(i + 1)
EndIf
If pX(i) <> 0
DisplayTransparentSprite(#Platform,xX,yY)
EndIf
Next
DisplayTransparentSprite(#Player,x,Y)
;-Jump physics
Velocity = Power - (Gravity * FlightTime) ;Adaptation of "v = u + at"
FlightTime + 1
y - Velocity
;-Collision detection
For i = 1 To n
If i & 1
xX = pX(i)
yY = pY(i + 1)
EndIf
If x<xX + 15 And x + 15>xX And Y + 24>yY And Y<yY ;Collision with TOP of platform
FlightTime = 0
Power = 0
y = yY - SpriteHeight(#Player)
EndIf
If x<xX + 20 And x>xX And Y + 24>yY And Y<yY ;Collision with RIGHT of platform
x = xX + 20
EndIf
If x + 20>xX And x<xX + 20 And Y + 24>yY And Y<yY ;Collision with LEFT of platform
x = xX - 20
EndIf
Next i
;-Horizontal movement
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Left)
x - 5
ElseIf KeyboardPushed(#PB_Key_Right)
x + 5
EndIf
;-Jump
If KeyboardPushed(#PB_Key_Space): Power = 10: EndIf
Until KeyboardPushed(#PB_Key_Escape)
End
the platform sprite is just a 20x20 block and the player sprite is just a 24x24 block and the level is a txt file.
Posted: Sun Aug 26, 2007 4:02 am
by Demivec
I've sent you my e-mail via a PM.
Posted: Sun Aug 26, 2007 6:50 pm
by Kaeru Gaman
i can't find any free upload sites which don't require creating an account.
what about
www.uploaded.to or
www.upload.sc ?
Posted: Mon Aug 27, 2007 5:16 am
by Rook Zimbabwe
the platform sprite is just a 20x20 block and the player sprite is just a 24x24 block and the level is a txt file.
Actually if that is true you could create the blocks inside the program and use [c*de][/c*de] to show us the text file as well...
Posted: Mon Aug 27, 2007 10:20 am
by ChebbyShabby
ok. sorry for the delay (and thanks, kaeru), people. here's the link anyway:
http://uploaded.to/?id=epm1mw
Posted: Mon Aug 27, 2007 6:47 pm
by Demivec
Here is an example of some changes that would help:
Code: Select all
;-Physics variables
Gravity.f = 0.5
;-Load the level
Procedure CountLines(file$)
If ReadFile(0,file$)
l = Lof(0)
m = AllocateMemory(l)
ReadData(0,m,l)
m$ = PeekS(m)
FreeMemory(m)
CloseFile(0)
EndIf;
ProcedureReturn CountString(m$,Chr(10))/2
EndProcedure;
n = CountLines("Level.txt")-1
;Dim pX.l(n)
;Dim pY.l(n)
Dim p.POINT(n)
ReadFile(1,"Level.txt")
; While Eof(1) = 0
; a + 1
; If a & 1
; pX(a) = Val(ReadString(1))
; Else
; pY(a) = Val(ReadString(1))
; EndIf
; Wend
For I=0 To n
p(I)\x=Val(ReadString(1))
p(I)\y=Val(ReadString(1))
Next
CloseFile(1)
;-Prepare the screen
InitKeyboard()
InitSprite()
OpenScreen(640,480,32,"")
SetFrameRate(60)
;-Prepare the sprites
Enumeration
#Player
#Platform
EndEnumeration
LoadSprite(#Player,"Eraser.bmp")
LoadSprite(#Platform,"Platform.bmp")
playerHeight = SpriteHeight(#Player)
playerWidth = SpriteWidth(#Player)
platformHeight = SpriteHeight(#Platform)
platformWidth = SpriteWidth(#Platform)
diffWidth = (playerWidth - platformWidth) / 2
diffHeight = (playerHeight - platformHeight) / 2
x = 30
Repeat
FlipBuffers()
ClearScreen(RGB(0,0,0))
;-Display the level
For I = 0 To n
; If I & 1
; xx = pX(I)
; yy = pY(I + 1)
; EndIf
; If pX(I) <> 0
; DisplayTransparentSprite(#Platform,xx,yy)
; EndIf
xx = p(I)\x
yy = p(I)\y
DisplayTransparentSprite(#Platform,xx,yy)
Next
DisplayTransparentSprite(#Player,x,y)
;-Jump physics
Velocity = Power - (Gravity * FlightTime) ;Adaptation of "v = u + at"
FlightTime + 1
y - Velocity
;-Horizontal movement
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Left)
x - 5
ElseIf KeyboardPushed(#PB_Key_Right)
x + 5
EndIf
;-Jump
If KeyboardPushed(#PB_Key_Space): Power = 10: EndIf
;-Collision detection
For I = 0 To n
; For I = 1 To n
; If I & 1
; xx = pX(I)
; yy = pY(I + 1)
; EndIf
xx = p(I)\x
yy = p(I)\y
;If x<xx + 15 And x + 15>xx And y + 24>yy And y<yy ;Collision with TOP of platform
If (xx - 19)<x And x<(xx + 15) And (yy - playerHeight)<y And y<(yy - diffHeight) And Velocity<0;Collision with TOP of platform
FlightTime = 0
Power = 0
;y = yy - SpriteHeight(#Player)
y = yy - playerHeight
EndIf
If (xx - 19)<x And x<(xx + 15) And (yy - diffHeight)<y And y<(yy + platformHeight) And Velocity>0;Collision with BOTTOM of platform
FlightTime = 20
y = yy + platformHeight
EndIf
;If x<xx + 20 And x>xx And y + 24>yy And y<yy ;Collision with RIGHT of platform
If (xx - diffWidth)<x And x<(xx + platformWidth) And (yy - playerHeight)<y And y<yy ;Collision with RIGHT of platform
x = xx + platformWidth
EndIf
;If x + 20>xx And x<xx + 20 And y + 24>yy And y<yy ;Collision with LEFT of platform
If (xx - playerWidth)<x And x<(xx - diffWidth) And (yy - playerHeight)<y And y<yy ;Collision with LEFT of platform
x = xx - playerWidth
EndIf
Next I
Until KeyboardPushed(#PB_Key_Escape)
End
The major change thoughis to move the collision checking before the displaying section. Your code does: display,checking,moving. It now does: display,moving,checking.
I made some small changes also. I changed the variables and loops for accesing the level data. Instead of pX() and pY() where only every other index had any data it now uses p.point() and every index contains data. This gives p(i)\x=x and p(i)\y=y.
I rearranged the terms in your collision checking to assist with one other small problem. Each now shows that a coodinate of 5<x<12 as "5<x and x<12" to make it easier to see the range the variable is in.
The player was allowed to go partially in to the Left of the platform but not the right. This was fixed with coordinates being adjusted, though I personally think it would be appropriate to have overlap on the platform in both left and right directions.
I substituted variables for the heights, widths and the difference of widths for the player and platforms. This is so you could see the way the formula was constructed easier. You may prefer to replace these with a constant value. In the meantime it allows you to change somethings a little easier.
I added a collision method for overhanging platforms, in case you add that in other levels. To demonstrate it I added three platforms to the beginning of your level.txt file:
The collision includes the direction of travel (velocity) to determine if the player moved into a platform from above or below. This included a small modification to the collision from the TOP code.
The collision method still has at least one case that it can't handlel. This is if a block is falling and moving into a platform on the left.
Posted: Mon Aug 27, 2007 7:41 pm
by ChebbyShabby
thank you so much, dem

. great help. now i'll just sit here and try to work out how to stop the case of jumping and moving to the left of the platform as well as why there's overlapping if this happens from the right. still, your work is appreciate.
Edit: also, i see you used mechanics/physics concepts to make FlightTime equal to 20 when falling down. can i just ask, what do you do in uni and what did you study at school?