Tiled data maps & collision
Blitz3D Forums/Blitz3D Beginners Area/Tiled data maps & collision
| ||
| Wotcha, folks. I've always been jealous of this piece of code, created by a user called Nebula (or something). ; Graphics 640,480,16,2 SetBuffer BackBuffer() Dim map(15,10) Type player Field x,y Field fall,jump Field fallspeed# End Type Global p.player = New player readlevel(1) While KeyDown(1) = False Cls If MouseDown(1) = True Then p\x = MouseX() p\y = MouseY() EndIf drawlevel drawplayer moveplayer world gravity Text 0,0,playermapcollision(0,0) Flip Wend End Function world() If playerspringcollision() = True Then p\fallspeed = -5 : p\fall = True : p\jump = True EndIf End Function Function playerspringcollision() px = (p\x+8)/32 py = p\y/32 If map(px,py) = 2 Then Return True End Function Function moveplayer() If KeyDown(205) = True Then If playermapcollision(1,0) = False Then p\x = p\x + 1 End If End If If KeyDown(203) = True Then If playermapcollision(-1,0) = False Then p\x = p\x - 1 End If End If If KeyDown(57) = True Then If p\jump = False Then p\jump = True p\fallspeed = -3 p\fall = True End If End If End Function Function gravity() ; ; If playermapcollision(0,p\fallspeed) = True And p\jump = True Then p\fallspeed = 0 p\y = p\y/32*32 End If ; If playermapcollision(0,1) = False And p\fall = False p\fall = True p\fallspeed = 1 End If ; If p\fall = True Then p\y = p\y + p\fallspeed p\fallspeed = p\fallspeed + .1 For i=0 To p\fallspeed If playermapcollision(0,i) = True Then p\y = p\y+i/32*32 p\fall = False p\jump = False Exit End If Next End If End Function Function playermapcollision(x1,y1) px = (p\x+x1) / 32 py = (p\y+y1) / 32 For x=-1 To 1 For y=-1 To 1 If RectsOverlap(px+x,py+y,1,1,0,0,15,10) = True Then Rect px*32+x*32,py*32+y*32,32,32,False If map(px+x,py+y) = 1 Then If RectsOverlap(p\x+x1,p\y+y1,16,16,px*32+x*32,py*32+y*32,32,32) = True Then Return True End If EndIf Next:Next If RectsOverlap(p\x+x1,p\y+y1,16,16,15,15,14*32,9*32) = False Then Return True End If End Function Function drawplayer() Color 255,255,0 Oval p\x,p\y,16,16,True End Function Function drawlevel() For x=0 To 15-1 For y=0 To 10-1 Select map(x,y) Case 1 Color 255,255,255:Rect x*32,y*32,32,32,True Case 2 Color 255,0,0 : Rect x*32,y*32+32-8,32,8,True End Select Next:Next End Function Function readlevel(level) Select level Case 1 Restore level1 End Select For y=0 To 10-1 For x=0 To 15-1 Read a map(x,y) = a Next:Next End Function .level1 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1 Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,2,0,0,0,0,0,0,0,0,0 Data 0,0,1,1,1,1,1,0,0,0,0,0,0,0,0 Data 0,0,0,0,0,0,0,2,0,0,0,0,0,0,0 Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 Try as I might, I've never really been able to get my head around his playermapcollision() function. Which is a shame as his routine seems so neat and effective. I understand that it checks the map data array 1 position all around the player, and that this is then used to check the rectsoverlap of actual blocks and the player .....but I'm just not quite there. Here's my code: Graphics 640,480,32,2
SetBuffer BackBuffer()
Dim map(9,9)
Global px=20
Global py=20
Global gpx=0
Global gpy=0
Global cgpx=False
Global cgpy=False
readmap()
; main loop
While Not KeyHit(1)
Cls
drawmap()
drawstats()
moveplayer()
drawplayer()
playermapcollision(0,0)
Flip
Wend
End
;*************
;* *
;* FUNCTIONS *
;* *
;*************
; PlayerMapCollision
Function playermapcollision(x1,y1)
goffx=x1
goffy=y1
For x=-1 To 1
For y=-1 To 1
Color 0,255,0
Rect (px/20)*20+(x*20),(py/20)*20+(y*20),20,20,False
Text 310+(x*10),140+(y*10),map(gpx+x,gpy+y)
Text 300,190,"X1: "+goffx+" Y1: "+goffy
If map(gpx+goffx,gpy+goffy)=1 Then Text 300,210,"Block coming up"
Color 255,255,255
Next
Next
End Function
; DrawStats
Function drawstats()
Text 300,10,"PX: "+px+" PY: "+py
gpx=px/20
gpy=py/20
Text 300,30,"Grid X: "+gpx+" Grid Y:"+gpy
Text 300,50,"Surround: "+(px/20)*20+","+(py/20)*20
Text 300,70,"Map ref: "+map(gpx,gpy)
Text 300,90,map(gpx-1,gpy-1)+" "+map(gpx,gpy-1)+" "+map(gpx+1,gpy-1)
Text 300,100,map(gpx-1,gpy)+" "+map(gpx,gpy)+" "+map(gpx+1,gpy)
Text 300,110,map(gpx-1,gpy+1)+" "+map(gpx,gpy+1)+" "+map(gpx+1,gpy+1)
End Function
; Move Player
Function moveplayer()
Local ox=px,oy=py
If KeyDown(205) Then
If playermapcollision(1,0) = False
px=px+1
End If
End If
If KeyDown(203) Then
If playermapcollision(-1,0) = False
px=px-1
End If
End If
If KeyDown(200) Then
If playermapcollision(0,-1) = False
py=py-1
End If
End If
If KeyDown(208) Then
If playermapcollision(0,1) = False
py=py+1
End If
End If
If px<20 Then px=ox
If px>160 Then px=ox
If py<20 Then py=oy
If py>160 Then py=oy
End Function
; Draw Player
Function drawplayer()
Color 255,255,0
Rect px,py,20,20,True
Color 255,255,255
End Function
; Read Map
Function readmap()
For y=0 To 9
For x=0 To 9
Read a
map(x,y)=a
Next
Next
End Function
.level1
Data 1,1,1,1,1,1,1,1,1,1
Data 1,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,1,0,1,0,1
Data 1,0,0,1,1,1,0,1,0,1
Data 1,0,0,1,0,0,0,0,0,1
Data 1,0,0,0,0,1,1,0,0,1
Data 1,0,0,0,0,0,1,0,0,1
Data 1,0,1,1,1,1,1,1,0,1
Data 1,0,0,0,0,0,0,0,0,1
Data 1,1,1,1,1,1,1,1,1,1
; Draw map
Function drawmap()
Color 0,0,255
For x=0 To 9
For y=0 To 9
If map(x,y)=1 Then Rect x*20,y*20,20,20,True
Line 0,y*20,200,y*20
Line x*20,0,x*20,200
Next
Next
Color 255,255,255
End Function
What's the method of restricting player movement when you come up against walls? .........you can tell I'm having problems - I can't even explain it well! Any help much appreciated. Tobo. |
| ||
Ooh ooh - I may be getting there.........Graphics 640,480,32,2 SetBuffer BackBuffer() Dim map(19,19) Global px=20 Global py=20 Global gpx,gpy readmap() While Not KeyHit(1) Cls drawmap() checkmove() drawplayer() drawsurround() showstats() Flip Wend End ; FUNCTIONS ; Draw Surround Function drawsurround() For x=-1 To 1 For y=-1 To 1 If map(gpx+x,gpy+y)=1 Color 255,255,0 Rect ((px/20)*20)+x*20,((py/20)*20)+y*20,20,20,False Color 255,255,255 End If Next Next End Function ; Show Stats Function showstats() Text 430,10,"Grid Ref: "+gpx+","+gpy Text 430,30,map(gpx-1,gpy-1)+" "+map(gpx,gpy-1)+" "+map(gpx+1,gpy-1) Text 430,40,map(gpx-1,gpy)+" "+map(gpx,gpy)+" "+map(gpx+1,gpy) Text 430,50,map(gpx-1,gpy+1)+" "+map(gpx,gpy+1)+" "+map(gpx+1,gpy+1) End Function ; Check Move Function checkmove() ox=px oy=py If KeyDown(205) px=px+2 End If If KeyDown(203) px=px-2 End If If KeyDown(200) py=py-2 End If If KeyDown(208) py=py+2 End If If px>360 Or px<20 Then px=ox If py>360 Or py<20 Then py=oy gpx=px/20 gpy=py/20 End Function ; Draw Player Function drawplayer() Rect px,py,20,20 End Function ; Draw Map Function drawmap() For ac=0 To 19 For dn=0 To 19 Color 0,0,255 If map(ac,dn)=1 Then Rect ac*20,dn*20,20,20 Color 0,255,0 Line ac*20,0,ac*20,400 Line 0,dn*20,400,dn*20 Color 255,255,255 Next Next End Function ; Read Map Function readmap() Restore level1 For dn=0 To 19 For ac=0 To 19 Read a map(ac,dn)=a Next Next End Function .level1 Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1 Data 1,0,0,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1 Data 1,0,0,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1 Data 1,0,0,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1 Data 1,0,0,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 |
| ||
| Okay - I'm officially happy now. SORTED ! Graphics 640,480,32,2 SetBuffer BackBuffer() Dim map(19,19) Global px=20 Global py=20 Global gpx,gpy readmap() While Not KeyHit(1) Cls drawmap() checkmove() drawplayer() showstats() Flip Wend End ; FUNCTIONS ; Player Map Collision Function playermapcollision() For x=-1 To 1 For y=-1 To 1 If map(gpx+x,gpy+y)=1 If RectsOverlap (px,py,20,20,((px/20)*20)+x*20,((py/20)*20)+y*20,20,20) Then Return True End If Next Next End Function ; Show Stats Function showstats() Text 430,10,"Grid Ref: "+gpx+","+gpy Text 430,30,map(gpx-1,gpy-1)+" "+map(gpx,gpy-1)+" "+map(gpx+1,gpy-1) Text 430,40,map(gpx-1,gpy)+" "+map(gpx,gpy)+" "+map(gpx+1,gpy) Text 430,50,map(gpx-1,gpy+1)+" "+map(gpx,gpy+1)+" "+map(gpx+1,gpy+1) End Function ; Check Move Function checkmove() ox=px oy=py If KeyDown(205) px=px+2 End If If KeyDown(203) px=px-2 End If If KeyDown(200) py=py-2 End If If KeyDown(208) py=py+2 End If If px>360 Or px<20 Then px=ox If py>360 Or py<20 Then py=oy gpx=px/20 gpy=py/20 If playermapcollision() = True Then px=ox:py=oy End Function ; Draw Player Function drawplayer() Rect px,py,20,20 End Function ; Draw Map Function drawmap() For ac=0 To 19 For dn=0 To 19 Color 0,0,255 If map(ac,dn)=1 Then Rect ac*20,dn*20,20,20 Color 0,255,0 Line ac*20,0,ac*20,400 Line 0,dn*20,400,dn*20 Color 255,255,255 Next Next End Function ; Read Map Function readmap() Restore level1 For dn=0 To 19 For ac=0 To 19 Read a map(ac,dn)=a Next Next End Function .level1 Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1 Data 1,0,0,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1 Data 1,0,0,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1 Data 1,0,0,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1 Data 1,0,0,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 If anyone can explain why in Nebula's code he had to pass variables to his playermapcollision() function, I'd love to know. Sorry for the mega post. Tobo. |
| ||
| Forgot to say... A very big thankyou to Nebula. Your damn piece of code has annoyed and encouraged me for the last 8 months. Now, can anyone tell me how to go from the above, to Half-Life2? |
| ||
| Good work, tobo :) glad you've solved it. |