Question

I recently downloaded Kivy as it's given me the most comprehensible tutorials and documentation, etc. I've tried pygame and cocos but never could get a foundation, and with Kivy it's been easy.

So heres my problem, I've made a pong game, and I'm trying to make the game pause by stopping the pong ball, and then starting it again when it's unpaused (by changing its velocity).

Here's my code:

class PongGame(Widget):
   ...

    def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
        if keycode[1] == 'escape':
        #Why doesnt it work without global?
        #If I don't use a global i get "tempBallVelocity referenced before assignment
            global tempBallVelocity
            tempBallVelocity = self.ball.velocity
            self.ball.velocity = 0,0


        if keycode[1] == '`':
            #Make the ball go again, thus exiting pause
            #This is where the error occurs if I don't use global
            self.ball.velocity = tempBallVelocity   

As you can see in the comments, If I don't use global, I get referenced before assignment error. But it's a local variable, I don't understand why this is happening.

Anyone have any ideas? thanks?

Edit: Just to make sure everyone is clear in my intentions, I do NOT want to use a global, but it's the only way it will work. I would prefer not to use globals.

Was it helpful?

Solution

If you fix the indentation error again you will see that: You can see that:

  1. the escape escape should work without the global, however tempBallVelocity will be considered as a local variable. If you want to modify a global variable you need to add the global declaration to tell python that tempBallVelocity is not local but global.

  2. In the second case, tempBallVelocity is not locally initialized if you do not enter the escape block and thus cannot be used as a local RValue. In this case python should look for the variable outside of the class. Is tempBallVelocity really a global variable ?

remark: if the cases are exclusive you should use elif instead of if for the second case.

OTHER TIPS

Your code inside the function is not indented, is that just a copying mistake? If not I wonder why you don't get an error.

Edit: Ok, it's easy you set the variable tempBallVelocity when you call the function with 'escape' but then the function exits and you loose the variable. If you then call it with 'backtick' you haven't set the variable tempBallVelocity yet, the best solution would probably be: self.tempBallVelocity = self.ball.velocity.

Each time you set a variable inside a identated block of code, the variable is destroyed once you get out of that block, back into the previous identation;

If you write

if True:
    foo = 'foo value, which is a string (?)'
    print foo

inside a huge script, python only handles the foo variable while it's 'inside' the if statement, and once it ends it and gets out, foo is completely forgotten in order to make things faster, it's understood that if you set the variable inside a statement, you'll use it only inside that statement.

If you wanted to do something like this

if True:
    foo = 'foo value'

# Right now foo has been trashed

if True:
    print foo
    # Raises an error

You'd have to set the foo variable outside the 'if' statements

foo = ''

if True:
    foo = 'foo value'

# Right now foo still exists and keeps it's recently changed value

if True:
    print foo
    # prints 'foo value'

Or you may also do it by setting foo as a global variable so it isn't destroyed once you get outside the 'if' statement

if True:
    global foo
    foo = 'foo value'

# foo still exists as it's a global variable

if True:
    print foo
    # There's no reason so it wouldn't work

But that may be unnecesary and confusing in most circunstances, or even problematic if you start making everything global so variables that you only use once accrue uselessly on your device's memory during the program.

Right now you are writing a class, so the right way to do what you are doing would be (from my point of view) to storage the 'tempBallVelocity' variable in the class like this

class PongGame(Widget):
   ...

    def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
        if keycode[1] == 'escape':
            self.tempBallVelocity = self.ball.velocity
            self.ball.velocity = 0,0


        if keycode[1] == '`':
            self.ball.velocity = self.tempBallVelocity   

It looks like it doesn't respect the rule I've just told you but the thing here is that when you write 'self.tempBallVelocity = ...' you are storaging the info in self, which is the shortcut to the PongGame object you'll instantiate in order to run the game, which will run that method, so the variable stands storaged there when you get out the method.

I hope this answer is helpful to you, you should get a more solid knowledge about python, Learn Python The Hard Way is a site of a book with a free html version that was useful for me.

See you! :D

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top