Map size optimization in playbasic

Started by LemonWizard, June 20, 2011, 07:15:31 AM

Previous topic - Next topic

LemonWizard

Okayy.. I've run into a snag.


Fortunately I've been re reading over certain design aspects of things and WOW have I really learned alot over the last few years.

Problem:
Playbasic hangs or even crashes after I try to run it using my code. Which, attempts to draw maps that are larger than 100*100 using the camera, and scene buffer systems.


Question is..why?

from "Map_Set_UP"
PlayBASIC Code: [Select]
type tile
image
index
endtype

type BG_Layer
visible
collision_state
endtype


dim tiles(100) as tile

for temp=1 to 100
tiles(temp).image=newfximage(32, 32)
rendertoimage tiles(temp).image
color=rndrgb()
cls color
tiles(temp).index=temp
next temp
rendertoscreen



type Level_Map
BG_1 as BG_Layer
BG_2 as BG_Layer
BG_3 as BG_layer
endtype

dim my_map as Level_Map




dim my_map_layer1(50, 50)
dim my_map_layer2(50, 50)
dim my_map_layer3(50, 50)


function Initialize_Level_Map()
my_map.BG_1.visible=true
my_map.BG_2.visible=true
my_map.BG_3.visible=true
endfunction






function fill_level_layer(layer)
randomize timer()
for tempx=1 to 50
for tempy=1 to 50
select layer
case 1
my_map_layer1(tempx, tempy)=rnd(100)
setcursor tempx*20, tempy*20
print my_map_layer1(tempx, tempy)
case 2
my_map_layer2(tempx, tempy)=rnd(100)
case 3
my_map_layer3(tempx, tempY)=rnd(100)
endselect
next tempy
next tempx
sync
waitkey
waitnokey


endfunction



From: Map_Functions

PlayBASIC Code: [Select]
function draw_level_layer(layer)

for tempx=1 to 50
for tempy=1 to 50
select layer
case 1
t=my_map_layer1(tempx, tempy)
if t>0 and t<100 then drawimage tiles(t).image, (tempx-1)*32, (tempy-1)*32, 0
case 2
t=my_map_layer2(tempx, tempy)
if t>0 then drawimage tiles(t).image, (tempx-1)*32, (tempy-1)*32, 0
case 3
t=my_map_layer3(tempx, tempy)
if t>0 then drawimage tiles(t).image, (tempx-1)*32, (tempy-1)*32, 0
endselect
next tempy
next tempx
endfunction



From: Main

PlayBASIC Code: [Select]
openscreen 1024, 768, 32, 1

;initalize the map
layer=1
Initialize_Level_Map()

fill_level_layer(layer)
cls

rendertoscreen


;initalize the world

; Create WOrld
CreateWorld 1

; Tell PB to Capture ALL folloing GFX commands
; to this world buffer
CaptureToWorld 1


; Create camera
CreateCamera 1






;;;Base Code to build off of right here
; V*points down*V
; | |
; | |

; Start of DO/LOOP
Do
; Enable Capture to Scene Buffer
CaptureToScene

; Clear the scene buffer
ClsScene

;draw the map
draw_level_layer(layer)

; Transfer the data from the World buffer
; to the scene buffer
CameraGrabWorld 1,1

; Draw Camera #1
DrawCamera 1

;move camera

if rightkey()
x#=x#+5
endif

if leftkeY()
x#=X#-5
endif

if upkey()
y#=y#-5
endif

if downkey()
y#=y#+5
endif


positioncamera 1, X#, Y#


; Display the screen
Sync

; Loop back to the DO
Loop









Now.. let me explain.
When I resize all of those functions, so that my_map_layer1, 2, and 3 are of size(200, 200)
Change all the for /temp loops that are double nested to account for it, and then change the map drawing function as well.
It says it's timing out or not responding.
Another thing, it displays the map random numbers in text first, just press any key to get around that it may hang for a second.
It does on my system but then again I'm running something a bit dated right now :/

Anyways the problem is I can't expand the map size along with the draw function.
Essentially I want to draw 3 layers of map, each one being atleast 200 by 200 tiles.
You may wonder why on earth somone would need levels that big, but believe me I have my reasons (It's for testing, and for making sure that it has the capacity for larger user based levels after my remake of DKC2 is completed.
Namely because I plan to re use the game engine in question once it's finished.


So any help would be appreciated. Also please keep in mind I'm really new at this whole camera and scene business..

Also to anyone wondering:
The reason I'm NOT using playbasic's map system is because it doesn't have transparent collision detection for tiles that are parted.
Say, 1/3 of the tile is a slope. And it uses transparency to detect non solid areas of a tile. Playbasic's map system doesn't seem to have anything that would do that. So, I'm coding my own. But.. this method is really slow.
I'm open to any alternatives. Just please bear in mind I'm trying to separate the low level stuff, to my functions and objects so I can keep everything organized.
When I ran into a mistake with the array code originally, I found when I modified the function, I didn't even have to change my main code at all. I didn't TOUCH main. It was the first time that ever happened to me. I was ecstatic.



kevin

#1
QuotePlaybasic hangs or even crashes after I try to run it using my code. Which, attempts to draw maps that are larger than 100*100 using the camera, and scene buffer systems.

 The scene buffer has probably overflowed..  You'll need it make it big enough to hold whatever is being thrown into it.. For that see->SceneCacheSize


 Some of the code needs cleaning up.. The map drawing routine for example shouldn't have any redundant decisions or operations inside the inner loop,  It's simply a waste of time..
PlayBASIC Code: [Select]
function draw_level_layer(layer)
for tempx=1 to 50
for tempy=1 to 50
select layer
case 1
t=my_map_layer1(tempx, tempy)
if t>0 and t<100 then drawimage tiles(t).image, (tempx-1)*32, (tempy-1)*32, 0
case 2
t=my_map_layer2(tempx, tempy)
if t>0 then drawimage tiles(t).image, (tempx-1)*32, (tempy-1)*32, 0
case 3
t=my_map_layer3(tempx, tempy)
if t>0 then drawimage tiles(t).image, (tempx-1)*32, (tempy-1)*32, 0
endselect

next tempy
next tempx
endfunction




  You can get rid of most of the overhead by splitting the routine into a caller, that passes a lower level function the map array.


PlayBASIC Code: [Select]
   tempx=50
tempy=50
Dim my_map_layer1(tempx, tempy)
Dim my_map_layer2(tempx, tempy)
Dim my_map_layer3(tempx, tempy)


Psub draw_level_layer(layer)
select layer
case 1
draw_level_layer_Array(my_map_layer1())
case 2
draw_level_layer_Array(my_map_layer2())
case 3
draw_level_layer_Array(my_map_layer3())
endselect
endPsub



Function draw_level_layer_Array(Map())
for tempy=1 to GetArrayElements(Map(),2)
Ypos=(tempy-1)*32
for tempx=1 to GetArrayElements(Map(),1)
t=map(tempx, tempy)
if t>0 and t<100 then drawimage tiles(t).image, (tempx-1)*32,ypos , 0
next tempx
next tempy
endfunction



  The problem is,such custom solutions just emulates what maps already do, but slower.



QuoteThe reason I'm NOT using playbasic's map system is because it doesn't have transparent collision detection for tiles that are parted.Say, 1/3 of the tile is a slope. And it uses transparency to detect non solid areas of a tile. Playbasic's map system doesn't seem to have anything that would do that. So, I'm coding my own. But.. this method is really slow.

 There's a dozen methods built into  PlayBasic V1.64M as well as number of examples on the source code boards.  

 But you're meant to use vector world collision.. as per examples like the  advanced platformer collision