collision problems

BlitzPlus Forums/BlitzPlus Programming/collision problems

Bremer(Posted 2003) [#1]
Hi, On one of my many projects I'm having difficulties with collision detection. I have made it work great for vertical check but just can't seem to get further with the horizontal. Following is the current code. It's a scrolling platformer that moves from right to left. Any suggestions are very welcome.

[code]
Graphics 800,600,32,2

tileImg = LoadAnimImage("gfx\tiles.png",32,32,0,15)
playerImg = LoadImage("gfx\player.png")

playerX# = 200
playerY# = 32
playerZ# = -1
playerU# = 0

gravity# = .1
friction# = .98

offset = 0
scroll = 0

Dim playfield(100,2500,16)
Gosub loadlevel

SetBuffer BackBuffer()

While Not KeyHit(1)

;-----------------------------------------------------------------------------
; CHECK PLAYER CONTROLS
;-----------------------------------------------------------------------------

If chkkeys + 25 <= MilliSecs() Then
chkkeys = MilliSecs()
If KeyDown(203) Or JoyXDir()=-1 Then
playerU = playerU - .2 ;left
Left = 1
Else
Left = 0
End If
If KeyDown(205) Or JoyXDir()=1
playerU = playerU + .2 ;right
Right = 1
Else
Right = 0
End If
jy = Int(JoyY())
If jy = -1 Or KeyHit(57) Then playerZ = 5.5
End If

If mvscreen + 5 <= MilliSecs() Then
mvscreen = MilliSecs()
If offset > 0 And offset < 2475 Then
If Left = 1 Then scroll = scroll - 2
If Right = 1 Then scroll = scroll + 2
End If
If offset = 0 Then
If Right = 1 And scroll < 31 Then scroll = scroll + 2
End If
If offset = 2475 Then
If Left = 1 And scroll > 0 Then scroll = scroll - 2
End If
If offset < 0 Then offset = 0
If offset > 2475 Then offset = 2475
If scroll > 31 Then
scroll = scroll - 32
offset = offset + 1
End If
If scroll < 0 Then
scroll = scroll + 32
offset = offset - 1
End If
End If

playerU = playerU * friction
playerZ = playerZ - gravity

playerX = playerX + playerU
playerY = playerY - playerZ

;-----------------------------------------------------------------------------
; DRAW SCREEN AND CHECK FOR PLAYER COLLISION
;-----------------------------------------------------------------------------

nomove = 0

For x=0 To 25
For y=0 To 15
If playfield(level,offset+x,y) >0 Then
DrawImage tileImg,x*32-scroll,y*32,playfield(level,offset+x,y)
If ImagesCollide(tileImg,x*32-scroll,y*32,playfield(level,offset+x,y),playerImg,playerX,playerY,0) Then nomove = 1
End If
Next
Next

If nomove = 1 Then
; playerX = playerX - playerU
playerY = playerY + playerZ
; playerU = 0
playerZ = 0
End If

If playerY < 0 Then playerY = 0
If playerY > 480 Then playerY = 480
If playerX > 768 Then playerX = 768
If playerX < 0 Then playerX = 0

DrawImage playerImg,playerX,playerY

Flip
Cls

Wend

FreeImage titleImg
FreeImage playerImg

End

;-----------------------------------------------------------------------------
; LOAD LEVEL INTO ARRAY
;-----------------------------------------------------------------------------

.loadLevel
filein = ReadFile("gianasisters.lvl")
;For lv = 0 To 99
For x = 0 To 2499
For y = 0 To 15
playfield(lv,x,y) = ReadInt(filein)
Next
Next
;Next
CloseFile(filein)
Return
[\code]


Bremer(Posted 2003) [#2]
I still have problems with this, but the code has changed a little, but basically my problem consist of not being able to get it to check right for collision left and right but it works fine up and down. Does anyone know of any code somewhere that shows how to do a collision check for a sideways platform scroller that is set up with arrays?


Sunteam Software(Posted 2003) [#3]
What behaviour is currently happening? Walking through solid blocks? Getting stuck? This would really help.


joncom2000(Posted 2003) [#4]
filein = ReadFile("gianasisters.lvl")

Does this mean I have some competition?
I am working on a Gianasisters remake, you can download a preview version form the Blitzcoder website.

As for your little problem, I would suggest you take a look at some of the platform aware code which you can also find on the Blitzcoder site.


Bremer(Posted 2003) [#5]
Yes the image is going solid blocks but only left and right not up and down.

Well its not really Giana Sisters, but it basically the same concept. Its a horizontal scrolling platform game that are one screen high, which is just what Giana Sisters was.

GS is just the "codename" for the project until I see where its going and I find a title for it.


Who was John Galt?(Posted 2003) [#6]
Try uncommenting the line

; playerX = playerX - playerU

Not sure if this will make everything OK or not.
I know it's a pain in the B/S, but if you modify your code so it can be run without external files, people will be more likely to run it and come up with some feedback.

Cheers


Bremer(Posted 2003) [#7]
I've tried that and it doesn't work. I think that I'll start from scratch and rethink this whole thing. If anyone have any links to anything that would be of help as far as doing collision checks on a horizontal scroller with tiles as background let me know. For now I'm back in the thinking box.


Tiger(Posted 2003) [#8]
I don't know if this can be the problem, but you only reset player position when hiting a wall, what about scroll and offsets? they still counting.

Good luck.

Bye.


Tiger(Posted 2003) [#9]
Try this Main loop:
(This is not the best way do fix the problem)
I removed Gravity, the gravity pushes player down to the floor,and the floor trigger a collision.(Player stucks).
You must check if its a wall or floor that triggers the collision.


While Not KeyHit(1) 

;----------------------------------------------------------------------------- 
; CHECK PLAYER CONTROLS 
;----------------------------------------------------------------------------- 

If chkkeys + 25 <= MilliSecs() Then 
chkkeys = MilliSecs() 
If KeyDown(203) Or JoyXDir()=-1 Then 
playerU = playerU - .2 ;left 
Left = 1 
Else 
Left = 0 
End If 
If KeyDown(205) Or JoyXDir()=1 
playerU = playerU + .2 ;right 
Right = 1 
Else 
Right = 0 
End If 
jy = Int(JoyY()) 
If jy = -1 Or KeyHit(57) Then playerZ = 5.5 
End If

 
;Save Scroll value   
Savescroll=Scroll; <----------------------Save old scroll
SaveOffset=Offset

If mvscreen + 5 <= MilliSecs() Then 
mvscreen = MilliSecs() 
If offset > 0 And offset < 2475 Then 
If Left = 1 Then scroll = scroll - 2 
If Right = 1 Then scroll = scroll + 2 
End If 
If offset = 0 Then 
If Right = 1 And scroll < 31 Then scroll = scroll + 2 
End If 
If offset = 2475 Then 
If Left = 1 And scroll > 0 Then scroll = scroll - 2 
End If 
If offset < 0 Then offset = 0 
If offset > 2475 Then offset = 2475 
If scroll > 31 Then 
scroll = scroll - 32 
offset = offset + 1 
End If 
If scroll < 0 Then 
scroll = scroll + 32 
offset = offset - 1 
End If 
End If 

playerU = playerU * friction 
;playerZ = playerZ - gravity 

playerX = playerX + playerU 
playerY = playerY - playerZ 

;----------------------------------------------------------------------------- 
; DRAW SCREEN AND CHECK FOR PLAYER COLLISION 
;----------------------------------------------------------------------------- 

nomove = 0 

For x=0 To 25 
For y=0 To 15 
If playfield(level,offset+x,y) >0 Then 
;DrawImage tileImg,x*32-scroll,y*32,playfield(level,offset+x,y) 
If ImagesCollide(tileImg,x*32-scroll,y*32,playfield(level,offset+x,y),playerImg,playerX,playerY,0) Then nomove = 1 
End If 
Next 
Next 

If nomove = 1 
playerX = playerX - playerU 
playerY = playerY + playerZ 
playerU = 0 
playerZ = 0 
scroll=Savescroll
offset=Saveoffset
End If


For x=0 To 25 
For y=0 To 15 
If playfield(level,offset+x,y) >0 Then 
DrawImage tileImg,x*32-scroll,y*32,playfield(level,offset+x,y) 
End If 
Next 
Next  


If playerY < 0 Then playerY = 0 
If playerY > 480 Then playerY = 480 
If playerX > 768 Then playerX = 768 
If playerX < 0 Then playerX = 0 

DrawImage playerImg,playerX,playerY 

Flip 
Cls 

Wend 

FreeImage titleImg 
FreeImage playerImg 

End 


Bye.


Henrik(Posted 2003) [#10]
Hi try this great tileengine from the blitz2d samples
folder(i donīt know who coded this).
I have added a few lines of collisionscode
Bye Henrik
Const width=640,height=480
Const map_width=96,map_height=48

Global tiles
Dim map(map_width,map_height)

Graphics 640,480
SetBuffer BackBuffer()

CreateTiles()
CreateMap()
;stars=LoadImage( "graphics/stars.bmp" )
max_x=map_width*32-width
max_y=map_height*32-height

While Not KeyDown(1)

	If KeyDown( 203 )
		scroll_x=scroll_x-8:If scroll_x<0 Then scroll_x=0
	Else If KeyDown( 205 )
		scroll_x=scroll_x+8:If scroll_x>max_x Then scroll_x=max_x
	EndIf
	If KeyDown( 200 )
		scroll_y=scroll_y-8:If scroll_y<0 Then scroll_y=0
	Else If KeyDown( 208 )
		scroll_y=scroll_y+8:If scroll_y>max_y Then scroll_y=max_y
	EndIf
	
	Cls
	;TileBlock stars,-scroll_x/2,-scroll_y/2
	RenderMap( scroll_x,scroll_y )
	Color 200,0,0
	Text 220,200,"Move your mouse and scroll with arrows"
	Line MouseX(),MouseY()-10,MouseX(),MouseY()+10
	Line MouseX()-10,MouseY(),MouseX()+10,MouseY()
	If map(((MouseX()+scroll_x)/32),((MouseY())+scroll_y)/32)=0 Text 320,240,"collision"
	Flip
Wend

End

Function RenderMap( x_offset,y_offset )
	ty=y_offset/32
	sy=-(y_offset Mod 32)
	While sy<height
		ty=ty Mod map_height
		tx=x_offset/32
		sx=-(x_offset Mod 32)
		While sx<width
			DrawImage tiles,sx,sy,map( tx Mod map_width,ty )
			tx=tx+1:sx=sx+32
		Wend
		ty=ty+1:sy=sy+32
	Wend
End Function

Function CreateMap()
	Color 255,255,255
	Rect 0,0,map_width,map_height
	Color 0,0,0
	Rect 1,1,map_width-2,map_height-2
	Color 255,255,255
	Text map_width/2,map_height/4,"YEEEHHHAAA!",1,1
	Text map_width/2,map_height/2,"ALLRIGHTY!",1,1
	Text map_width/2,map_height*3/4,"TILEMAPDEMO",1,1
	For x=0 To map_width-1
		For y=0 To map_height-1
			GetColor x,y
			If ColorRed()>0 Then map(x,y)=0 Else map(x,y)=1
		Next
	Next
End Function

Function CreateTiles()
	tiles=CreateImage( 32,32,2 )
	
	Color 128,128,128
	Rect 0,0,32,32
	Color 192,192,192
	Rect 0,0,31,1:Rect 0,0,1,31
	Color 32,32,32
	Rect 31,1,1,31:Rect 1,31,31,1
	
	GrabImage tiles,0,0,0
	
	Color 0,0,0
	Rect 0,0,32,32
	For k=7 To 31 Step 16
		Color 192,192,192
		Rect k,0,1,32
		Color 32,32,32
		Rect k+1,0,1,32
	Next
	For k=7 To 31 Step 16
		Color 192,192,192
		Rect 0,k,32,1
		Color 32,32,32
		Rect 0,k+1,32,1
	Next
	
	GrabImage tiles,0,0,1
	
End Function



Who was John Galt?(Posted 2003) [#11]
Nice one, Henrik.

Another couple of ideas for you, Zarwan....

Using something like the above code, you can just think of your player's position in terms of x and y on a big (larger than screen) play area. Makes things a lot less melon twisting.

To keep your player centre, screen;

map\x=player\x-screenwidth/2
mapy\y=player\y-screenheight/2
origin 0,0
render_map(map\x,map\y)
origin -map\x,-map\y
draw your player and all the baddies at their x,y positions.

Now all the game objects scroll with the map for little effort. You could also write a function to test a graphic for a precise collision with the map. Function figures out which map blocks the graphic will overlap with (e.g: if graphic has same side length as map blocks, it will overlap max 4 blocks) then do the images collide bit.