Hello,
I'm using BlitzPlus to get the hang of the basic mechanics behind a platform game.
My problem is with the collision detection between the player sprite and the floor.
The play area is 640x480, divided in to tiles of 8x8, and the player sprite is 15x16 pixels. (x,y)
The code I have used checks all of the tiles around the player at any given time. Using this information it knows if the player should be falling, walking on the floor etc
This is all great, however, I'm finding that the player sprite doesn't always land flush with the floor tile. Sometimes the player lands pixel perfectly on the top of the floor, other times the players feet dip a few pixels below and overlap in to the floor.
Can anybody throw some light on it for me?
Cheers!
*******Code now follows**********
AppTitle "Little Platformer"
;Player Variables
Global frmplayer, tmrplayer ;player animation
Global playerx, playery, jumping ;player position/status
Global ladderpresent ;is the player on a ladder
Global tileleft
Global tileright
Global tileabove
Dim tilebelow(1)
Dim tileon(1)
;Player constants
playerx=250 ;start position
playery=455
;Environment Variables
Global gravity#,yspeed#
;Environment Constants
gravity =.3;Affects jump
jump#= -5 ;jump height
speedx#=0 ;ground friction
;Level variables
Dim level(79,59)
;MAIN PROGRAM;
;************;
;Prepare Screen
Graphics 640,480,16,1 ;set resolution
;load player animation and mask
gfxplayer=LoadAnimImage("c:\dk\player.bmp",15,16,0,12)
MaskImage gfxplayer,255,0,255
;load level gfx
floorgfx=LoadImage("C:\dk\floor.bmp")
MaskImage floorgfx,255,0,255
laddergfx=LoadImage("C:\dk\ladder.bmp")
MaskImage laddergfx,255,0,255
;Load the current level from file to the array
filein = ReadFile("c:\dk\levels\level1.txt")
For y = 0 To 59
For x = 0 To 79
level(x,y) = ReadByte(filein) ;read 1 byte at a time
Next
Next
CloseFile(filein)
;MAIN GAME LOOP;
;**************;
While Not KeyDown(1) ;until esc is pressed
SetBuffer BackBuffer()
Cls
;draw the level/objects on screen
;Floor tiles
For y = 0 To 59
For x = 0 To 79
Select level(x,y)
Case 49
DrawImage floorgfx,x*8,y*8
Case 50
DrawImage laddergfx,x*8,y*8
End Select
Next
Next
;draw the player
DrawImage gfxplayer,playerx,playery,frmplayer
;discover players immediate surroundings
tilebelow(0) = level(playerx/8,(playery/8)+2)
tilebelow(1) = level((playerx/8)+1,(playery/8)+2)
tileabove = level(playerx/8,(playery/8)-1)
tileleft = level((playerx/8)-2,playery/8)
tileright = level((playerx/8)+2,playery/8)
tileon(0) = level(playerx/8,playery/8)
tileon(1) = level(playerx/8+1,playery/8)
;check collisions against surroundings
If tileon(0) = 49 Or tileon(1) = 49 And yspeed <= 0 Then ;stop jumping you have hit your head
yspeed=0
End If
If tileon(0) = 50 Or tileon(1) = 50 Then ;player is over a ladder
ladderpresent=1
Else
ladderpresent=0
End If
If tilebelow(0) = 49 Or tilebelow(1) = 49 And yspeed >=0 Then ;stop if you are falling and land on a tile
jumping = 0
yspeed=0
End If
If tilebelow(0) = 48 And tilebelow(1) = 48 Then ;falling if nothing is below
jumping=1
End If
;check player input and update accordingly
If JoyX()=-1 Then ;left
;friction
speedx = speedx -.2
If speedx < -2 Then speedx = -2
If MilliSecs() > tmrplayer + 100 Then
tmrplayer=MilliSecs() ; 'reset' the timer
frmplayer=( frmplayer + 1 ) Mod 3 ; increment the frame, flip to 0 if we are out
End If
EndIf
If JoyX()=+1 Then ;right
speedx = speedx +.2
If speedx > 2 Then speedx=2
If MilliSecs() > tmrplayer + 100 Then
tmrplayer=MilliSecs() ; 'reset' the timer
frmplayer=3+( frmplayer + 1 ) Mod 3; increment the frame, flip to 0 if we are out
End If
EndIf
If JoyY()=-1 And ladderpresent=1 Then ;up if a ladder is present
playery=playery-1 ;only go up if there is more ladder
If MilliSecs() > tmrplayer + 100 Then
tmrplayer=MilliSecs() ; 'reset' the timer
If frmplayer=8 Then
frmplayer=10
Else
frmplayer=8
EndIf
End If
EndIf
If JoyY()=+1 And ladderpresent=1 Then ;down if a ladder is present
playery=playery+1 ;only go down if there is more ladder to go down
If MilliSecs() > tmrplayer + 100 Then
tmrplayer=MilliSecs() ; 'reset' the timer
If frmplayer=8 Then
frmplayer=10
Else
frmplayer=8
EndIf
End If
EndIf
If JoyHit(1) And jumping=0 Then ;jump if not already
jumping = 1 ;the player is mid-jump
yspeed# = jump#
EndIf
If jumping=1 ; check that we have pushed the jump key
YSpeed# = YSpeed# + Gravity# ; this will calculate the y location in pixels
If yspeed# > 4 Then yspeed# = 4
playery = playery + YSpeed ; this will add our calculated number to our current y position
End If
;updates on player variables
speedx = speedx * .88 ;friction
playerx = playerx + speedx ;update player x position
;debugging
;Show tilesbelow
;Rect(playerx,playery+16,8,8,0)
;Rect(playerx+8,playery+16,8,8,0)
;show tileon
;Rect(playerx,playery,8,8,0)
;Rect(playerx+8,playery,8,8,0)
Flip ;draw the screen
Wend
I'm using BlitzPlus to get the hang of the basic mechanics behind a platform game.
My problem is with the collision detection between the player sprite and the floor.
The play area is 640x480, divided in to tiles of 8x8, and the player sprite is 15x16 pixels. (x,y)
The code I have used checks all of the tiles around the player at any given time. Using this information it knows if the player should be falling, walking on the floor etc
This is all great, however, I'm finding that the player sprite doesn't always land flush with the floor tile. Sometimes the player lands pixel perfectly on the top of the floor, other times the players feet dip a few pixels below and overlap in to the floor.
Can anybody throw some light on it for me?
Cheers!
*******Code now follows**********
AppTitle "Little Platformer"
;Player Variables
Global frmplayer, tmrplayer ;player animation
Global playerx, playery, jumping ;player position/status
Global ladderpresent ;is the player on a ladder
Global tileleft
Global tileright
Global tileabove
Dim tilebelow(1)
Dim tileon(1)
;Player constants
playerx=250 ;start position
playery=455
;Environment Variables
Global gravity#,yspeed#
;Environment Constants
gravity =.3;Affects jump
jump#= -5 ;jump height
speedx#=0 ;ground friction
;Level variables
Dim level(79,59)
;MAIN PROGRAM;
;************;
;Prepare Screen
Graphics 640,480,16,1 ;set resolution
;load player animation and mask
gfxplayer=LoadAnimImage("c:\dk\player.bmp",15,16,0,12)
MaskImage gfxplayer,255,0,255
;load level gfx
floorgfx=LoadImage("C:\dk\floor.bmp")
MaskImage floorgfx,255,0,255
laddergfx=LoadImage("C:\dk\ladder.bmp")
MaskImage laddergfx,255,0,255
;Load the current level from file to the array
filein = ReadFile("c:\dk\levels\level1.txt")
For y = 0 To 59
For x = 0 To 79
level(x,y) = ReadByte(filein) ;read 1 byte at a time
Next
Next
CloseFile(filein)
;MAIN GAME LOOP;
;**************;
While Not KeyDown(1) ;until esc is pressed
SetBuffer BackBuffer()
Cls
;draw the level/objects on screen
;Floor tiles
For y = 0 To 59
For x = 0 To 79
Select level(x,y)
Case 49
DrawImage floorgfx,x*8,y*8
Case 50
DrawImage laddergfx,x*8,y*8
End Select
Next
Next
;draw the player
DrawImage gfxplayer,playerx,playery,frmplayer
;discover players immediate surroundings
tilebelow(0) = level(playerx/8,(playery/8)+2)
tilebelow(1) = level((playerx/8)+1,(playery/8)+2)
tileabove = level(playerx/8,(playery/8)-1)
tileleft = level((playerx/8)-2,playery/8)
tileright = level((playerx/8)+2,playery/8)
tileon(0) = level(playerx/8,playery/8)
tileon(1) = level(playerx/8+1,playery/8)
;check collisions against surroundings
If tileon(0) = 49 Or tileon(1) = 49 And yspeed <= 0 Then ;stop jumping you have hit your head
yspeed=0
End If
If tileon(0) = 50 Or tileon(1) = 50 Then ;player is over a ladder
ladderpresent=1
Else
ladderpresent=0
End If
If tilebelow(0) = 49 Or tilebelow(1) = 49 And yspeed >=0 Then ;stop if you are falling and land on a tile
jumping = 0
yspeed=0
End If
If tilebelow(0) = 48 And tilebelow(1) = 48 Then ;falling if nothing is below
jumping=1
End If
;check player input and update accordingly
If JoyX()=-1 Then ;left
;friction
speedx = speedx -.2
If speedx < -2 Then speedx = -2
If MilliSecs() > tmrplayer + 100 Then
tmrplayer=MilliSecs() ; 'reset' the timer
frmplayer=( frmplayer + 1 ) Mod 3 ; increment the frame, flip to 0 if we are out
End If
EndIf
If JoyX()=+1 Then ;right
speedx = speedx +.2
If speedx > 2 Then speedx=2
If MilliSecs() > tmrplayer + 100 Then
tmrplayer=MilliSecs() ; 'reset' the timer
frmplayer=3+( frmplayer + 1 ) Mod 3; increment the frame, flip to 0 if we are out
End If
EndIf
If JoyY()=-1 And ladderpresent=1 Then ;up if a ladder is present
playery=playery-1 ;only go up if there is more ladder
If MilliSecs() > tmrplayer + 100 Then
tmrplayer=MilliSecs() ; 'reset' the timer
If frmplayer=8 Then
frmplayer=10
Else
frmplayer=8
EndIf
End If
EndIf
If JoyY()=+1 And ladderpresent=1 Then ;down if a ladder is present
playery=playery+1 ;only go down if there is more ladder to go down
If MilliSecs() > tmrplayer + 100 Then
tmrplayer=MilliSecs() ; 'reset' the timer
If frmplayer=8 Then
frmplayer=10
Else
frmplayer=8
EndIf
End If
EndIf
If JoyHit(1) And jumping=0 Then ;jump if not already
jumping = 1 ;the player is mid-jump
yspeed# = jump#
EndIf
If jumping=1 ; check that we have pushed the jump key
YSpeed# = YSpeed# + Gravity# ; this will calculate the y location in pixels
If yspeed# > 4 Then yspeed# = 4
playery = playery + YSpeed ; this will add our calculated number to our current y position
End If
;updates on player variables
speedx = speedx * .88 ;friction
playerx = playerx + speedx ;update player x position
;debugging
;Show tilesbelow
;Rect(playerx,playery+16,8,8,0)
;Rect(playerx+8,playery+16,8,8,0)
;show tileon
;Rect(playerx,playery,8,8,0)
;Rect(playerx+8,playery,8,8,0)
Flip ;draw the screen
Wend