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.