AlpineXJedi
AlpineXJedi

Reputation: 1

Attribute Error when Trying to add instances of Bullet class

https://github.com/TheManhattan/ErrorCode

I have provided a link to a repository with the complete code because I feel it may be necessary to fully grasp the problem. I am creating a game using pygame and I'm trying to add bullet behavior. The trace back is pulling me towards the Bullet class.

Traceback (most recent call last):
  File "C:/Users/Andrew/Desktop/Shooting Game Project/shooting_game.py", line 32, in <module>
run_game()
  File "C:/Users/Andrew/Desktop/Shooting Game Project/shooting_game.py", line 26, in run_game
gf.check_events(ai_settings, screen, ship, bullets)
   File "C:\Users\Andrew\Desktop\Shooting Game Project\game_functions.py", line 17, in check_events
check_keydown_events(event, ai_settings, screen, ship, bullets)
  File "C:\Users\Andrew\Desktop\Shooting Game Project\game_functions.py", line 35, in check_keydown_events
new_bullet = Bullet(ai_settings, screen, ship)
  File "C:\Users\Andrew\Desktop\Shooting Game Project\bullet.py", line 14, in __init__
self.rect = pygame.Rect(0, 0, self.ai_settings.bullet_width, self.ai_settings.bullet_height)
AttributeError: 'pygame.Surface' object has no attribute 'bullet_width'

I'm thinking this has to be the incorrect syntax or usage of pygame.Rect but everything I can find on the subject tells me that the usage and syntax is indeed correct.

So, moving on from this and assuming I just input the width and height manually instead of referencing the Settings class.. I get the same traceback with an error corresponding to the line below it. This is even more confusing to me because I cant see how the Settings class even comes into play when defining an attribute for the bullet rectangle. The Ship class is referenced from an instance of Ship being created in the run_game() function but the rectangle attribute of the Ship class does not reference any information stored in the Settings class.

File "C:\Users\Andrew\Desktop\Shooting Game Project\bullet.py", line 15, in __init__
self.rect.center.x = ship.rect.centerx
AttributeError: 'Settings' object has no attribute 'rect'

Any insight that you guys can offer would be greatly appreciated.

Thank you in advance

Upvotes: 0

Views: 101

Answers (1)

lortimer
lortimer

Reputation: 710

The problem is in game_functions.py. Your call to check_keydown_events doesn't match its signature.

Notice that check_keydown_events is expecting 5 parameters called "event", "ship", "ai_settings", "screen", and "bullets" in that order. You call check_keydown_events inside check_events and pass in the same 5 arguments, but in the wrong order.

def check_events(ai_settings, screen, ship, bullets):
    ...
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event, ai_settings, screen, ship, bullets)
    ...


def check_keydown_events(event, ship, ai_settings, screen, bullets):
     ...

check_keydown_events's third parameter is ai_settings, but when you call it, the third parameter is a variable called screen, which is a pygame.Surface object.

You're allowed to pass anything you want into a method, but if it doesn't have the attributes the method is expecting, you'll get this kind of exception. Changing the signature of check_keydown_events to match the call should work:

def check_events(ai_settings, screen, ship, bullets):
    ...
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event, ai_settings, screen, ship, bullets)
    ...


def check_keydown_events(event, ai_settings, screen, ship, bullets):
     ...

Upvotes: 1

Related Questions