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. |