Bug or my fault? (types related)

Blitz3D Forums/Blitz3D Beginners Area/Bug or my fault? (types related)

Valgar(Posted 2004) [#1]
Hallo.
I'm trying to create an object at other object coordinates,but when i run the code i have the error "variable must be a type" or "the object doesn't exist"...
The two "variable" that create the error are jet\positionx & jet\positiony
Don't know where i made error because those two variable type are created before the call to the create function..and if i try to modify the code to place a number instead the 2 variable all the code run...


GfK(Posted 2004) [#2]
You need to post some code.


Valgar(Posted 2004) [#3]
the code is about 3000 line of code.....
i try to post some function instead
the strange thing is i can use those 2 variable ONLY for movement,but not for collision detection or object creations...
Here's some function


If in my main i call in a row the function for move and after the function to create object...i have a error that the object don't exist and the debugger point me to the two variable that hold the x and y position of the moving object...


Valgar(Posted 2004) [#4]
I forgot to tell that every type is declared global.


Valgar(Posted 2004) [#5]
There's something wrong with the types..i can't even use ALL the variable of that type for debuglog.....it seems that the type don't exist....but if don't exist why it moves???


Valgar(Posted 2004) [#6]
It seems that the types variable are accessible ONLY inside the function from where they are created!


GfK(Posted 2004) [#7]
It seems that the types variable are accessible ONLY inside the function from where they are created!
In which case, "jet" is not global.


Valgar(Posted 2004) [#8]
but i declared jet as global at the start of the code!
if i don't do it the program return me the error "variable must be a type" before a single cycle of code....


GfK(Posted 2004) [#9]
Did you type "Global Jet.main_jet", or just "Global Jet"?


Valgar(Posted 2004) [#10]
If i type in my main debuglog jet (jet is the type's name) i see :
1
0
1
0
1
0
1
0
and so on..... why sometimes is 1 and other is 0???


Valgar(Posted 2004) [#11]
i have typed global jet.main_jet


Valgar(Posted 2004) [#12]
I think i have individuated the problem!
The other function don't see the 2 variable because they're just in use by other function (i think...)so if i add in the function that set the 2 variable other 2 variable that store the same x and y pos all go well.
It's something similar to the problem with mousehit(1) if you call it 2 or 3 times in a row (reset itself).....i think that every access to a variable reset to null the variable....
But why all this trouble with variable utilization?
It's confusing....


WolRon(Posted 2004) [#13]
i think that every access to a variable reset to null the variable....
This is ABSOLUTELY not true (unless you are nulling it yourself).

The problem is something else.


big10p(Posted 2004) [#14]
I think you're tying yourself in knots with this jet.main_jet global variable. It changes every time you call load_mainjet() and you're also using it as a For/Each variable in draw_mainjet().

[edit] Yeah, on further investigation, every time you use jet as the For\Each variable, the global is reset to 0.


Valgar(Posted 2004) [#15]
Load_mainjet is called one time only outside the main loop ( a classic while not.....wend)
The one that are called are draw_mainjet (every loop) and create object (every time i press button).
I have tried to eliminate draw_mainjet and incorporate the procedure INTO the main just after the classic "setbuffer backbuffer()" and no error occurr except that every time i call create object the position of the object are changed at random (???).
I use the "for each" loop because it's a full type "control"...if i don't do it the function don't work at all....
Except for assigning multiple variable to the same variable's type (actually i use multiple names for the same type object,like jet\positionx in this manner:x=jet\positionx......posX=jet\positionx....and so on...but at the end it's confusing because the multiple variable names to remember...)there are other solution???


MAX711(Posted 2004) [#16]
you are defining jet\posizionex which relies on jet\velocita before you define jet\velocita=1, which seems strange, is that the way you intended?


Valgar(Posted 2004) [#17]
Urgh you are right.....
But it's not the error (i have tryied to assign speed firt then position but it's the same..)
Now i have another problem....
I have resolved the previous problem assigning jet\positionx and jet\positiony at another variable OUTSIDE the "for jet.main_jet = each main_jet" loop and all go well...except that i have the jet change it's display frames accordingly to a variable that relies on a call to millisecs()....
If i use the EXACT command in the function draw_mainjet() the calls to millisecs() don't work (???) if i delete the function and write the EXACT command into the main loop...all work!
Why???


Valgar(Posted 2004) [#18]
Another problem.....if i use the previous example (to write the code inside the main) when i call other function that rely in some manner to what is writed inside the main.....i get "image frame out of range"............ARGH
It seems that the "if frame=>6 then frame = 6" (for make the frame stop at the max frame...) is not executed!
Because if i use debuglog frames i see 19...
Why?It seems that frames is added to some variable,but i don't do it manually!!!
Are there some bugs with Blitz types or in some manner is my method of writing function??


Valgar(Posted 2004) [#19]
Ok...sorted this problem....i assign a different name to the variable (i think that in some part of my code there's a variable name like that one...).
But why some things must be INSIDE the main i don't know....
Anyway.....the "for...each" loop for the modification of types is a tricky one.....if it's reset the global to 0 (like what big10p says)it's a terrible problem (for me at least...).


Valgar(Posted 2004) [#20]
Sorry for bothering all of you...but i have "discovered" another problem....
It's not the "for...each" the problem....but the function itself!
I have deleted the call to the function and instead write what it was inside the function at the start of the main....i even write the "for...each" loop to go trough the type object and....all go well,even the calls to millisecs()!
So i think there's something wrong with the functions...
I have always thinked that what is inside of a function is like it was inside the main ,because if i call the function at every main loop it's similar to if i write the code in the loop...but it seems it's not like this.
Some code must be INSIDE the main,even if thet function is called everytime...argh what a mess!
(i don't even thinked that 3000 or so lines of code are so difficult to "maintain" ...)


big10p(Posted 2004) [#21]
First: If load_mainjet() only gets called once, why are you using a For/Each loop to go through all main_jet types when there is only one? Or are you creating new main_jet types somewhere else in your code?

Secondly:

Anyway.....the "for...each" loop for the modification of types is a tricky one.....if it's reset the global to 0 (like what big10p says)it's a terrible problem (for me at least...).



This shouldn't be a problem. Instead of using 'For jet.main_jet=Each main_jet' (which uses the global variable jet for the loop), use a different variable like 'For this_jet.main_jet=Each main_jet'. It's a very bad idea to use loop variables outside of the loop itself - they should be temporary variables just used to iterate through the loop.


Valgar(Posted 2004) [#22]
I use the for each because if i don't all the field type return me the error" variable musty be a type" or "object don't exist" if i try to process some field type inside other function.
I don't understand what do you mean for different variable name....i use jet.mainjet because jet.mainjet is the type instance....if i use,for example,this_jet.mainjet=each mainjet....if i try to access type field inside other function...i get a "object doesn't exist" error...because i don't have declared global the instance of this_jet.mainjet
Now i write some code to see if you tell me (if you want of course!) what the error is.
In this function i use 3 calls to millisecs() in a row....so if i take the same code in a function don't work....if i take the EXACT code in the main...work!
Function prova()
	

	For jet.main_jet=each main_jet
		
		assex=JoyX()*2
		assey=JoyY()*2
		joypad=JoyX()
		jet\posizionex=jet\posizionex+assex
		jet\posizioney=jet\posizioney+assey
		If jet\posizionex => 630 Then jet\posizionex=jet\posizionex-2
		If jet\posizionex <= 10 Then jet\posizionex=jet\posizionex+2
		;x=x+assex
		;y=y+assey
		;If x => 630 Then x=x-2
		;If x <= 10 Then x=x+2
		If startmov=0 Then fotogramma2=3
		
		If joypad=0 And startmov=1	;no left or right direction pulled and no animation started
			If orologio > counter+50
				counter=orologio
				If fotogramma2 > 3
					current_frame=fotogramma2
					fotogramma2=current_frame-1
					If fotogramma2=3
						fotogramma2=3
						startmov=0	;reset the anim to not started...
					EndIf
				EndIf
				If fotogramma2 < 3
					current_frame=fotogramma2
					fotogramma2=current_frame+1
					If fotogramma2=3 
						fotogramma2=3
						startmov=0	;reset the anim to not started...
					EndIf
				EndIf
			EndIf
		EndIf

		If joypad=1 Then 	;if joypad pull right
			startmov=1
			If orologio > timer + 150
				timer=orologio
				current_frame=fotogramma2
				fotogramma2=current_frame+1
				If fotogramma2 => 6 Then fotogramma2=6
			EndIf
		EndIf

		If joypad=-1 Then	;if joypad pull left
			startmov=1
			If orologio > timer2 + 150
				timer2=orologio
				current_frame=fotogramma2
				fotogramma2=current_frame-1
				If fotogramma2 < 0 Then fotogramma2=0
			EndIf
		EndIf
		;For jet.main_jet = Each main_jet
			If jet\resistenza <= 0 
				crea_esplosione(jet\posizionex,jet\posizioney)
				Delete jet
				jetdistrutto=True
		Exit
			EndIf
		;Next
		DrawImage(jet_image,jet\posizionex,jet\posizioney,fotogramma2)
		jet_collisionx=jet\posizionex
		jet_collisiony=jet\posizioney
		DebugLog fotogramma2
		DebugLog timer
		DebugLog counter
		DebugLog startmov
		DebugLog orologio
	Next
	
	
	
End Function

Orologio is declared global at the start of the code.


Valgar(Posted 2004) [#23]
In other words...i declare global the type instance (i always declare type instance global...)because some type fields are required for other function to work....collision is dependent of jet\positionx &jet\positiony and so on.....so if i don't declare global the jet type...the other function that relys on jet fields- return me error.
It's why i declare type instance global.


_PJ_(Posted 2004) [#24]
DrawImage(jet_image, jet\posizionex,jet\posizioney,fotogramma2)


Doesn't look right to me...

Perhaps this is better?
DrawImage jet\immagine,jet\posizionex,jet\posizioney,fotogramma2



big10p(Posted 2004) [#25]

I don't understand what do you mean for different variable name....i use jet.mainjet because jet.mainjet is the type instance....


Yes, but you can't use jet as the For/Each loop variable because it will be set to point to the next mainjet type in the list, after every loop. This will be a NULL pointer (zero) when the end of the list is reached. So, as you're using the global jet as the loop variable, it gets set to 0!

If you only have one mainjet type object in your game, you don't need to use a for/each loop. Storing the pointer to the single mainjet type in a global allows you to access it from anywhere in your program. If you're getting errors, you must be doing something else wrong.


tonyg(Posted 2004) [#26]
In addition to Malice's response.
You need to create better debug messages.
First, have standard debug messages such as...
DebugLog "Have entered/exited function xxx"
at the start and end of each function (along with timer messages for optimisation tests).
If you get a problem add further debug messages which are output when set and when leaving functions.
Rather than
DebugLog fotogramma2
use something like...
DebugLog "Fotogramma2 on exit of function xxx is " +
fotogramma2
Consider using text commands for items such as player x/y and names which appear on screen.
Finally, get used to setting checkpoint messages in your main loop such as...
DebugLog "Main_loop4"
With all these you can trace any errors to specific code by checking which messages have been written.
p.s. I tend to have a comment such as TGDEBUG so I can delete lines later.


Valgar(Posted 2004) [#27]
I've tried to delete the for each ....but i receive error in other function that relys on type fields....What do you mean by storing the pointer to the single mainjet type in a global?

@Malice You are right :) but i have 2 variable that do the same thing so change the one to the other is equal.

Ps: sorry for bothering all of you,but i think thisi is an extremely important thing,because in 1 years that i have Blitz i have encountered the same error in about all function and types that i use...so i'm missing something crucial.


Valgar(Posted 2004) [#28]
I go to take some fresh air (my small brain is begging me for this!)
I return in about an hour (sorry for this but i'm going to fuse....).


big10p(Posted 2004) [#29]

What do you mean by storing the pointer to the single mainjet type in a global?



Please answer this question:
Do you only have ONE main_jet type instance in your game, or do you have several?

If you only have one, then:
Global jet.main_jet

Creates a global pointer to it which can be accessed anywhere in the program. You then call load_mainjet() which creates the main_jet instance and sets jet.main_jet to point at it.

You can now access this main_jet type instance anywhere in your program. If you are getting errors with this, please post the code that causes the error.


Valgar(Posted 2004) [#30]
I do the exact thing that you have writed....
i try to post some snippet of code...(i take a little time to do this..sorry!)


Valgar(Posted 2004) [#31]
Ok i have tried to recreate some code that do the same error:


Now when you hit the two joypad button....the error occur.
The same error that some other function in other program gave me!(so i think i made the same error)


big10p(Posted 2004) [#32]
You seem to be getting very confused as to how you can use the variables you're creating.

Global jet.main_jet
Global missile.bullet

What do you THINK these 2 global variables are pointing at?
(Please answer this question!)

missile.bullet can point at a bullet type but which one? I assume your game doesn't have only one bullet in it?!

Again, you're still using these global variables with for/each which I've already tried to explain is not good.


Valgar(Posted 2004) [#33]
And now the same snippet of code to see why if some instruction are inside a function they don't work...(millisecs()
Here the code with the function: (the one that don't work)
Graphics 640,480,32,2

Global bullet_image=LoadImage("bullet1.bmp")
Global bomb_image=LoadImage("bullet3.bmp")
Global jet_image=LoadAnimImage("jet-strip1.bmp",42,54,0,7)
Global jet.main_jet
Global assex
Global assey
Global joypad
Global x=320
Global y=240
MidHandle jet_image
MidHandle bomb_image
MidHandle bullet_image
Global missile.bullet	






Type bullet
	Field immagine
	Field positionx
	Field positiony
	Field potenza
	Field velocita
	Field durata
End Type

Type main_jet
	Field posizionex
	Field posizioney
	Field immagine
	Field potenza
	Field resistenza
	Field velocita
End Type

Function load_mainjet(image)
	jet.main_jet=New main_jet
	jet\posizionex=320
	jet\posizioney=240
	jet\immagine=image
	jet\potenza=1
	jet\resistenza=20		;successivamente si applicheranno dei modificatori (power-up)
	jet\velocita=1
End Function

Function crea_proiettile(immagine,speed,power,posx,posy,lunghezza)
	missile.bullet=New bullet
	missile\immagine=immagine
	missile\positionx=posx
	missile\positiony=posy
	missile\potenza=power
	missile\velocita=speed
	missile\durata=lunghezza
End Function


Function spara_proiettili()
	If hi_score<=100	;un rudimentale sistema di power-up
		crea_proiettile(bullet_image,6,1,jet\posizionex-10,jet\posizioney-20,50)	;proiettilenormale
	EndIf
	If hi_score >100	;se il punteggio e superiore a 100 crea un altro proiettile...
						;posso usare un'altra condizione(aver raccolto un power-up)
						;aumentare il danno ecc ecc
		crea_proiettile(bullet_image,6,1,jet\posizionex-10,jet\posizioney-20,50)	;proiettilenormale
		crea_proiettile(bullet_image,6,1,jet\posizionex+10,jet\posizioney-20,50)	;proiettilenormale
	EndIf
End Function


Function muovi_proiettile()

	For missile.bullet = Each bullet
		missile\durata = missile\durata-1
		

		If missile\durata=<0
			Delete missile
		Else
			missile\positionx = missile\positionx ;This does nothing.
			missile\positiony = missile\positiony-missile\velocita
			counter = counter+1 ;This doesn't appear to be used.
			DrawImage (missile\immagine,missile\positionx,missile\positiony)
		EndIf		
	Next
End Function

;M A I N 
load_mainjet(jet_image)

While Not KeyHit(1)=True
SetBuffer BackBuffer() : Cls
joybutton1=JoyHit(1)
joybutton2=JoyHit(2)
prova()
If jetdistrutto=False	;se il jet non e stato distrutto spari,altrimenti non spari ^^
	If joybutton1=True		;se premo il tasto sinistro del mouse
		spara_proiettili()
	EndIf
	If joybutton2=True ;se premo il tasto destro del mouse
		crea_proiettile(bomb_image,4,5,jet\posizionex,jet\posizioney-20,30)	;proiettile + potente (bomba)
	EndIf
EndIf

muovi_proiettile()

Flip True
Wend

Function prova()
For jet.main_jet=Each main_jet
assex=JoyX()*2
assey=JoyY()*2
joypad=JoyX()
jet\posizionex=jet\posizionex+assex
jet\posizioney=jet\posizioney+assey
If jet\posizionex => 630 Then jet\posizionex=jet\posizionex-2
If jet\posizionex <= 10 Then jet\posizionex=jet\posizionex+2
If startmov=0 Then fotogramma=3
DebugLog timer
DebugLog counter
If joypad=0 And startmov=1	;no left or right direction pulled and no animation started
	If MilliSecs()> counter+50
		counter=MilliSecs()
		If fotogramma > 3
			current_frame=fotogramma
			fotogramma=current_frame-1
			If fotogramma=3Then fotogramma=3:startmov=0	;reset the anim to not started...
		EndIf
		If fotogramma < 3
			current_frame=fotogramma
			fotogramma=current_frame+1
			If fotogramma=3 Then fotogramma=3:startmov=0	;reset the anim to not started...
		EndIf
	EndIf
EndIf

If joypad=1 Then 	;if joypad pull right
	startmov=1
	If MilliSecs() > timer + 150
		timer=MilliSecs()
		current_frame=fotogramma
		fotogramma=current_frame+1
		If fotogramma => 6 Then fotogramma=6
	EndIf
EndIf

If joypad=-1 Then	;if joypad pull left
	startmov=1
	If MilliSecs() > timer + 150
		timer=MilliSecs()
		current_frame=fotogramma
		fotogramma=current_frame-1
		If fotogramma < 0 Then fotogramma=0
	EndIf
EndIf

DrawImage jet_image,jet\posizionex,jet\posizioney,fotogramma		
Next
End Function


Now here's the code that work (the one without the function but with the EXACT instruction of the previous function...)
Graphics 640,480,32,2

Global bullet_image=LoadImage("bullet1.bmp")
Global bomb_image=LoadImage("bullet3.bmp")
Global jet_image=LoadAnimImage("jet-strip1.bmp",42,54,0,7)
Global jet.main_jet
Global assex
Global assey
Global joypad
Global x=320
Global y=240
MidHandle jet_image
MidHandle bomb_image
MidHandle bullet_image
Global missile.bullet	






Type bullet
	Field immagine
	Field positionx
	Field positiony
	Field potenza
	Field velocita
	Field durata
End Type

Type main_jet
	Field posizionex
	Field posizioney
	Field immagine
	Field potenza
	Field resistenza
	Field velocita
End Type

Function load_mainjet(image)
	jet.main_jet=New main_jet
	jet\posizionex=320
	jet\posizioney=240
	jet\immagine=image
	jet\potenza=1
	jet\resistenza=20		;successivamente si applicheranno dei modificatori (power-up)
	jet\velocita=1
End Function

Function crea_proiettile(immagine,speed,power,posx,posy,lunghezza)
	missile.bullet=New bullet
	missile\immagine=immagine
	missile\positionx=posx
	missile\positiony=posy
	missile\potenza=power
	missile\velocita=speed
	missile\durata=lunghezza
End Function


Function spara_proiettili()
	If hi_score<=100	;un rudimentale sistema di power-up
		crea_proiettile(bullet_image,6,1,jet\posizionex-10,jet\posizioney-20,50)	;proiettilenormale
	EndIf
	If hi_score >100	;se il punteggio e superiore a 100 crea un altro proiettile...
						;posso usare un'altra condizione(aver raccolto un power-up)
						;aumentare il danno ecc ecc
		crea_proiettile(bullet_image,6,1,jet\posizionex-10,jet\posizioney-20,50)	;proiettilenormale
		crea_proiettile(bullet_image,6,1,jet\posizionex+10,jet\posizioney-20,50)	;proiettilenormale
	EndIf
End Function


Function muovi_proiettile()

	For missile.bullet = Each bullet
		missile\durata = missile\durata-1
		

		If missile\durata=<0
			Delete missile
		Else
			missile\positionx = missile\positionx ;This does nothing.
			missile\positiony = missile\positiony-missile\velocita
			counter = counter+1 ;This doesn't appear to be used.
			DrawImage (missile\immagine,missile\positionx,missile\positiony)
		EndIf		
	Next
End Function

;M A I N 
load_mainjet(jet_image)

While Not KeyHit(1)=True
SetBuffer BackBuffer() : Cls
joybutton1=JoyHit(1)
joybutton2=JoyHit(2)
; here's the SAME EXACT code that was previously inside the function....with the "for...each" for the types also
;**********
For jet.main_jet=Each main_jet
assex=JoyX()*2
assey=JoyY()*2
joypad=JoyX()
jet\posizionex=jet\posizionex+assex
jet\posizioney=jet\posizioney+assey
If jet\posizionex => 630 Then jet\posizionex=jet\posizionex-2
If jet\posizionex <= 10 Then jet\posizionex=jet\posizionex+2
If startmov=0 Then fotogramma=3
DebugLog timer
DebugLog counter
If joypad=0 And startmov=1	;no left or right direction pulled and no animation started
	If MilliSecs()> counter+50
		counter=MilliSecs()
		If fotogramma > 3
			current_frame=fotogramma
			fotogramma=current_frame-1
			If fotogramma=3Then fotogramma=3:startmov=0	;reset the anim to not started...
		EndIf
		If fotogramma < 3
			current_frame=fotogramma
			fotogramma=current_frame+1
			If fotogramma=3 Then fotogramma=3:startmov=0	;reset the anim to not started...
		EndIf
	EndIf
EndIf

If joypad=1 Then 	;if joypad pull right
	startmov=1
	If MilliSecs() > timer + 150
		timer=MilliSecs()
		current_frame=fotogramma
		fotogramma=current_frame+1
		If fotogramma => 6 Then fotogramma=6
	EndIf
EndIf

If joypad=-1 Then	;if joypad pull left
	startmov=1
	If MilliSecs() > timer + 150
		timer=MilliSecs()
		current_frame=fotogramma
		fotogramma=current_frame-1
		If fotogramma < 0 Then fotogramma=0
	EndIf
EndIf

DrawImage jet_image,jet\posizionex,jet\posizioney,fotogramma		
Next
;**********
;as you see it's the same....








;prova()				commented!!! 







If jetdistrutto=False	;se il jet non e stato distrutto spari,altrimenti non spari ^^
	If joybutton1=True		;se premo il tasto sinistro del mouse
		spara_proiettili()
	EndIf
	If joybutton2=True ;se premo il tasto destro del mouse
		crea_proiettile(bomb_image,4,5,jet\posizionex,jet\posizioney-20,30)	;proiettile + potente (bomba)
	EndIf
EndIf

muovi_proiettile()

Flip True
Wend

Now i have tell everything of the problem (the other that i have are related to these two and the error that i have are similar...)


Valgar(Posted 2004) [#34]
For your previous post.
If i don't declare global mainjet why i have error when other function try to access mainjet field?
If i don't declare global mainjet i have to add at each function that use mainjet fields the "for jet.mainjet =each mainjet"...or it's just the correct way to go?(to declare each time i use a field type the for each loop)


Valgar(Posted 2004) [#35]
Ps:many thanks for the advice tonyg!
but in about 1 year of Blitz i have used debuglog only now -_-' so i'm much a baginner at debugging more then the command itself....


Valgar(Posted 2004) [#36]
No one know why millisecs if used in this manner don't work outside the main?
Is something sistem-timer related?


Valgar(Posted 2004) [#37]
Sorry for bothering....i have resolved creating another type fields and assign to this field the current millisecs().


big10p(Posted 2004) [#38]
In case you're still interested, I guess the version using a function doesn't work as you expect because the variable 'timer' is local to the function and will thus be reset to zero every time the function is called. 'timer' will retain it's value when the code is moved into the main code.


Valgar(Posted 2004) [#39]
Yes you are right;in fact i have resolved added a field to the type "timer" and i call this instead Millisecs(),all i have to do is declare at the creation of the types instance that "type\timer=Millisecs()".
Anyway i think i have resolved the "for----each" problem and global types.
Now i see if i write for every types variable contained in a function the "for this_type_variable.type=each type-----next" all go well.
In fact now when i write e function i use this method and no error occurr....