Global variables are Empty.. Why?
BlitzMax Forums/BlitzMax Beginners Area/Global variables are Empty.. Why?
| ||
Hello! When i try loading images into Global Variables at start of the code, they appear empty in runtime. When i load them in the function theyre called from theyre ok and showing pictures.. I even tried to recreate that situation in an empty .BB File, but there the Problem wont show up and loading them into global variables is ok and functioning, even with copy&paste code I cannot load the Pictures in The function because the function is called too often (like 60fps ; ) and so the game crashes after 10 seconds or something like that |
| ||
Here is my code: Look ad B1-B11 (Loadimage...) Stuff in DrawBlock() if i put it at the beginning of my code, with GLOBAL in Front theyre empty, showing error message "Picture not found". Now where they are theyre ok. What can i do to load them like they are before the draw() command, once for the whole runtime? Global wnd%=2 Global GraphicsMode#=2 Global posx=400 Global posy=1 Global tmp_select=True Global randblockselect Global level=400 SeedRnd(MilliSecs()) SetBuffer BackBuffer () fpstimer= CreateTimer(60) SetGraphicsMode() ; begin core Repeat ; [1] Fallback timer=MilliSecs() posy=posy+40 Select True ; Check wether Blok has Reached the End of Screen, then sets it back and generates another Case unten=True randblockselect=Rand(1,11) unten=False posy=1 Case posy > 600 unten=True End Select; Repeat ; Changes X Coordinate of block, Draws actual block, ends after LEVEL second If KeyHit(203) posx=posx-40 Else If KeyHit(205) posx=posx+40 End If DrawBlock() ;Draws one Random generated Block until it reaches end of y (Posy 600 for practicing) WaitTimer(fpstimer); 60FPS thing Flip(0):Cls Until MilliSecs() >= timer+level ; Timer allows blocks being moved for LEVEL seconds, then [ Fallback [1] ] and start over pos y+40 Until KeyHit(1) ; END OF MAIN CODE Function DrawBlock() B1=LoadImage("fropf_l_1.png") B2=LoadImage("fropf_l_2.png") B3=LoadImage("fropf_l_3.png") B4=LoadImage("fropf_l_4.png") B5=LoadImage("fropf_r_1.png") B6=LoadImage("fropf_r_2.png") B7=LoadImage("fropf_r_3.png") B8=LoadImage("fropf_r_4.png") B9=LoadImage("rechteck.png") B10=LoadImage("rechteck_2.png") B11=LoadImage("dreieck.png") Select True Case randblockselect=1 selectedblock=B1 Case randblockselect=2 selectedblock=B2 Case randblockselect=3 selectedblock=B3 Case randblockselect=4 selectedblock=B4 Case randblockselect=5 selectedblock=B5 Case randblockselect=6 selectedblock=B6 Case randblockselect=7 selectedblock=B7 Case randblockselect=8 selectedblock=B8 Case randblockselect=9 selectedblock=B9 Case randblockselect=10 selectedblock=B10 Case randblockselect=11 selectedblock=B11 Default selectedblock=B1 End Select DrawImage selectedblock, posx, posy End Function Function SetGraphicsMode() ; Set Graphics Select True Case GraphicsMode#=1 ;1: 640x480 Graphics 640,480, 32, wnd% Case GraphicsMode#=2 ;2: 800x600 Graphics 800,600,32, wnd% Case GraphicsMode#=3 ;3: 1024x768 Graphics 1024, 768, 32, wnd% Default End Select End Function |
| ||
Because you have this action 1: -------- repeat bla until action 2: -------- load images Just do the "load" before the "repeat" and you will be fine. The globals just exist "globally" but are initialized at the position in the code _you_ designed. ------- Die Globalen werden _nach_ dem repeat mit Werten gefuellt ... das geht alles "der Reihe nach". bye Ron |
| ||
This should be posted in Blitz3D board. |
| ||
Do not combine Loading and Drawing in one function. Loading should be before REPEAT, drawing inside the loop. So divide your code into two functions LOADBLOCK() and DRAWONE() check this: you have to load the images AFTER a graphic mode is defined, not before. In your context this will mean, that your LoadBlock() call has to be between SetGraphicsMode() and Repeat. Global wnd%=2 ..... Global B1%, B2%, B3%, B4%, ... fpstimer= CreateTimer(60) SeedRnd(MilliSecs()) SetGraphicsMode() SetBuffer BackBuffer () LoadBlock() Repeat DrawOne() ..... Until ... Function LoadBlock() B1=LoadImage("fropf_l_1.png") B2=LoadImage("fropf_l_2.png") .... End Function Function DrawOne() Select True Case randblockselect=1 selectedblock=B1 .... End Select DrawImage selectedblock, posx, posy End Function |
| ||
Youve got a massive memory leak there too....all those images will be loaded into memory every frame and then the reference is lost....im surprised you havent noticed it fall over once available memory is chewed up. |
| ||
Hello again! I did as Midimaster said, i put the loading functions into a seperate function and tried loading them before the "main loop" starts but when i do so, i've got that strange error message again. I just copy&pasted the Image Path but when i load them outside "that drawing() function" of that rogram the compiler / Program says that it doesn't find the images. Strangely, when i create a new .bb file from scratch, i can copy & paste the loading code into as it is and it works like midimater said outside the drawing function and i tried so already before by declaring them as GLOBAL. I even recreated the amount of IF and REPEAT structures in that new file and in a new file it works. Can it has something to do with the delay/timer function for limiting FPS at 60? Other Ideas i have not, but Gremlins that live in that code -.- Picture 1 ![]() Picture of loadblock() http://prntscr.com/8y2eeh If i load them outside a loading() function, by declaring them as GLOBAL variable its the same.. "not found" |
| ||
You need to store the reference to the images in a variable whose scope survives beyond the end of the function. Typically a type, a global var or an array would be used for this. As soon as the load function is exited the variables no longer exist bevause they are local to the function. That also means you get a memory leak because the images still exist in memory but you no longer have any reference to them. Blitz3d/plus dont clean up lost references for you. |
| ||
Ok, it works now. Look, that: ![]() is okay, but that: ![]() is not Thats confusing me. |
| ||
Hi, functions are special in a way that they themselfs can be considered globals, as they are static through out the programs lifecycle and are allocated similarly. This is why globals declared inside a function can only be seen inside a function. Globals are usually declared at the beginning of the source (main program) in order to be seen everywhere. On a sidenote using globals is thought to be bad programming form due to same reasons they are used for. If you have many globals *and whats worse* they are named arbitrarily on a larger program, it gets hard to maintain what variable names can be used safely so that they don't mix with globals declared somewhere else. One solution to this would be to name your globals with specific prefix. -Henri |
| ||
Probably too early to consider organising your code, but it's a slow day in work so I knocked this up for you, this probably wont run as I don't have blitz3d installed or have used in many years. I was also taken back of your used of Select and Repeat loops which are not really required. Affectively the code runs in two main functions, Update() and Render() with an Initiate() function to call at the start and a EndGame() function when you want to Quit. |
| ||
you forgot to define the variables B1...B11 at the beginning of the code as GLOBAL. have a look on my code snipplet from the last post: Global wnd%=2 ..... Global B1%, B2%, B3%, B4%, ... fpstimer= CreateTimer(60) SeedRnd(MilliSecs()) SetGraphicsMode() SetBuffer BackBuffer () LoadBlock() Repeat DrawOne() ..... Until . |