Tiles and collision
Blitz3D Forums/Blitz3D Beginners Area/Tiles and collision
| ||
Hi, I'm currently working on a clone of mega bomberman, and i have got the basic scene to display, but i dont have a clue on how to apply collision to certain tiles and not on others. i'm using the data command to layout the scene, and i need certain values used in the data command to have collision applied. please can someone help. thanks. p.s. please say if this does not make any sense. |
| ||
Have you looked at the alien breed threads? Take a look at the first ever thread that's got basic tile collision, an editor, and other stuff that may interest you. This was the whole point of the alien breed project to help people learn. |
| ||
I have looked at the alien breed threads, but doesn't seem to help me with my project, abit confusing really to be honest. I think my problem is that i'm not used to other peoples coding methods, which doesn't really help me. i've added the page to my favorites for future reference but i need a get my own understanding of this stuff first if you see what i mean. |
| ||
Dont use the display to detect collisions, build an array that matches the tiles on screen and move the player around the array; you just check the array cell you want to move into and if its a tile that blocks you then you dont move. |
| ||
There are many ways to achieve what you want. As mentioned you could use arrays to store extra information about each tile. You could also use Types or Arrays of Types to store extra information. Or you could simply use some kind of simple coding scheme in your Data statements. Say for example that all of your tiles are enumerated from 0-37. You know that you will never use more than 64 tiles, so you can set flags for certain tiles by adding the number 64 to any tile (ex. A number 5 tile would equal 69). You can check if the tile is collidable by doing either If tile > 63 col_tile = True ;tile is collidable, so note that tile = tile - 64 ;now tile equals what it really is EndIfor col_tile = (tile AND $40) Shr 6 ;col_tile now equals a 0 or 1 tile = tile - 64If you need to add more bits of information to your tiles, you can use other 'multiples of 2' numbers like 128, 256, 512, etc. and compare those with $80, $100, and $200 respectively. energy_tile = (tile AND $200) Shr 9 ;energy_tile now equals a 0 or 1 tile = tile - 512 Alternatively, you could leave tile to equal what it is (don't subtract the 64 or 512 part) and just do a compare like the following when you want to check what type of tile it is. This will only return the value below 64. tiletype = (tile AND $3F) |
| ||
sorry for taking so long to post back, i sort of know what to do now, but not really in the coding sense, are there any simple examples of tile maps and collision with a player. just need some example to study to learn which doesn't have to much coding. please help if possible. thanks |
| ||
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 |
| ||
Henrik, thanks for the example, i still varies from my code alot though. here is my coding so far: AppTitle "Mega Bomberman Clone v0.0 - Test 1","Do you wish to return to your desktop?" Graphics 640,510,32,2 SetBuffer BackBuffer() Global Tiles Dim Map(16,16) Load_Map() While Not KeyHit(1) Cls Update() Flip Wend End Function Load_Map() Restore Map For y=000 To 16 For x=000 To 16 Read Map(x,y) Next Next tiles =LoadAnimImage("TileMap.png",29,29,0,13) End Function Function Update() For y= 000 To 16 For x= 000 To 16 DrawImage tiles,x*30,y*30,map(x,y) Next Next End Function .map Data 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 Dunno how collision fits into this sort of thing. hope somebody can help. |
| ||
Maybe you can use this Bye Henrik AppTitle "Mega Bomberman Clone v0.0 - Test 1","Do you wish to return to your desktop?" Graphics 640,510,32,2 SetBuffer BackBuffer() Global Tiles Dim Map(16,16) Load_Map() While Not KeyHit(1) Cls Update() collisiontest() Flip Wend End Function collisiontest() testnumber=4;or 12 or 0 or whatever tile you would like to test!!! If MouseX()<30*17 And MouseY()<30*17 Then;donīt test if your mouse is outside your mapsize (30*17) Color 200,0,0 Text 220,200,"Move your mouse" Line MouseX(),MouseY()-10,MouseX(),MouseY()+10 Line MouseX()-10,MouseY(),MouseX()+10,MouseY() If Map(MouseX()/30,MouseY()/30)=testnumber Text 180,240," Collision with tile nr:"+testnumber EndIf End Function Function Load_Map() Restore Map For y=000 To 16 For x=000 To 16 Read Map(x,y) Next Next tiles =LoadAnimImage("TileMap.png",29,29,0,13) End Function Function Update() For y= 000 To 16 For x= 000 To 16 DrawImage tiles,x*30,y*30,map(x,y) Next Next End Function .map Data 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 |
| ||
Cool, works well, thanks for all the help :), i shouldn't be back for a while know :), thanks again, bye. |
| ||
Ok, i thought i wouldn't be back for a while, well, i tried to apply collision so the mouse stoped when it hit a tile but doesn't work can someone tell me what i am doing wrong. i suck at 2d programing. Here is my code: AppTitle "Mega Bomberman Clone v0.0 - Test 1","Do you wish to return to your desktop?" Graphics 640,510,32,2 SetBuffer BackBuffer() Global Tiles Dim Map(16,16) Load_Map() While Not KeyHit(1) Cls Update() collisiontest() Flip Wend End Function collisiontest() OldX=MouseX() Oldy=MouseY() testnumber=0;or 12 or 0 or whatever tile you would like to test!!! If MouseX()<30*17 And MouseY()<30*17 Then;donīt test if your mouse is outside your mapsize (30*17) Color 200,0,0 Text 220,200,"Move your mouse" Line MouseX(),MouseY()-10,MouseX(),MouseY()+10 Line MouseX()-10,MouseY(),MouseX()+10,MouseY() If Map(MouseX()/30,MouseY()/30)=testnumber Text 180,240," Collision with tile nr:"+testnumber If RectsOverlap(MouseX()-10,MouseY()-10,MouseX()+10,MouseY()+10,Map(x,y)=0,Map(x,y)=0,Map(x,y)=29,Map(x,y)=29) Then MouseX=OldX MouseY=OldY EndIf EndIf End Function Function Load_Map() Restore Map For y=000 To 16 For x=000 To 16 Read Map(x,y) Next Next tiles =LoadAnimImage("TileMap.png",29,29,0,13) End Function Function Update() For y= 000 To 16 For x= 000 To 16 DrawImage tiles,x*30,y*30,map(x,y) Next Next End Function .map Data 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12,4 Data 4,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,4 Data 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 |
| ||
Hi I found another great example of tile collision/slideing on my harddisk i think you can use. It is made by "Norc" (i think he use another nickname now) Bye Henrik ;Demonstration of very simple Non-Image-Collision-based "Wall-Detection" Graphics 640,480,16;,2 nux#=0 oldx#=0 oldy#=0 x#=100 y#=100 a#=0 Dim tiles(15,15) ; Read the Wall information For j=0 To 15 For i=0 To 15 Read tiles(i,j) Next Next ; MAINLOOP While KeyHit(1)=0 Cls For j=0 To 15 ; draw all walls for test purposes For i=0 To 15 ; use your favorite Picture instead If tiles(i,j)=1 Then Color 120,120,120 Rect i*40,j*30,40,30,0 EndIf Next Next oldx=x ; remember old player pos oldy=y ; Keys If KeyDown(200)=1 ; fwd x=x+Sin(a) y=y+Cos(a) EndIf If KeyDown(208)=1 ; back x=x-Sin(a) y=y-Cos(a) EndIf If KeyDown(203)=1 ; Player angle < a=a+2 If a> 360 Then a=a-360 EndIf If KeyDown(205)=1 ; Player angle > a=a-2 If a< 0 Then a=a+360 EndIf ; dont allow walking tru walls, but allow sliding along If tiles(((x-20)/40),((y-15)/30))=1 Then ; try new x, new y nux#=x ; remeber nu x x=oldx ; reset x to old x EndIf If tiles(((x-20)/40),((y-15)/30))=1 Then ; try old x, new y x=nux# y=oldy EndIf If tiles(((x-20)/40),((y-15)/30))=1 Then ; try new x, old y x=oldx ; no, no chance, reset x and y both to old pos y=oldy EndIf Color 255,0,0 ; Show a graphical Player Oval x-5,y-5,10,10,1 Color 255,255,255 ; show also wich direction Player is facing Line x+Sin(a)*10,y+Cos(a)*10,x-Sin(a)*10,y-Cos(a)*10 Flip Wend End ; Walls = "1", Air = "0" ; you can also use bigger levels - just keep ; the relation (ie. 640/16=40) to check the Collision Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 Data 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 Data 1,1,0,1,1,1,1,1,0,1,1,1,1,0,1,1 Data 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,1,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 |
| ||
Ok, that should help me alot, thanks for the help :). |
| ||
Hi again :(, I have just been doing more coding and got the player to move and such, and tried to apply collision to the scene, i know sort of what i am suposed to do thanks to Henrik's coding sample, the only problem is i'm completly new to 2d programing and i'm not good at array programing, in other words i'm a crap programer at present. i know this is asking alot in the eyes of some people, but i was wandering if there was anyone here who is really good with 2d programing in blitz3d and has some free time available, if i could send my code via email to be checks and then get help on where i'm going wrong, please. sorry if i'm being really annoying. thanks. |
| ||
I haven't spent too much time looking (as I'm about to go to bed), but noticed one big flaw in your code.MouseX=OldX MouseY=OldYFirst of all, these would need to be MouseX() and MouseY() but even then, it wouldn't work. MouseX() and MouseY() are read-only functions. You can't use them to position the cursor. Instead, replace those two lines with: MoveMouse OldX,OldYRather than trying to re-write your entire program each time you have a new idea, keep working on your program as it is until it WORKS. :) This is called bug-hunting. Yes, its a long process and can be very frustrating, but you'll learn a lot more in the process for next time. If you start again however, you'll have a whole new set of bugs. Unless you're a very professional programmer, you'll always run into bugs in any program over a few lines. So, add in extra lines to print the results of your equations to the screen, etc, to see if they're working the way you mean them to. Note: we can't actually run this code without the tilemap.png file. Sure someone like sswift or halo could come along, read all your code, and find exactly what mistake you're making and tell you how to fix it, but they won't necessarily be there the next time theres a bug, or the time after, or the time after that. :) Anyway, I fixed one bug for you. ;) Keep working at it till you eliminate them all! :) +BlackD [EDIT: PS - I recommend going to the Blitz manual (download the latest documentation update too!) and clicking on 2D - Category, then going through one by one and reading up on what EVERY instruction does. You're not expected to remember them all right away, but some time later you'll remember "hey - wasn't there a command to move the mouse?" (or whatever) and look it up. The categories to concentrate on first are BASIC, INPUT, GRAPHICS and IMAGES. You NEED to know pretty much all the commands in those categories by heart, to write even a beginners 2D game.) |
| ||
Thanks for the tip BlackD, the only main problem i'm having is know where the errors are. i took your advise on adding lines for code to print the results but where ever i place it i get some kind of error like : array index out of range or variable must be a type ??? the code i put in is: If Map(player\x,player\y)=0 Then Text 0,0,"Player has collided with the scene!" i placed it in the update_player function which give me the first message i quoted and also in the main loop of the program which give the seconds error, i haven't placed the code in the two places at once. and i dunno where the code has gone wrong. |