Functions Problem (Moving Sphere)

Blitz3D Forums/Blitz3D Beginners Area/Functions Problem (Moving Sphere)

Captain Wicker (crazy hillbilly)(Posted 2011) [#1]
Hi,
I like to learn the hard way so could someone please look at this code and tell me what is wrong with it and why it will not work?
Graphics3D 800,600,32,2
SetBuffer BackBuffer()

Global cam=CreateCamera()

Local sphere=CreateSphere()
Global light=CreateLight()
PointEntity light,sphere

PositionEntity sphere,0,0,6


Repeat
	
	control()
	
	
	
	UpdateWorld
	RenderWorld
	Flip
Forever



;FUNCTIONS
Function control()
	If KeyDown(200) Then MoveEntity sphere,0,0,1
	If KeyDown(208) Then MoveEntity sphere,0,0,-1
	If KeyDown(203) Then MoveEntity sphere,-1,0,0
	If KeyDown(205) Then MoveEntity sphere,1,0,0
End Function



big10p(Posted 2011) [#2]
It's because you've defined sphere as Local, for some reason, so it isn't recognised inside the control() funtion. Make sphere Global, instead.


Matty(Posted 2011) [#3]
sphere is a local variable and therefore inaccessible to the function "control()" - unless you pass it as a parameter, or declare it global.


Captain Wicker (crazy hillbilly)(Posted 2011) [#4]
Oh ok thanks for that wonderful piece of info. :)
Thank you big10p! :)
Thank you Matty! :)


Yasha(Posted 2011) [#5]
Useful Wikipedia resources:

http://en.wikipedia.org/wiki/Variable_scope
http://en.wikipedia.org/wiki/Variable_%28programming%29#Scope_and_extent
http://en.wikipedia.org/wiki/Call_stack

Variables in Blitz3D follow a simple lexical scoping rule with no nested procedures.

It's very important to master the concepts of scope and functions in order to proceed onto using "procedural programming", a powerful step up from simple structured programming.


_PJ_(Posted 2011) [#6]
Excellent way to begin, Captain Wicker - a simple, but effective program which is easy enough to understand, but very easy to make changes to and update as you go!

I'd recommend you keep going with this framework, think of more ideas, such as, maybe introducing mouse controls to rotate the camera or such.








By declaring the sphere Global at the top instead of Local, everything is then perfect with that program.

You've made a great use of Whitespace and that really helps to see how the program is structured.

You've got 3 basic parts to it.

The first, is the "initialisation" part:
Thios sets the screen display, defines all the objects and (Global) variables you will need and makes sure everything's in the right place ready for the next part...
Graphics3D 800,600,32,2
SetBuffer BackBuffer()

Global cam=CreateCamera()

Local sphere=CreateSphere()
Global light=CreateLight()
PointEntity light,sphere

PositionEntity sphere,0,0,6



The second part, is the "Main Loop"
Very typical, this begins and ends with Repeat/Forever.

Other options are While/Wend or Repeat/Until which allow you to stop the Looping when cetain conditions arise.
My personal favouriote is
 While ( Not (KeyHit (1) ) )
     ; Loop contents
 Wend

Since this ensures that Pressing Escape will stop the program. The same can be achieved by using Repeat/Until
 Repeat
     ; Loop contents
 Until (KeyHit (1) )

Or to keep the Forever, you can add a clause WITHIN the Loop to 'jump out' if Escape is pressed by usig Exit:
 Repeat
     ; Loop contents
     If (KeyHit(1)) Then Exit
 Forever


There are subtle differences between using these varieties of loops. Mainly, note than the condition (the check for Escape being pressed in this case) for While/Wend accompanies the While command. This means that If escape had already been pressssed, the loop wont even execute at all - unlike the Repeat/Until where the condition is only checked at the END of the loop, accompanying "Until", so if Escape had been pressed earlier, the entire Loop would still run through ONCE.
The use of the Exit command allows the program to 'Jump Out' of any Loop (While/Wend, Repeat/Until/Forever and even For/Next loops) at any point within the Loop. Sometimes, it's handy to do just that!




In a game, this Main Loop would be where most things happen, although by putting the controls in the control() function, and just calling that inside the loop, you're not only keeping the Main Loop neat and tidy (which I feel is VERY important especially when you end up with very big, very complicated games), but you're also making it easier for yourself if you need to change something with the controls later. You only need to change the function withoout altering anything in the Main Loop, This is good coding practice.
Repeat
	
	control()
	
	
	
	UpdateWorld
	RenderWorld
	Flip
Forever











Finally, the third section is where you declare your control () function. (Also nicely and distinctly labelled with the ;FUNCTIONS comment!)
It's neat to keep this down here out of the way, and, as your program grows and you add more functions, these too can be declared at the bottom of the code away from the Main Loop and the Initialisation. I personally think it's great to do this, keeping them separated in such a way since the Initialisation part at the top AND the Main Loop are both directly procedural when you run the program, whilst the functions are only run through as and when they are called. Basically, you're ensuring that as the program runs (and works through the code from top to bottom), that order is clear and easy to see when looking at the code.

Last edited 2011


Yue(Posted 2011) [#7]
Function control(Entity)
	If KeyDown(200) Then MoveEntity Entity,0,0,1
	If KeyDown(208) Then MoveEntity Entity,0,0,-1
	If KeyDown(203) Then MoveEntity Entity,-1,0,0
	If KeyDown(205) Then MoveEntity Entity,1,0,0
End Function

=)