Help with optimisation needed
Blitz3D Forums/Blitz3D Programming/Help with optimisation needed
| ||
Got some trouble with Trouble! Anyone who has played my puzzle game would notice some slowdown whenever large numbers of conveyor belts are used in a map. This is because currently I'm checking every conveyor against every moveable block every loop. What I'd like is to be able to optimise this so I get the same effect without killing off too many clock cycles. Here's the code. Function MoveBlocks() For p.pushblok = Each pushblok If Not p\locked If p\moving And p\movcnt > 0 Select p\dir Case dirNorth nx = p\x ny = p\y - 4 Case dirSouth nx = p\x ny = p\y + 4 Case dirEast nx = p\x + 4 ny = p\y Case dirWest nx = p\x - 4 ny = p\y End Select Else nx = p\x ny = p\y p\moving = False p\movcnt = 0 EndIf Select CheckBColl( p, nx, ny ) Case collision p\moving = False p\movcnt = 0 Case destroy Delete p Case conveyor p\x = nx p\y = ny p\movcnt = 32 Case reset Return Default p\x = nx p\y = ny p\movcnt = p\movcnt - 4 If p\tpe = 5 And p\movcnt = 0 p\movcnt = 32 EndIf End Select EndIf Next End Function Function CheckBColl(p.pushblok, x, y) If ImagesOverlap(pushgfx, x, y, Cchr, p1\x, p1\y+15) Select p\dir Case dirNorth If CheckPColl(p1\x, p1\y - 4) If version$ = "1.4" LoadMap "maps\puzzle" + cur_map + ".puz" Else LoadMap "maps\map" + cur_map + ".puz" EndIf nodoor = False Return reset Else p1\y = p1\y - 4 EndIf Case dirSouth If CheckPColl(p1\x, p1\y + 4) If version$ = "1.4" LoadMap "maps\puzzle" + cur_map + ".puz" Else LoadMap "maps\map" + cur_map + ".puz" EndIf nodoor = False Return reset Else p1\y = p1\y + 4 EndIf Case dirEast If CheckPColl(p1\x + 4, p1\y) If version$ = "1.4" LoadMap "maps\puzzle" + cur_map + ".puz" Else LoadMap "maps\map" + cur_map + ".puz" EndIf nodoor = False Return reset Else p1\x = p1\x + 4 EndIf Case dirWest If CheckPColl(p1\x - 4, p1\y) If version$ = "1.4" LoadMap "maps\puzzle" + cur_map + ".puz" Else LoadMap "maps\map" + cur_map + ".puz" EndIf nodoor = False Return reset Else p1\x = p1\x - 4 EndIf End Select EndIf For b.pushblok = Each pushblok If b <> p If ImagesOverlap(pushgfx, b\x, b\y, pushgfx, x, y) Return collision EndIf EndIf Next For pn.panel = Each panel If ImagesOverlap(pushgfx, x, y, tiles, pn\x, pn\y) If Between(x - pn\x, -6, 6) And Between(y - pn\y, -6, 6) If pn\tpe = p\tpe p\locked = True p\x = pn\x p\y = pn\y pn\active = True Return True EndIf EndIf EndIf Next For s.specialzone = Each specialzone If ImagesOverlap(pushgfx, x, y, special, s\x, s\y) Select s\tpe Case spHole, spHole2 If Between( x - s\x, -12, 12 ) And Between( y - s\y, -12, 12 ) an.animfx = New animfx an\x = s\x an\y = s\y an\clr = p\tpe an\tpe = animFall Return destroy EndIf Case spIce If p\tpe = 6 If between( x - s\x, -16, 16 ) And between( y - s\y, -16, 16) Delete s EndIf Else If x = s\x And y = s\y p\movcnt = p\movcnt + 32 EndIf EndIf Case spHeat If p\tpe = 5 If Between( x - s\x, -16, 16 ) And Between( y - s\y, -16, 16 ) DeleteSmoke( s\ID ) Delete s EndIf EndIf Case spConv If x = s\x And y = s\y p\moving = True p\dir = s\dir Return conveyor EndIf End Select EndIf Next For d.doorway = Each doorway If d\reset = 0 If ImagesOverlap(pushgfx, x, y, door, d\x, d\y) If Between( x - d\x, -6, 6 ) And Between( y - d\y, -6, 6 ) If d\anim = 0 p\locked = True d\anim = danimDrop p\x = d\x p\y = d\y Return collision EndIf EndIf EndIf EndIf Next End FunctionThanks in advance guys. |
| ||
Well not sure of the ins and outs of your game, but is one conveyor made of a single graphic or a line of tile blocks? If the answer is the latter you could write your own routine to test if two rectangles overlap, and you would only need a single collision check between each movable object and each straight segment of conveyor. If it's the latter, then you could only check for collisions if the object moved in the last game loop. If neither, sorry I don't have any ideas. |
| ||
If it's the latter, then you could only check for collisions if the object moved in the last game loop Hmm... the trouble I have is that when blocks are pushed against each other, blocking the path for example, I want the player to be able to push one block and have the others continue along the conveyor so this method will not work (as the block was stationary).I suppose I *could* store the information of which blocks are on which conveyor and only update those which have blocks on them to save a few frames, but it still requires me to cycle through each of the special tiles multiple times. |