Platformer Collisions broken, cant fix *headbash*

BlitzPlus Forums/BlitzPlus Programming/Platformer Collisions broken, cant fix *headbash*

SilentAssaSIN(Posted 2010) [#1]
Hi guys, I made this platformer code, pretty basic ATM just generates a floor and some random blocks. Collisions seems to work perfectly except under one condition, moving to the left when there is a block underneath.

I've tried and tried but cannot work out what to change, if any of you kind fellows could mull this over and give advise that would be awesome.

One of the things I looked at was to possibly modify the collisions so that X and Y checks are further seperated, maybe that will fix it. I'm going to try that now I guess!

Any help will be ecstaticly recieved as I just can't work it out. I hope you find the code readable enough. It needs to following images to work:

player.png image which can be any image 32x32 (or less)

tiles.png a 32x32 tilestrip, the tiles can be blank/anything as long as the first tile is blank, colour 255,0,255! It's set to load 5 frames as standard so a pure white strip is fine.

collide.png 32x32 mostly 255,0,255 masked to show the areas the code will check for collisions in.




Sauer(Posted 2010) [#2]
I looked at your code and couldn't pinpoint the problem. If I had to guess, it would have something to do with your collision checking does not vary depending on the direction the player is moving.

What I do when making platformers is check collisions at only the points necessary (usually the corners) depending on what direction the player is moving. Here's a small example where the white dots around the circle show where the collisions are being checked:



Hope that helps. I'll look at your code again tomorrow to see if I can find a specific solution.


SilentAssaSIN(Posted 2010) [#3]
Thanks, will check it out once I get into work :) very much appreciated.

At current (sorry I should have explained a bit better) it check the 9 squares around the player. I 'fixed' it in a way by moving the player up very slightly if a y collision is detected but its ugly and occasionally still locks for a millisecond :s

Hehe must find an elegant solution hopefully your techniques will be better, I shall try and adopt them in once I've understood it!

Either way I'm quite chuffed so far hehe.


If you watned to see what i did, after the line

If resety=true
PD\y#=PD\oldy#

change it to also take 0.05 (or so) away from PD\y# ontop but if the number gets too large it bounces, too low and it doesn't work! Interesting times. Good fun either way.


SilentAssaSIN(Posted 2010) [#4]
Hehe thanks for the help, made a few changes and lo and behold it is slightly cleaner. I also added a jump/doublejump feature (spacebar) which is fun. Haha this is great I'm having buckets of fun doing this!

Got myself the basics of a map editor together, going to be great adding features to the 'game' :D

Graphics 800,600,0,2
SetBuffer(BackBuffer())

SeedRnd(Rnd(0.9))

Color 255,0,0

Type playerData
	Field x#,y#,oldx#,oldy#
	Field acc#,maxspeed#,dec#,speed#
	Field gravity#
	Field maxspeedy#,speedy#
	Field IsInAir,DoubleJump
End Type

	PD.playerData=New playerData
	PD\x#=100
	PD\y#=100
	PD\acc#=0.6
	PD\maxspeed#=2
	PD\dec#=0.1
	PD\gravity#=1
	PD\maxspeedy#=24
	PD\IsInAir=True

	player=LoadImage("p.png")
	MidHandle player
	MaskImage player,255,0,255
	tiles=LoadAnimImage("tiles32.png",32,32,0,5)
	MaskImage tiles,255,0,255
	collide=LoadImage("collide.png")
	MaskImage collide,255,0,255

Dim MapH(100,25,7)
;0 background 1
;1 background 2
;3 level layer
;4 foreground 1
;5 foreground 2
;6 mobs
;7 objects
For x=0 To 100
	MapH(x,18,3)=1
	MapH(x,19,3)=1
	MapH(Rand(0,25),Rand(5,20),3)=Rand(0,3)
Next

While Not KeyDown(1)
Cls

PD\oldx#=PD\x#
PD\oldy#=PD\y#

If KeyDown(205) ;Right
	PD\speed#=PD\speed#+PD\acc#
EndIf

If KeyDown(203) ;Left
	PD\speed#=PD\speed#-PD\acc#
EndIf

If KeyHit(57)
	If PD\IsInAir=False
		PD\speedy#=PD\speedy#-16
		PD\IsInAir=True
	Else If PD\DoubleJump=False
		PD\speedy#=PD\speedy#-8
		PD\DoubleJump=True
	EndIf
EndIf

If PD\speed#>0.1
	PD\speed#=PD\speed#-PD\dec#
ElseIf PD\speed#<0.1
	PD\speed#=PD\speed#+PD\dec#
EndIf

If PD\speed#>PD\maxspeed# Then PD\speed#=PD\maxspeed#
If PD\speed#<PD\maxspeed#*-1 Then PD\speed#=PD\maxspeed#*-1
If PD\speed#>-0.2 And PD\speed#<0.2 Then PD\speed#=0



PD\x#=PD\x#+PD\speed#
PD\speedy#=PD\speedy#+PD\gravity
If PD\speedy#>PD\maxspeedy# Then PD\speedy#=PD\maxspeedy#
PD\y#=Floor(PD\y#+PD\speedy#)

For x=Floor(PD\x#/32)-1 To Floor(PD\x#/32)+1
	For y=Floor(PD\y#/32)-1 To Floor(PD\y#/32)+1
		DrawImage collide,x*32,y*32
		Text x*32,y*32,x+" "+y
		If ImagesCollide(player,PD\x#,PD\y#,0,tiles,x*32,y*32,mapH(x,y,3))
			If Not ImagesCollide(player,PD\oldx#,PD\y#,0,tiles,x*32,y*32,mapH(x,y,3))
				Text 10,80,"X Collide  "+x
				resetx=True
			EndIf
			If Not ImagesCollide(player,PD\x#,PD\oldy#,0,tiles,x*32,y*32,mapH(x,y,3))
				Text 10,70,"Y Collide  "+y
				resety=True
				PD\speedy#=0
				PD\IsInAir=False
				PD\DoubleJump=False
			EndIf
			If resetx=True
				PD\x#=PD\oldx#
				resetx=False
			EndIf
			If resety=True
				PD\y#=PD\oldy#
				resety=False
				PD\y#=PD\y#-0.05
			EndIf
		EndIf
	Next
Next

Text 10,10,PD\x#
Text 10,20,PD\speed#

Text 10,40,(PD\x#/32)
Text 10,50,(PD\y#/32)

For x=0 To 24
	For y=0 To 18
		DrawImage tiles,x*32,(y*32),MapH(x,y,3)
	Next
Next
DrawImage player, PD\x#, PD\y#

Flip
Wend