So here is my code this my code and I don't know what have I done wrong is this code.
main.py
import pygame
import sys
from setting import Setting
from ship import Ship
class AlienInvasion:
def __init__(self):
pygame.init()
self.setting = Setting()
self.bg_color = (230, 230, 230)
self.screen = pygame.display.set_mode((self.setting.screen_width, self.setting.screen_height))
pygame.display.set_caption("ALien Invasion")
self.ship = Ship(self)
def run_game(self):
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
self.screen.fill(self.bg_color)
pygame.display.flip()
self.screen.fill(self.setting.bg_color)
self.ship.blitme()
if __name__ == '__main__':
ai = AlienInvasion()
ai.run_game()
I dono that could it be an error about my file location or not
import pygame
class Ship:
def __init__(self, ai_game):
self.screen = ai_game.screen
self.screen_rect = ai_game.screen.get_rect()
self.image = ai_game.image.load('images\spaceship')
self.rect = self.image.get_rect()
self.rect.midbottom = self.screen_rect.midbottom
def blitme(self):
self.screen.blit(self.image, self.rect)
Here is my error
this is what I got
Traceback (most recent call last):
File "C:\Users\PC\PycharmProjects\pygame\main.py", line 25, in <module>
ai = AlienInvasion()
File "C:\Users\PC\PycharmProjects\pygame\main.py", line 13, in __init__
self.ship = Ship(self)
File "C:\Users\PC\PycharmProjects\pygame\ship.py", line 7, in __init__
self.image = ai_game.image.load('images\spaceship')
AttributeError: 'AlienInvasion' object has no attribute 'image'
In your __init__() function of the ship class, you used ai_game.image.load. ai_game is here your AlienInvasion object. I think you intended to use pygame.image.load instead.
Related
I am learning python and started creating a game called alienshooter but after creating class form ship, the code fails and give the error;
'AlienShooter' object has no attribute 'screen'
this is the code:
main.py
import sys
import pygame
from settingsPY import Setting
from ShipPY import Ship
class AlienShooter:
def __init__(self):
pygame.init()
self.settingsPY = Setting()
self.ShipPY = Ship(self)
self.screen = pygame.display.set_mode((self.settingsPY.screen_width, self.settingsPY.screen_height ))
pygame.display.set_caption("AlienShooter")
def run_game(self):
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
self.screen.fill(self.settingsPY.bg_color)
self.ShipPY.blitme()
pygame.display.flip()
if __name__ == '__main__':
ai = AlienShooter()
ai.run_game()
ShipPY
import pygame
class Ship:
def __init__(self, ai_game):
self.screen = ai_game.screen
self.screen_rect = ai_game.screen.get_rect()
self.image = pygame.image.load('images/Ship.bmp')
self.rect = self.image.get_rect()
self.rect.midbottom = self.screen_rect.midbotttom
def blitme(self):
self.screen.blit(self.image, self.rect)
settingsPY
class Setting:
def __init__(self):
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (230, 230, 230)
You must initiate the display and set self.screen before you create the ship with Ship(self), because the screen attribute is required in the constructor of the Ship class:
class AlienShooter:
def __init__(self):
pygame.init()
self.settingsPY = Setting()
self.screen = pygame.display.set_mode((self.settingsPY.screen_width, self.settingsPY.screen_height ))
pygame.display.set_caption("AlienShooter")
self.ShipPY = Ship(self)
The constructor of Ship tries to access the screen variable before it's set:
...
self.ShipPY = Ship(self)
self.screen = pygame.display.set_mode((self.settingsPY.screen_width, self.settingsPY.screen_height ))
...
In this part of the code the ship gets initialized and afterwards the screen variable gets assigned. The constructor of Ship uses this screen variable, but as it's assigned after the creation of the ship, the contructor will not be able to access it and raise the error.
A quick way to fix this is to swap the two lines so that first the screen is assigned and afterwards the ship object is constructed:
...
self.screen = pygame.display.set_mode((self.settingsPY.screen_width, self.settingsPY.screen_height ))
self.ShipPY = Ship(self)
...
I'm new to coding and just started reading "Python Crash Course" around a month back. While working on one of the projects, I encountered this error: AttributeError: 'AlienInvasion' object has no attribute 'blit'
Code:
main:
import sys
import pygame
from settings import Settings
from ship import Ship
class AlienInvasion:
'''overall class to manage game behavior'''
def __init__(self):
'''initialize pygame'''
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode(
(self.settings.screen_width, self.settings.screen_height))
pygame.display.set_caption("Alien Invasion")
self.ship = Ship(self)
# bg color
self.bg_color = (230, 230, 230)
def run_game(self):
'''main loop'''
while True:
# watch for keyboard and mouse events
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# draw screen
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
# make most recent screen visible
pygame.display.flip()
if __name__ == '__main__':
# make an instance of game
ai = AlienInvasion()
ai.run_game()
ship:
import pygame
class Ship:
'''class to manage ship'''
def __init__(self, ai_game):
'''initialize ship and start pos'''
self.screen = ai_game
self.screen_rect = ai_game.screen.get_rect()
# load ship
self.image = pygame.image.load('images/ship.bmp')
self.rect = self.image.get_rect()
# start each new ship
self.rect.midbottom = self.screen_rect.midbottom
def blitme(self):
'''draw a ship at current location'''
self.screen.blit(self.image, self.rect)
full error msg:
Traceback (most recent call last):
File "C:\Users\richh\PycharmProjects\pythonProject\alien_shooter\main.py", line 39, in <module>
ai.run_game()
File "C:\Users\richh\PycharmProjects\pythonProject\alien_shooter\main.py", line 32, in run_game
self.ship.blitme()
File "C:\Users\richh\PycharmProjects\pythonProject\alien_shooter\ship.py", line 18, in blitme
self.screen.blit(self.image, self.rect)
AttributeError: 'AlienInvasion' object has no attribute 'blit'
The problem is that you are confused over whether you are sending the entier AlienInvasion instance to Ship, or just the pygame screen. There are two ways to clear that up. Instead of this:
import pygame
class Ship:
'''class to manage ship'''
def __init__(self, ai_game):
'''initialize ship and start pos'''
self.screen = ai_game
self.screen_rect = ai_game.screen.get_rect()
just save the screen item:
self.screen = ai_game.screen
self.screen_rect = ai_game.screen.get_rect()
A better way would be just to pass the pygame instance, instead of the whole AlienInvasion instance. So, in AlienInvasion, change this:
self.ship = Ship(self)
to this:
self.ship = Ship(self.screen)
Then in Ship, change the last line of this:
def __init__(self, ai_game):
'''initialize ship and start pos'''
self.screen = ai_game
self.screen_rect = ai_game.screen.get_rect()
to this:
self.screen_rect = ai_game.get_rect()
In the file ship.py, in the line:
self.screen = ai_game
It's supposed to be:
self.screen = ai_game.screen
Doing this would make the attribute screen in Ship to be equal to the attribute screen in your main. Only then you could pass in the values of screen in main to your blit function.
I am learning Python from the book, "PYTHON CRASH COURSE: A Hands-On, Project-Based Introduction to Programming", 2E.
In that while making game, I am getting the error
Traceback (most recent call last):
File "d:\BOOKS\python\my-projects\AlienInvasion\tempCodeRunnerFile.py", line 69, in <module>
alinv = AlienInvasion()
File "d:\BOOKS\python\my-projects\AlienInvasion\tempCodeRunnerFile.py", line 22, in __init__
self.ship = Ship(self.screen)
File "d:\BOOKS\python\my-projects\AlienInvasion\ship.py", line 10, in __init__
self.screen = alinv_game.screen
AttributeError: 'pygame.Surface' object has no attribute 'screen'
My Code is:
AlienInvasion.py
# Importing modules
import sys
import pygame
from settings import Settings
from ship import Ship
class AlienInvasion:
'''Class to manage game assets and behavior'''
def __init__(self):
'''Constructor to initialize the game and its assets'''
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
self.settings.screen_width = self.screen.get_rect().width
self.settings.screen_height = self.screen.get_rect().height
pygame.display.set_caption("Alien Invasion")
self.ship = Ship(self.screen)
def run_game(self):
'''Starts the main loop for the game'''
while True:
self._check_events()
self.ship.update()
self._update_screen()
def _check_events(self):
'''Watch for the keyboard and mouse events'''
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
self._check_keydown_events(event)
elif event.type == pygame.KEYUP:
self._check_keyup_events(event)
def _check_keydown_events(self, event):
"""Respond to keypresses."""
if event.key == pygame.K_RIGHT:
self.ship.moving_right = True
elif event.key == pygame.K_LEFT:
self.ship.moving_left = True
elif event.key == pygame.K_ESCAPE:
sys.exit()
def _check_keyup_events(self, event):
"""Respond to key releases."""
if event.key == pygame.K_RIGHT:
self.ship.moving_right = False
elif event.key == pygame.K_LEFT:
self.ship.moving_left = False
def _update_screen(self):
'''Redraw the screen during each pass of the loop'''
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
'''Make the most recently drawn screen visible'''
pygame.display.flip()
if __name__ == '__main__':
'''Make a game instance, and run the game'''
alinv = AlienInvasion()
alinv.run_game()
ship.py
import pygame
class Ship:
'''A class to manage the ship'''
def __init__(self, alinv_game):
'''Initialize the ship and set its starting position'''
self.screen = alinv_game.screen
self.settings = alinv_game.settings
self.screen_rect = alinv_game.screen.get_rect()
'''Load the ship image and get its rect'''
self.image = pygame.image.load('images/ship.bmp')
self.rect = self.image.get_rect()
'''Start each new ship at the bottom-center of the screen'''
self.rect.midbottom = self.screen_rect.midbottom
'''Store a decimal value for ship's horizontal position'''
self.x = float(self.rect.x)
'''Movement Flag'''
self.moving_right = False
self.moving_left = False
def update(self):
if self.moving_right and self.rect.right < self.screen_rect.right:
self.x += self.settings.ship_speed
if self.moving_left and self.rect.left > 0:
self.x -= self.settings.ship_speed
'''Update rect obj from self.x'''
self.rect.x = self.x
def blitme(self):
'''Draw the ship at its current location.'''
self.screen.blit(self.image, self.rect)
In the update method of class Ship, I Implemented two separate blocks to allow ship.rect.x value
to be increased and then decreased when both left and right
arrow keys are pressed. Otherwise, the self.moving_right will
have more priority if 'elif' is implemented.
settings.py
class Settings:
'''A class to store all settings for Alien Invasion Game.'''
def __init__(self):
'''Initialize the game's settings'''
# Screen Settings:
self.screen_width = 1280
self.screen_height = 720
self.bg_color = (230, 230, 230)
# Ship Settings:
self.ship_speed = 1.5
I think the error should be with the screen declaration because I think Pygame.Surface do not have 'screen' attribute but we can though get it by get_rect method. Kindly help me finding the bug. I am not able to solve the issue.
I believe you meant to make the line self.ship = Ship(self.screen) say self.ship = Ship(self). That way the Ship object can access all of the attributes of the AlienInvasion object, instead of just it's screen attribute (and that attribute doesn't have a screen attribute, thus the error).
I am stuck on a game writing exercise from a beginner Python book called Python Crash Course. At this point, it's very basic. It's only supposed to create a window where an image of the ship would load in the bottom center. I'm certain that I copied the code almost line for line, and encountered examples online that pretty much do what I did here, but I still keep getting the following error:
Traceback (most recent call last):
File "c:/Users/.../chapteraliens/alien_invasion.py", line 40, in <module>
ai = AlienInvasion()
File "c:/Users/.../chapteraliens/alien_invasion.py", line 17, in __init__
self.ship = Ship(self)
File "c:\Users\...\chapteraliens\ship.py", line 9, in __init__
self.screen_rect = screen.get_rect()
AttributeError: 'AlienInvasion' object has no attribute 'get_rect'
And here are the 3 files that I have created. I don't think it has anything to do with settings.py, but I included it just in case because it's very short.
alien_invasion.py
import sys
import pygame
from settings import Settings
from ship import Ship
class AlienInvasion:
"""Overall class to manage game assets and behavior."""
def __init__(self):
"""Initialize the game and create the game resources."""
pygame.init()
pygame.display.set_caption("Alien Invasion")
self.settings = Settings()
self.ship = Ship(self)
self.bg_color = (self.settings.bg_color)
self.screen = pygame.display.set_mode(
(self.settings.screen_width, self.settings.screen_height))
def run_game(self):
"""Start the main loop for the game."""
while True:
"""Watch for the keyboard and mouse events."""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# Set the visual elements of the game.
self.screen.fill(self.bg_color)
self.ship.blitme()
# Make the most recently drawn screen visible.
pygame.display.flip()
if __name__ == "__main__":
# Make a game instance, and run the game.
ai = AlienInvasion()
ai.run_game()
ship.py
import pygame
class Ship:
"""The class that handles the management of the ship."""
def __init__(self, screen):
"""Initialize the ship and set up the starting position."""
self.screen = screen
self.screen_rect = screen.get_rect()
# Load the ship image and get its rect.
self.image = pygame.image.load("ship_w.bmp")
self.rect = self.image.get_rect()
# Start each new ship at the bottom of center of the screen.
self.rect.midbottom = self.screen_rect.midbottom
def blitme(self):
"""Draw the ship at its current location."""
self.screen.blit(self.image, self.rect)
settings.py
class Settings:
"""A class to store settings for the game."""
def __init__(self):
"""Initialize the game's settings."""
# Screen settings
self.screen_width = 800
self.screen_height = 600
self.bg_color = (40, 40, 40)
I then tried to comment out the lines to do with the get_rect error, but that only made it so that the same error appeared with the "blit" line this time. The lines that I commented out and the new error is as follows:
...
# self.screen_rect = screen.get_rect()
...
# self.rect.midbottom = self.screen_rect.midbottom
...
Traceback (most recent call last):
File "c:/Users/.../chapteraliens/alien_invasion.py", line 41, in <module>
ai.run_game()
File "c:/Users/.../chapteraliens/alien_invasion.py", line 33, in run_game
self.ship.blitme()
File "c:\Users\...\chapteraliens\ship.py", line 20, in blitme
self.screen.blit(self.image, self.rect)
AttributeError: 'AlienInvasion' object has no attribute 'blit'
Might it be that I'm using the get_rect() and blit() functions incorrectly somehow? And that's if the whole thing is not a simple small error that wasn't able to catch.
Ship() expects screen as argument but in AlienInvasion.__init__ you use self in Ship(self) so you use instace of AlienInvasion, not screen - so later it tries to get AlienInvasion.get_rect() and you get your error.
You have to first create self.screen and then use it with Ship()
self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
self.ship = Ship(self.screen)
I'm developing a Space Invaders clone using Python 3.5.1 and PyGame. My issue is that I cannot manage to load my sprites onto the screen. I keep receiving the error:
Traceback (most recent call last):
File "C:\Users\supmanigga\Documents\Space Invaders\spaceinvaders.py", line 44, in
allSprites.draw(screen)
File "C:\Users\supmanigga\AppData\Local\Programs\Python\Python35\lib\site-packages\pygame\sprite.py", line 475, in draw
self.spritedict[spr] = surface_blit(spr.image, spr.rect)
AttributeError: 'Ship' object has no attribute 'image'
My code is as follows:
import pygame
import sys
width = 500
height = 700
white = (255, 255, 255)
black = (0, 0, 0)
score = 0
screen = pygame.display.set_mode([width, height])
class Ship(pygame.sprite.Sprite):
def _init_(self):
sprite.Sprite._init_(self)
self.image = pygame.image.load("player").convert()
self.rect = self.image.get_rect()
class Enemy(pygame.sprite.Sprite):
def _init_(self):
sprite.Sprite._init_(self)
self.image = pygame.image.load("enemy").convert()
self.rect = self.image.get_rect()
class Bullet(pygame.sprite.Sprite):
def _init_(self):
sprite.Sprite._init_(self)
self.image = pygame.image.load("laser").convert()
self.rect = self.image.get_rect()
player = Ship()
allSprites = pygame.sprite.Group()
allSprites.add(player)
running = True
while running == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill(black)
allSprites.draw(screen)
pygame.display.flip()
pygame.quit()
def _init_(self): should be def __init__(self):
Otherwise, the line self.image = pygame.image.load("player").convert() is never executed, and thus your Ship instance will have no image attribute.