2

I'm very new to Python, so sorry about what will surely be an obvious question. I want the class Computer_paddle to be able to call Ball's function, y_position(), and get the return value. But it doesn't seem to be doing that, telling me:

"global name 'ball' is not defined". 

Is there something special I need to do to call a function within another function?

class Ball(games.Sprite):
    """ A ball that bounces off walls and paddles. """
    image = games.load_image("ball.png")

    def __init__(self, game, x, y):
        """ Initialise ball sprite. """
        super(Ball, self).__init__(image = Ball.image,
                                   x = x, y = y,
                                   dx = -3, dy = 0)

    def update(self):
        """Check if ball has hit paddle or wall, and then bounce that ball. """
        super(Ball, self).update()

        # check if ball overlaps paddles
        if self.overlapping_sprites:
            self.dx = -self.dx
            self.dy += random.randint(-1, 1)

        # check if ball hits a wall
        if self.top < 0 or self.bottom > games.screen.height:
            self.dy = -self.dy
        if self.left < 0 or self.right > games.screen.width:
            self.dx = -self.dx

    def y_position(self):
        return self.y

class Paddle(games.Sprite):
    """ A paddle that can only partly leave the screen. """
    image = games.load_image("paddle.png")

    def __init__(self, game, x, y):
        """ Initialise paddle sprite."""
        super(Paddle, self).__init__(image = Paddle.image, x = x, y = y)

    def update(self):
        """ Prevent sprite from completely leaving the screen. """
        if self.top < -33:
            self.top = -33

        if self.bottom > games.screen.height + 33:
            self.bottom = games.screen.height + 33

class Human_paddle(Paddle):
    """ A paddle controlled by the player. """

    def update(self):
        """ Move paddle to mouse position. """
        super(Human_paddle, self).update()

        self.y = games.mouse.y

class Computer_paddle(Paddle):
    """ A paddle controlled by the computer. """
    MAX_SPEED = 1

    def update(self):
        """ Move paddle towards ball's position on Y-axis. """
        super(Computer_paddle, self).update()

        ball_y = ball.y_position()

        if ball_y > self.y:
            self.y += MAX_SPEED
        if ball_y < self.y:
            self.y -= MAX_SPEED
1
  • 3
    Welcome to StackOverflow. I've formatted your question for you (you can do this yourself for your next question by selecting the code and using the {} button in the toolbar). Also, there's a lot of code here that's not relevant to your problem, please try to reduce your code to the bare minimum required to demonstrate the issue you are having. Good luck! Commented Aug 21, 2011 at 9:34

3 Answers 3

3

No, but you need to have a reference to an object in order to access its methods. Since you never bind ball to anything, there's no object to call the methods on. Did you mean to create ball as an instance of Ball at a global level?

Sign up to request clarification or add additional context in comments.

Comments

3

Right now all the attributes and methods you defined for the "Ball" class are instance specific: to be able to access them you would need to

  • create a Ball instance
  • then pass that ball instance to the paddle instances that need to have knowledge of it

So something like this : Somewhere in the code create a ball instance:

ball_1=Ball(game, 0,0)

Then change your Paddle's update method to accept a ball instance as a parameter:

def update(self,ball):

And when calling the update method on any paddle that needs to have knowledge of the ball:

my_paddle.update(ball_1)

This way, the paddle objects will know what ball's y position you are trying to access.

Of course you could do this a number of different ways, as long as you somehow pass a ball instance to the paddle so it knows what ball it needs to query for its y position.

Hope this helps!

2 Comments

Sorry if this comes off as unclear. I don't call the update method directly, I use games.screen.mainloop(). So therefore, I get a TypeError saying "update() takes exactly 2 positional arguments (1 given)", and I don't know how to pass two arguments to update().
could you then perhaps post the code for the games.screen.mainloop() ? or ar you using some sort of library perhaps ?
2

You need to instantiate the class Ball anywhere and make this instance available for the Computer_paddle instance.

I'd suggest a handler-class that organizes the game and has attributes accessible from the paddles. (Or you could also subclass the Game-class of the games module.)

class GameHandle(object):
    def __init__(self):
        self.game = games.Game() # or however to create a game instance
        self.ball = Ball(self.game, 0, 0)
        self.player1 = Human_paddle(self.game, -100, 0, self)
        self.player2 = Computer_paddle(self.game, 100, 0, self)

class Paddle(games.Sprite):
    def __init__(self, game, x, y, handle):
        # ...
        self.handle = handle

class Computer_paddle(Paddle):
    def update(self):
        # ...

        ball_y = self.handle.ball.y_position()

        # ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.