Global variables are Empty.. Why?

BlitzMax Forums/BlitzMax Beginners Area/Global variables are Empty.. Why?

kolpingwerkhamster(Posted 2015) [#1]
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


kolpingwerkhamster(Posted 2015) [#2]
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




Derron(Posted 2015) [#3]
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


markcw(Posted 2015) [#4]
This should be posted in Blitz3D board.


Midimaster(Posted 2015) [#5]
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



Matty(Posted 2015) [#6]
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.


kolpingwerkhamster(Posted 2015) [#7]
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"


Matty(Posted 2015) [#8]
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.


kolpingwerkhamster(Posted 2015) [#9]
Ok, it works now.

Look, that:



is okay, but that:



is not

Thats confusing me.


Henri(Posted 2015) [#10]
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


coffeedotbean(Posted 2015) [#11]
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.




Midimaster(Posted 2015) [#12]
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 .