Collision Problem.
BlitzMax Forums/BlitzMax Programming/Collision Problem.
| ||
![]() In the above example, the red land area is my collision layer for my level, the black box, and smaller yellow box's are my player, and where on the player I am checking collisions. First of all to keep my player on the land I do a check at his feet, loop through small amounts until its touching or just on top of the land. I then check to see if the left is touching anything and the right and nudge the players x left or right to stop it touching. this is actually buggy and for some reason the left check seems to get ignored sometimes. Also another problem is at pos3 if I jump into a land mass as soon as my feet hit it, my loop code bounces me to the top of it, iv tried a number of things to avoid this but they all didnt work. so little help is needed, if you have a better of of checking player collisions on a large image like mine please let me know. oh the land mass in the air, I want to be able to jump through it, but only land on it if my feet actually hit the top of it. Method Collisions() debugstop Local LeftCheck:Int Local RightCheck:Int Local FootCheck:Int ' Im pre checking these here because as the method grows, I may need to call the same chack at the ' same pos more than once. footcheck = ImagesCollide(footcollisionImage , X , Y , 0 , bg_Coll , level_offset , gfx_height - ImageHeight(bg_Coll) , 0 ) rightcheck = ImagesCollide(rightcollisionImage , X , Y , 0 , bg_Coll , level_offset , gfx_height - ImageHeight(bg_Coll) , 0 ) leftcheck = ImagesCollide(leftcollisionImage , X , Y , 0 , bg_Coll , level_offset , gfx_height - ImageHeight(bg_Coll) , 0 ) If footcheck = 0 fallspeed = fallspeed + .5 gravity:+fallspeed End If 'keep the player on top of the collision layer. Local ontop = 0 Local steps= 0 Repeat If ImagesCollide(footcollisionImage , X , Y , 0 , bg_Coll , level_offset , gfx_height - ImageHeight(bg_Coll) , 0 ) = 1 y:-.2 fallspeed = 0 steps:+1 Else ontop=1 End If If ImagesCollide(rightcollisionImage , X , Y , 0 , bg_Coll , level_offset , gfx_height - ImageHeight(bg_Coll) , 0 ) = 1 And state<>state_jump x:-.2 End If If ImagesCollide(leftcollisionImage , X , Y , 0 , bg_Coll , level_offset , gfx_height - ImageHeight(bg_Coll) , 0 ) = 1 And state<>state_jump x:+ .2 ''debugstop End If Until ontop=1 End Method Last edited 2011 |
| ||
| it's kind of hard to actually see what it's doing wrong from that bit of code. It can be a number of reason not having to do anything with the that code. it might be better if you can post an executable or even better the complete source code. |
| ||
| You should keep your collisions separate from your movement. Collisions are best used when the code returns true or false if there's a collision, makes it easier to debug and get working right. I can see in your code that you have If....EndIf..... and then do another ImagesCollide. But yet you have movement (y:-0.2) going on before another collision, so that will affect subsequent collision checks. Is this the way you want to do this? Probably not. Separate your functionality. One way I do this is by using a NEWPOSX, NEWPOSY variable, and setting the new player's position when all the collisions are done checking the old position. |
| ||
| yeah think I get what your saying, so call my update, do all the moveing by setting a newx newy, and then at the end in a new method/function do all collision checks and if there are any dont set the current x,y to the new x,y or am I getting something wrong ? God my memory is so bad Iv not touched code in years, taking my time getting back into things im sure iv made some other really stupid mistakes in the code so far I might just post the full source for some suggestions on how to clean it up. dont want to retain any old bad habbits.
'Black Night Test Code.
Strict
Framework brl.glmax2d
Import brl.freeaudioaudio
Import brl.linkedlist
Import brl.math
Import brl.random
Import brl.wavloader
Import brl.bmploader
Import brl.pngloader
Import brl.tgaloader
Import brl.jpgloader
Import brl.oggloader
SetGraphicsDriver GLMax2DDriver()
Global GFX_Width :Int = 1024
Global GFX_Height :Int = 768
Graphics GFX_Width,GFX_Height,0
Global bg_Sky:TImage = LoadImage ("sprite/level1/bground_sky.png")
Global bg_Back:TImage = LoadImage ("sprite/level1/Ground_back_3.png")
Global bg_Coll:TImage = LoadImage ("sprite/level1/ground_coll_3.png")
Global bg_Fore:TImage = LoadImage ("sprite/level1/ground_fore_3.png")
Global footcollisionImage:TImage = LoadImage ("sprite/footcollision.png")
Global leftcollisionImage:TImage = LoadImage ("sprite/leftcollision.png")
Global rightcollisionImage:TImage = LoadImage ("sprite/rightcollision.png")
Const State_Idle:Int = 1
Const State_run:Int = 2
Const State_attack:Int = 3
Const State_jump:Int = 4
Const State_kneel:Int = 5
Const Direction_left:Int = 1
Const Direction_right:Int = 2
Const Direction_up:Int = 2
Global level_offset:Int =0
Global map_push:Int = 350
Global CurrentLevel:Int = 1
Type level
Field x:Int
Field y:Int
Field name:String
Field skyimage:TImage
Field bgImage:TImage
Field colImage:TImage
Field foreImage:TImage
Field levelOffset:Int
Field segment:Int
Field totalsegments:Int
Field totalwidth:Int
Field mappush:Int
Field prevSeg:Int
Field nextSeg:Int
Field zorder:Int
Method New ()
name = "Level " + CurrentLevel
segment = 1
x = 0
'bgimage = LoadImage ("sprite/level" + currentlevel + "/ground_back_" + segment + ".png")
'colimage = LoadImage ("sprite/level" + currentlevel + "/ground_coll_" + segment + ".png")
'foreimage = LoadImage ("sprite/level" + currentlevel + "/ground_fore_" + segment + ".png")
'skyimage = LoadImage ("sprite/level" + currentlevel + "/bground_sky.png")
'y = gfx_height-ImageHeight(colimage)
End Method
Method loadlevel(newlevel:Int)
'do level loading here.
End Method
End Type
Global Levels:level = New level
levels.Loadlevel(CurrentLevel)
Type Player
Const RunRight_offset = 1
Const Runleft_offset = 0
Const idleRight_offset = 5
Const idleleft_offset = 4
Const attackRight_offset = 3
Const attackleft_offset = 2
Field x:Int
Field y:Int
Field oldx:Int
Field oldy:Int
Field runspeed:Float
Field direction:Int
Field image:TImage
Field image_run:TImage
Field image_idle:TImage
Field image_attack:TImage
Field frame:Int
Field framerate:Int = 100
Field frametime:Int = MilliSecs()
Field Gravity:Float = 5
Field state:Int=State_idle
Method Draw()
''debugstop
Select State
Case State_idle
Select direction
Case Direction_right
DrawImage image , X , Y , frame + (idleright_offset*7)
Case direction_left
DrawImage image , X , Y , frame + (idleleft_offset*7)
End Select
Case State_run
Select direction
Case Direction_right
DrawImage image , X , Y , frame + (runright_offset*7)
Case direction_left
DrawImage image , X , Y , frame + (runleft_offset*7)
End Select
Case State_jump
Select direction
Case Direction_right
DrawImage image , X , Y , frame + (runright_offset*7)
Case direction_left
DrawImage image , X , Y , frame + (runleft_offset*7)
End Select
Case State_attack
Select direction
Case Direction_right
DrawImage image , X , Y , frame + (attackright_offset*7)
Case direction_left
DrawImage image , X , Y , frame + (attackleft_offset*7)
End Select
Case State_kneel
Select direction
Case Direction_right
DrawImage image , X , Y , frame + (idleright_offset*7)
Case direction_left
DrawImage image , X , Y , frame + (idleleft_offset*7)
End Select
End Select
DrawImage footcollisionImage , X , Y
DrawImage leftcollisionImage , X , Y
DrawImage rightcollisionImage , X , Y
SetColor 255 , 255 , 255
Local data:String = "x ["+String.Fromfloat(x)+"] y ["+String.Fromfloat(y)+"]"
DrawText data , 1 , 1
DrawText "x = " + player1.x , 1 , 20
DrawText "frametime = " + frametime , 1 , 40
DrawText "framerate = " + framerate , 1 , 60
End Method
Method update()
oldy = y
oldx = x
y = y + gravity
collisions()
If MilliSecs() - framerate > frametime
If frame =< 5
frame = frame + 1
Else
frame = 0
End If
frametime = MilliSecs()
End If
If x > map_push Then x = map_push
If KeyHit(KEY_SPACE)
state = state_jump
End If
If state = state_jump
Select direction
Case direction_right
''debugstop
If x => map_push
level_offset:- runspeed
x = map_push
Else
x:+ runspeed
End If
Case direction_left
If x <= map_push And level_offset<0
level_offset:+ runspeed
x = map_push
Else
x:- runspeed
End If
Case direction_up
'
End Select
End If
If KeyDown(KEY_D) And state<>state_attack And state<>State_jump And state<>state_kneel
state = State_run
direction=Direction_right
If x => map_push
level_offset:- runspeed
x = map_push
Else
x:+ runspeed
End If
End If
If KeyDown(KEY_A) And state<>state_attack And state<>State_jump And state<>state_kneel
state = State_run
direction = Direction_left
If x <= map_push And level_offset<0
level_offset:+ runspeed
x = map_push
Else
x:- runspeed
End If
End If
If KeyDown(key_A) = 0 And KeyDown(key_d) = 0 And state<>State_attack And state<>state_jump And state<>state_kneel
'not moving so set state to idle
state = state_idle
End If
If MouseHit(1) And state <> state_attack And state <> state_kneel
state = state_attack
frame=0
DebugStop
End If
Select State
Case State_idle
player1.framerate=200
Case State_run
player1.framerate=100
Case State_attack
'debugstop
player1.framerate = 17
If frame => 6
state=state_idle
End If
Case state_kneel
player1.framerate = 1000
Default
framerate=100
End Select
If player1.framerate = 1000
Local g:Int =1
End If
End Method
Method Collisions()
'debugstop
If ImagesCollide(footcollisionImage , X , Y , 0 , bg_Coll , level_offset , gfx_height - ImageHeight(bg_Coll) , 0 ) = 0
End If
'keep the player on top of the collision layer.
Local ontop = 0
Repeat
If ImagesCollide(footcollisionImage , X , Y , 0 , bg_Coll , level_offset , gfx_height - ImageHeight(bg_Coll) , 0 ) = 1
y:-.2
Else
ontop:+ 1
If state <> state_attack
state = state_idle
Else
'
End If
End If
Until ontop => 1
End Method
Method New ()
frametime=MilliSecs()
framerate = 100
runspeed = 4
direction = Direction_left
state = state_run
image = LoadAnimImage("sprite/player.png" , 132 , 135 , 0 , 42)
x = 350
y = 600
End Method
End Type
Global Player1:player = New player
Repeat
Cls
update()
render()
Flip
Until KeyHit(KEY_ESCAPE) Or AppTerminate()
Function Update()
''debugstop
player1.update()
End Function
Function Render()
''debugstop
DrawImage bg_Sky , 0 , 0
DrawImage bg_Back , level_offset , gfx_height-ImageHeight(bg_back)
DrawImage bg_Coll , level_offset , gfx_height-ImageHeight(bg_Coll)
player1.draw()
DrawImage bg_Fore , level_offset , gfx_height-ImageHeight(bg_Fore)
End Function
|
| ||
| EDIT - think the above code might be a revision where i ripped out the jump code i had cos , well it sucked. Last edited 2011 |
