[Tutor] __init__ argument

Dave Angel davea at davea.name
Fri Mar 15 23:58:11 CET 2013


On 03/15/2013 06:46 PM, Joshua Wilkerson wrote:
> The program keeps telling me that the __init__ in Rock takes two arguments and only one is given. Ideas?
> The point of the game is to dodge falling rocks. Two more appear every time one reaches the bottom of the screen.
>
> # Avalanche, a dodging game
> # Written by Josh Wilkerson
> # Dodge falling rocks, two new rocks appear every time a rock hits the bottom.
>
> from livewires import games, color
> import random
>
> games.init(screen_width = 640, screen_height = 480, fps = 50)
>
> class Chef(games.Sprite):
>      """
>      A chef controlled by the player to dodge falling rocks.
>      """
>      image = games.load_image("chef.jpg")
>
>      def __init__(self, y = 450):
>          """ Initialize Chef object and create Text object for score. """
>          super(Chef, self).__init__(image = Chef.image,
>                                     x = games.mouse.x,
>                                     bottom = games.screen.height)
>
>          self.score = games.Text(value = 0, size = 25, color = color.black,
>                                  top = 5, right = games.screen.width - 10)
>          games.screen.add(self.score)
>

This following update() is probably indented wrong.  Currently it's a 
regular function, not a method, so having a paramter 'self' is just 
weird.  If you want it to be part of the class, you'd better indent it 
to match the other defs.

> def update(self):
>      """ Move to mouse position x. """
>      self.x = games.mouse.x
>
>      if self.left < 0:
>          self.left = 0
>
>      if self.right > games.screen.width:
>          self.right = games.screen.width
>
>      self.check_catch()
>
>      def check_hit(self):
>          """ Check if hit by rcok. """
>          for rock in self.overlapping_sprites:
>              self.end_game()
>              self.destroy()
>
> class Rock(games.Sprite):
>      """
>      A rock which falls to the ground.
>      """
>      image = games.load_image("rock.jpg")
>      speed = 1
>      def __init__(self, x, y = 90):

This defines a method that can take either two or three arguments.  The 
third one has a default value.

>          """ Initiate a rock object. """
>          super(Rock, self).__init__(image = Rock.image,
>                                     x = x, y = y,
>                                     dy = rock.speed)
>
>      def update(self):
>          """ Check if bottom edge has reached screen bottom. """
>          if self.bottom > games.screen.height:
>              SPAWN = 2
>              Rock.SPAWN
>
>
>      def handle_hit(self):
>          """ Destroy self if hits chef. """
>          self.destroy()
>
>      def end_game(self):
>          """ End the game. """
>          end_message = games.Message(value = "Game Over",
>                                      size = 90,
>                                      color = color.red,
>                                      x = games.screen.width / 2,
>                                      y = games.screen.height / 2,
>                                      lifetime = 5 * games.screen.fps,
>                                      after_death = games.screen.quit)
>          games.screen.add(end_message)
>
> class Dropper(games.Sprite):
>      """
>      An invisible object that drops the rocks.
>      """
>      def __init___(self, y = 55, speed = 2, odds_change = 200):
>          """ Initialize the Dropper object. """
>          super(Dropper, self).__init__(x = games.screen.width / 2,
>                                        y = y,
>                                        dx = speed)
>          self.odds_change = odds_change
>          self.time_til_drop = 0
>
>      def update(self):
>          """ Determines if direction needs to be reversed. """
>          if self.left < 0 or self.right > games.screen.width:
>              self.dx = -self.dx
>          elif random.randrange(self.odds_change) == 0:
>              self.dx = -self.dx
>
>          self.check_drop()
>
>      def check_drop(self):
>          """ Decreases countdown or drop rock and reset countdown. """
>          if self.time_til_drop > 0:
>              self.time_til_drop -= 1
>          else:
>              new_rock = Rock(x = self.x)
>              games.screen.add(new_rock)
>          # set buffer to approx 30% of rock height, regardless of pizza speed
>          self.time_til_drop = int(new_rock.height * 1.3 / Rock.speed) + 1
>
> def main():
>      """ Play the game. """
>      backround_image = games.load_image("backround.jpg", transparent = False)
>      games.screen.backround = backround_image
>
>      the_chef = Chef()
>      games.screen.add(the_chef)
>
>      the_rock = Rock()

When creating a new instance of a class, there is an implied 'self' 
argument, and you supply no others.  So you're missing the 'x' argument. 
  It needs to get  self & x, and you're only passing self.

>      games.screen.add(the_rock)
>
>      the_dropper = Dropper()
>      games.screen.add(the_dropper)
>
>      games.mouse.is_visible = False
>
>      games.screen.event_grab = True
>      gsmes.screen.mainloop()
>
> # start it up
> main()
>
> This is the error.
>
> Exception AttributeError: "'Rock' object has no attribute '_gone'" in <bound method Rock.__del__ of <__main__.Rock object at 0x02C2F030>> ignored
>
> Traceback (most recent call last):
>    File "C:\Users\Joshua\Projects\Avalanche\Avalanche.py", line 129, in <module>
>      main()
>    File "C:\Users\Joshua\Projects\Avalanche\Avalanche.py", line 117, in main
>      the_rock = Rock()
> TypeError: __init__() takes at least 2 arguments (1 given)
>>>>
>>>>


-- 
DaveA


More information about the Tutor mailing list