Functions and Type help

Blitz3D Forums/Blitz3D Beginners Area/Functions and Type help

AaP(Posted 2011) [#1]
I have a small problem with the localization of variables in types.

I declare a type in a function using

Function CreateBlock()
For x = 0 to 1
Block.blocks = New Blocks
Block\x = x
Next
End Function

but then when I try to access the type variables in another function...

Function MoveBlock()
For block.blocks = New blocks
Block\x = 1
Next
End Function

Nothing happens....


Yasha(Posted 2011) [#2]
Two things:

1: Functions have separate "local scopes" from one another; the variable "block" in CreateBlock has no connection at all to the variable "Block" in MoveBlock. This is quite a big part of the reason for using functions - to prevent that confusion.

2: MoveBlock is creating more block objects. The "New" command creates new objects of a given type, so naturally it won't refer to the objects created beforehand. You can iterate over each object in a type's global list using "Each":

Local block.blocks
For block = Each blocks
    block\x = 1
Next



Rob the Great(Posted 2011) [#3]
At a first glance, this line:
For block.blocks = New blocks

should become:
For block.blocks = Each blocks


I don't know if that's just a typo in your post, but if this is how it appears in your game, then Blitz will think that you're trying to cycle only a newly create block type, not every single type you've created previously.

On a second glance through your post, I notice that you're creating two blocks, positioned at 0,0,0 and 1,0,0. Then, you're moving both blocks to the same space (Block\x = 1) to 1,0,0 in your MoveBlock() function, which will make them appear as 1 block. Also, make sure that you're updating position with PositionEntity, MoveEntity, or TranslateEntity with the blocks and not just changing field variables.

EDIT:Yasha beat me to it. lol.

Last edited 2011


AaP(Posted 2011) [#4]
yah sorry i meant Each block, but how do i get it so that i can use one set of types in two different functions....


Rob the Great(Posted 2011) [#5]
I'm not sure if I follow...You should be able to do that already.

Types are Global (the actual Type is Global, but the identifier is Local to each function.).

In other words, if you have this line:
r.RandomType

"RandomType" is going to be accessible throughout your whole program. "r", however, is only going to be available in that specific function. This shouldn't ever be a problem, because you will need to re-declare "r" each time you want to access a type object anyways. The only difference is that you can name "r" to whatever variable you want (in Blitz's rules) per function, e.g. r.RandomType, this.RandomType, ACompletelyDifferentVariableNameFromTheOriginalType.RandomType, ect.

I'm going off on a tangent here, so just ignore the above statements if it's confusing. The point I'm trying to get across is that once you make a Type set, you can use any of those fields in any part of your program later on.

Here's an example of using a Type object in more than one function. Pay attention to formatting:
Graphics3D 640,480,0,2 ;set the graphics

SetBuffer BackBuffer() ;set up a double buffer

Global camera = CreateCamera() ;make a camera

Type enemy ;Create a new type list for all enemies
   Field family$ ;Each enemy has a family it belongs to (what kind of enemy?)
   Field bodymesh ;Each enemy needs a body
   Field x# ;Each enemy needs an x location (EntityX() will do the same thing)
   Field y# ;Each enemy needs a y location (EntityY() will do the same thing)
   Field z# ;Each enemy needs a z location (EntityZ() will do the same thing)
End Type
;Note that in the above type, I can store all three different data types (%,#, and $)
;All of these field are now accesible anywhere in my program if I call on this type list.

For count = 1 To 50 ;Do this part 50 times
   CreateNewFireMonster() ;Make a new fire monster (Uses the type above)
Next

For count = 1 To 50 ;Do this part 50 times
   CreateNewWaterMonster() ;Make a new water monster (Uses the type aboe)
Next

While Not KeyDown(1) ;The MAIN loop

   MoveFireMonsters() ;Randomly move each fire monster
   MoveWaterMonsters() ;Randomly move each water monster
   UpdateWorld
   RenderWorld
   Flip

Wend


;Functions List is below


Function CreateNewFireMonster() ;This will create a new enemy type for fire monsters
   e.enemy = New enemy ;Make a new enemy type, and call it "e" for now
   e\family$ = "Fire Monster" ;e's family$ is now "Fire Monster"
   e\bodymesh = CreateSphere() ;e's body is now a sphere
   EntityColor e\bodymesh,255,0,0 ;A Red sphere
   e\x# = Rnd(-50.0,50.0) ;generate a random x# location
   e\y# = Rnd(-50.0,50.0) ;generate a random Y# location
   e\z# = Rnd(-50.0,50.0) ;generate a random z# location
   PositionEntity e\bodymesh,e\x#,e\y#,e\z# ;position e's body at the new location
End Function

Function CreateNewWaterMonster() ;This is virtually the same as CreateNewFireMonster()
   w.enemy = New enemy ;But note that it's using the same type list and I'm using "w" instead of "e" as an identifier
   w\family$ = "Water Monster" ;Make this one a "Water Monster"
   w\bodymesh = CreateCube() ;a cube, not a sphere
   EntityColor w\bodymesh,0,0,255 ;and a blue cube
   w\x# = Rnd(-50.0,50.0)
   w\y# = Rnd(-50.0,50.0)
   w\z# = Rnd(-50.0,50.0)
   PositionEntity w\bodymesh,w\x#,w\y#,w\z#
End Function

Function MoveFireMonsters() ;This function will move fire monsters
   For BLAH.enemy = Each enemy ;This is important. If you ever need to cycle all enemy, use this line
      If BLAH\family$ = "Fire Monster" ;For every enemy, if it belongs to the "Fire Monster" family$
         BLAH\x# = BLAH\x# + Rnd(-1.0,1.0) ;generate a new x location
         BLAH\y# = BLAH\y# + Rnd(-1.0,1.0) ;generate a new y location
         BLAH\z# = BLAH\z# + Rnd(-1.0,1.0) ;generate a new z location
         PositionEntity BLAH\bodymesh,BLAH\x#,BLAH\y#,BLAH\z# ;position the body there...
      EndIf
   Next
End Function

Function MoveWaterMonsters() ;This function is the same as above
   For AnyVariableName.enemy = Each enemy ;Cycle through each enemy
      If AnyVariableName\family$ = "Water Monster" ;and if the enemy is a water monster
         AnyVariableName\x# = AnyVariableName\x# + Rnd(-1.0,1.0) ;you get the idea...
         AnyVariableName\y# = AnyVariableName\y# + Rnd(-1.0,1.0)
         AnyVariableName\z# = AnyVariableName\z# + Rnd(-1.0,1.0)
         PositionEntity AnyVariableName\bodymesh,AnyVariableName\x#,AnyVariableName\y#,AnyVariableName\z#
      EndIf
   Next
End Function

Normally, I don't test my examples as they're more to demonstrate concept rather than provide technique, but I did test this example and it works. My only advice is that you shouldn't run this example if you're epileptic (the enemy movement is extremely jittery).

In the code above, I over-exaggerated the fact that you can name the Type identifier to any Blitz valid variable you want, but this is typically avoided in good programming practice. I find it easy to just use the first letter of the Type name ("e" in this case) for Type identifiers, as you only have to type 1 character as opposed to a long variable name.

I believe this answers your question, but let me know otherwise.


AaP(Posted 2011) [#6]
Thanks I actually found I was having problems with a mousehit command versus a mousedown command. What I was doing now works.


Rob the Great(Posted 2011) [#7]
It's always the little things that miss us. I can't tell you how many times I've done something similar.