Several problems

BlitzPlus Forums/BlitzPlus Programming/Several problems

D2(Posted 2007) [#1]
My scrolling shooter's going great, except for two problems. First off, I used this code to update the bullet position:

;/////// UPDATE BULLETS ///////
For mainBullet.bullet = Each bullet
	mainBullet/y = mainBullet/y = 5


When I run it, it says "expecting 'Next'"

When I read the book "game programming for teens," and I saw and identical portion of code, there was no "Next" there, and they expect it to work. This is really annoying.

Second, whenever I place the key detection in a function, it goes wrong. First off, here's the key detection:
;move left
If KeyDown(KEY_LEFT)
	player1\x = player1\x - moveSpeed
EndIf	

;move right
If KeyDown(KEY_RIGHT)
	player1\x = player1\x + moveSpeed
EndIf	

;move up
If KeyDown(KEY_UP)
	player1\y = player1\y - moveSpeed
EndIf

;move down
If KeyDown(KEY_DOWN)
	player1\y = player1\y + moveSpeed
EndIf


But if I put that in a function, like so:
Function KeyControl()
;move left
If KeyDown(KEY_LEFT)
	player1\x = player1\x - moveSpeed
EndIf	

;move right
If KeyDown(KEY_RIGHT)
	player1\x = player1\x + moveSpeed
EndIf	

;move up
If KeyDown(KEY_UP)
	player1\y = player1\y - moveSpeed
EndIf

;move down
If KeyDown(KEY_DOWN)
	player1\y = player1\y + moveSpeed
EndIf
End Function

then it gives me the message "variable must be a type." Why is this happening?


Phil Newton(Posted 2007) [#2]
Firstly, all For loops need a Next to terminate them, so it might be a typo in the book.

If you want the function to be able to access the player1 variable, you either need to declare it as a Global, or pass it to the function. The reason you're getting the "variable must be type" error is because Blitz is creating a local variable called "player1" inside this function, but it automatically makes it an integer and not a type.

You'll also need to make sure the "moveSpeed" variable is either a global or a constant, otherwise the function won't be able to access it.

I apologise if you know any of this already :)

One way to do it is put "Global" before the first use of the player1 variable, probably when it's first created.

Global player1.Player


This will let all functions in your program access and modify it. This can be a bad thing though, so you may want to pass it to the function instead. There's one gotcha here though. When passing variables to a function normally, they are passed by value. In other words, if you pass a variable called "myVar" and modify it within the function, the changes will only be effecting inside the function - try this for a good example:

Local myVar = 1
print "Value before function: " + myVar
valueTest(myVar)
print "Value after function: " + myVar

Function valueTest(someVar)
  someVar = 3
  Print "Value within function: " + someVar
End Function


HOWEVER, if you pass an object (a type instance) to a function, it is passed by reference. This means that changes in the function will change it outside the function too. Here's another example:

Type myType
  Field someValue$
End Type

Local test.myType = New myType
test\someValue = "Hello"

Print "Before function: " + test\someValue
typeTest(test)
Print "After function: " + test\someValue

Function typeTest(this.myType)
  test\someValue = "Goodbye"
End Function


Hopefully that made sense. Although this behaviour can be a little confusing to begin with, it makes things much easier later on.

Anyway, to answer you question (finally!), here is how to fix your problem by passing the player object to the function:

; Main code
Local player1.Player = new Player

; Call the key control
KeyControl(player1)

Function KeyControl(this.Player)
 If KeyDown(KEY_LEFT)
  this\x = this\x - moveSpeed
 EndIf
 ; etc
End Function


Hope that helps :)


Rob Farley(Posted 2007) [#3]
And Next aside
mainBullet/y = mainBullet/y = 5
is wrong

It should be
mainBullet/y = mainBullet/y + 5
to move the bullet down or
mainBullet/y = mainBullet/y - 5
to move the bullet upwards.


Senzak(Posted 2007) [#4]
seems like the slashes should be back slashes as well