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.
Related
This question already has an answer here:
Why isn't my class initialized by "def __int__" or "def _init_"? Why do I get a "takes no arguments" TypeError, or an AttributeError?
(1 answer)
Closed 2 months ago.
How do I fix this error?
I use print examination it is execution, but when I use self.rect it will be error.
Now I try to use input() and a lot of thing, but now it also didnt work.
In the "def init:" I have to use self.rect but it didnt have error.
Who can help me?
from turtle import up
import os
import pygame
import sys
from pygame.locals import Color, QUIT, MOUSEBUTTONDOWN, USEREVENT, USEREVENT
pygame.display.set_caption("666")
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
WHITE = (255, 255, 255)
IMAGEWIDTH = 300
IMAGEHEIGHT = 200
FPS = 60
pygame.init()
window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
cat_png = pygame.image.load(os.path.join("F:\py\gamepy", "cat.png")).convert()
catx = 100
ballx = 240
class Cat(pygame.sprite.Sprite):
def _init_(self):
pygame.sprite.Sprite._in(self)
self.image = cat_png
self.rect = self.image.get_rect()
self.rect.center = (WINDOW_WIDTH/2, WINDOW_HEIGHT/2)
def update(self):
key_pressed = pygame.key.get_pressed()
if key_pressed[pygame.K_w]:
self.rect.y += 2
if key_pressed[pygame.K_s]:
self.rect.y -= 2
all_sprite = pygame.sprite.Group()
cat = Cat()
all_sprite.add(cat)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
all_sprite.update()
window.fill((255, 255, 255))
window.blit(cat_png, (0,0))
pygame.display.update()
Full error:
Traceback (most recent call last):
File "f:\a.py", line 45, in <module> all_sprite.update()
File "C:\Users\user\AppData\Local\Programs\Python\Python39-32\lib\site-packages\pygame\sprite.py", line 539, in update sprite.update(*args, **kwargs)
File "f:\a.py", line 29, in update self.rect.y += 2
AttributeError: 'Cat' object has no attribute 'rect'
I think there are typos in constructor call, it should be:
def __init__(self):
pygame.sprite.Sprite.__init__(self)
but you have
def _init_(self):
pygame.sprite.Sprite._in(self)
I want to access my player position, I tried following Moving a Sprite Class from outside of the original Class in pygame but then I got "AttributeError: 'GroupSingle' object has no attribute 'rect'" as my error. I need to access player position inside my obstacle class.
This is my code:
import pygame
import os
import random
from sys import exit
pygame.init()
os.system("cls")
WIDTH = 288
HEIGHT = 512
FPS = 60
JUMP_POWER = 60
GRAVITY = 0.15
GAME_ACTIVE = 1
OBSTACLE_INTERVAL = 1000
AWAY_FROM_BIRD = 100
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("assets/images/player/bird.png").convert_alpha()
self.rect = self.image.get_rect(center = (WIDTH/4, HEIGHT/2))
self.gravity_store = 0
self.jump_sfx = pygame.mixer.Sound("assets/audio/jump.wav")
self.jump_sfx.set_volume(0.1)
def player_input(self):
for event in event_list:
if event.type == pygame.KEYDOWN:
if self.rect.bottom <= 0:
pass
else:
if event.key == pygame.K_SPACE:
self.gravity_store = 0
self.rect.y -= JUMP_POWER
self.jump_sfx.play()
def gravity(self):
self.gravity_store += GRAVITY
self.rect.y += self.gravity_store
print(int(self.gravity_store), int(clock.get_fps()))
def collision(self):
if self.rect.colliderect(ground_rect):
GAME_ACTIVE = 0
def update(self):
self.player_input()
self.gravity()
self.collision()
class Obstacles(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("assets/images/obstacles/pipe-green.png")
def obstacle_spawn(self):
#I want to access player position here
print(player.rect.x)
self.rect = self.image.get_rect(midleft = (0, 0))
def update(self):
self.obstacle_spawn()
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Mama Bird")
clock = pygame.time.Clock()
background_surf = pygame.image.load("assets/images/background/background-day.png")
ground_surf = pygame.image.load("assets/images/background/base.png")
ground_rect = ground_surf.get_rect(topleft = (0, HEIGHT-112))
player = pygame.sprite.GroupSingle()
player.add(Player())
obstacle = pygame.sprite.Group()
obstacle.add(Obstacles())
OBSTACLESPAWN = pygame.USEREVENT + 1
pygame.time.set_timer(OBSTACLESPAWN, OBSTACLE_INTERVAL)
while True:
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
pygame.quit()
exit()
SCREEN.blit(background_surf, (0,0))
player.draw(SCREEN)
player.update()
for event in event_list:
if event.type == OBSTACLESPAWN and GAME_ACTIVE == 1:
obstacle.update()
obstacle.draw(SCREEN)
SCREEN.blit(ground_surf, ground_rect)
pygame.display.update()
clock.tick(FPS)
I tried to see if it would access the player position using "print(player.rect.x)". And got this error:
Traceback (most recent call last):
File "c:\Users\46722\Documents\Programmering\Python\yesman\Pygame\Mama Bird\main.py", line 98, in <module>
obstacle.update()
File "C:\Users\46722\AppData\Local\Programs\Python\Python310\lib\site-packages\pygame\sprite.py", line 539, in update
sprite.update(*args, **kwargs)
File "c:\Users\46722\Documents\Programmering\Python\yesman\Pygame\Mama Bird\main.py", line 65, in update
self.obstacle_spawn()
File "c:\Users\46722\Documents\Programmering\Python\yesman\Pygame\Mama Bird\main.py", line 61, in obstacle_spawn
print(player.rect.x)
AttributeError: 'GroupSingle' object has no attribute 'rect'
PS C:\Users\46722\Documents\Programmering\Python\yesman\Pygame\Mama Bird>
player is an instance of pygame.sprite.Group():
player = pygame.sprite.GroupSingle()
player.add(Player())
Use the sprite property to access the pygame.sprite.Sprite in a pygame.sprite.GroupSingle:
print(player.rect.x)
print(player.sprite.rect.x)
from numpy import place
import pygame, sys ,random as ran
start = True
class Player(pygame.sprite.Sprite):
def __init__(self, pos_x, pos_y):
super().__init__()
self.attack_animation = False
self.sprites_1 = []
self.sprites_1.append(pygame.image.load('crossHair.png'))
self.sprites_1.append(pygame.image.load('crossHair_2.png'))
self.sprites_1.append(pygame.image.load('crossHair_3.png'))
self.sprites_1.append(pygame.image.load('crossHair_4.png'))
self.sprites_1.append(pygame.image.load('crossHair_5.png'))
self.sprites_1.append(pygame.image.load('FIRE.png'))
self.current_sprite = 0
self.image = self.sprites_1[self.current_sprite]
self.image.set_colorkey('white')
for items in self.sprites_1:
items.set_colorkey('white')
self.rect = self.image.get_rect()
self.rect.topleft = [pos_x,pos_y]
def attack(self):
self.attack_animation = True
self.image.set_colorkey('white')
def update(self,speed):
self.image.set_colorkey('white')
if self.attack_animation == True:
self.current_sprite += speed
if int(self.current_sprite) >= len(self.sprites_1):
self.current_sprite = 0
self.attack_animation = False
print('shot')
self.image = self.sprites_1[int(self.current_sprite)]
# self.image = self.sprites_1[int(self.current_sprite)]
mouse = pygame.mouse.get_pos()
self.rect = mouse
class enemy(pygame.sprite.Sprite):
def __init__(self, pos_x, pos_y):
super().__init__()
self.image = pygame.image.load('sp_1.png')
self.rect = self.image.get_rect()
self.rect.center = [pos_x, pos_y]
self.image.set_colorkey((255,255,255))
# General setup
pygame.init()
pygame.mouse.set_visible(0)
clock = pygame.time.Clock()
# Game Screen
screen_width = 400
screen_height = 400
mouse = pygame.mouse.get_pos()
screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption("Sprite Animation")
# Creating the sprites and groups
moving_sprites = pygame.sprite.Group()
crosshair = Player(mouse[0],mouse[1])
enemy_x = ran.randint(18,387)
enemy_y = ran.randint(18,387)
print(enemy_x,enemy_y)
enemy_ = enemy(enemy_x,enemy_y)
moving_sprites.add(enemy_,crosshair)
while True:
# Player.set_pos(*pygame.mouse.get_pos())
globals()['mouse'] = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if pygame.mouse.get_pressed()[0]:
crosshair.attack()
enemy.checkCollision(enemy,crosshair,enemy_)
# enemy.attack()
# pygame.sprite.spritecollide(Player,enemy,True)
screen.fill((120,220,150))
#this is causing the problem
get_hit = pygame.sprite.spritecollide(Player,enemy,True)
# Drawing
screen.set_colorkey('white')
moving_sprites.draw(screen)
moving_sprites.update(0.08)
pygame.display.flip()
clock.tick(120)
the movement i check for sprite collision it gives me error sayin' :
File "c:\Users\pc\VS_PYTHON_PY\pyGame.py", line 82, in
get_hit = pygame.sprite.spritecollide(Player,enemy,True)
File "C:\python-py\lib\site-packages\pygame\sprite.py", line 1682, in spritecollide
default_sprite_collide_func = sprite.rect.colliderect
AttributeError: type object 'Player' has no attribute 'rect'
why is that happening can you solve this pls
The arguments of pygame.sprite.spritecollide must be instance objects of Sprite and Group classes. Player and enemy are a classes, however crosshair and enemy_ are objects. Create a Group for the enemies and detect the collisions between the crosshair and the Group of enemies:
crosshair = Player(mouse[0],mouse[1])
enemyGroup = pygame.sprite.Group()
enemy_ = enemy(enemy_x,enemy_y)
enemyGroup.add(enemy_)
while True:
# [...]
get_hit = pygame.sprite.spritecollide(crosshair, enemyGroup, True)
See also How do you program collision in classes? and How do I detect collision in pygame?.
Also see Style Guide for Python Code: Class names should normally use the CapWords convention. The name of the class should be Enemy instead of enemy.
I am trying to learn pygame by replicating and examining this: https://www.wikihow.com/Program-a-Game-in-Python-with-Pygame#Adding_a_Player_Object_sub
however when I run either the original version(step 4) as seen above or my code
it brings me a black screen and this error:
Traceback (most recent call last):
File "C:/Users/Mohamed/Desktop/mopy/pys/first pycharm.py", line 77, in <module>
game().gameloo()
File "C:/Users/Mohamed/Desktop/mopy/pys/first pycharm.py", line 60, in gameloo
self.handle()
File "C:/Users/Mohamed/Desktop/mopy/pys/first pycharm.py", line 74, in handle
for event in pygame.event.get():
pygame.error: video system not initialized
here is my code:
import pygame
from pygame.locals import *
pygame.init()
resolution = (400, 350)
white = (250, 250, 250)
black = (0, 0, 0)
red = (250, 0, 0)
green = (0, 250, 0)
screen = pygame.display.set_mode(resolution)
class Ball:
def __init__(self, xPos=resolution[0] / 2, yPos=resolution[1] / 2, xVel=1, yVel=1, rad=15):
self.x = xPos
self.y = yPos
self.dx = xVel
self.dy = yVel
self.radius = rad
self.type = "ball"
def draw(self, surface):
pygame.draw.circle(surface, black, (int(self.x), int(self.y)), self.radius)
def update(self):
self.x += self.dx
self.y += self.dy
if (self.x <= 0 or self.x >= resolution[0]):
self.dx *= -1
if (self.y <= 0 or self.y >= resolution[1]):
self.dy *= -1
class player:
def __init__(self, rad=20):
self.x = 0
self.y = 0
self.radius = rad
def draw(self, surface):
pygame.draw.circle(surface, red, (self.x, self.y))
ball = Ball()
class game():
def __init__(self):
self.screen = pygame.display.set_mode(resolution)
self.clock = pygame.time.Clock()
self.gameobjct = []
self.gameobjct.append(Ball())
self.gameobjct.append(Ball(100))
def handle(self):
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
def gameloo(self):
self.handle()
for gameobj in self.gameobjct:
gameobj.update()
screen.fill(green)
for gameobj in self.gameobjct:
gameobj.draw(self.screen)
pygame.display.flip()
self.clock.tick(60)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
game().gameloo()
You've initialized the window twice pygame.display.set_mode(). Remove the global window initialization, but keep and use the window set to the .screen attribute of the class game.
The method handle should only do the event loop, but the method gameloo should contain the main loop. Inside the main loop the events have to be handled by self.handle():
screen = pygame.display.set_mode(resolution)
class game():
def __init__(self):
self.screen = pygame.display.set_mode(resolution)
self.clock = pygame.time.Clock()
self.gameobjct = []
self.gameobjct.append(Ball())
self.gameobjct.append(Ball(100))
def handle(self):
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
def gameloo(self):
while True:
self.handle()
for gameobj in self.gameobjct:
gameobj.update()
self.screen.fill(green)
for gameobj in self.gameobjct:
gameobj.draw(self.screen)
pygame.display.flip()
self.clock.tick(60)
game().gameloo()
I am currently learning the code from a tutorial on Pygame Game Development:
https://www.youtube.com/watch?v=fcryHcZE_sM
I have copied the code exactly into Pycharm and I believe it should work.
#Pygame Sprite Example
import pygame
import random
import os
WIDTH = 360
HEIGHT = 480
FPS = 30
#Colours
BLACK = (0, 0, 0)
WHITE= (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# set up assets folders
game_folder = os.path.dirname(__file__)
img_folder = os.path.join(game_folder, "img")
class Player(pygame.sprite.Sprite):
# sprite for the player
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(os.path.join(img_folder, "p1_jump.png")).convert()
self.image.set_colourkey(BLACK)
self.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT / 2)
def update(self):
self.rect.x += 5
if self.rect.left > WIDTH:
self.rect.right = 0
#initialise pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("My Game")
clock = pygame.time.Clock()
all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
#Game Loop
running = True
while running:
#keep loop running at right speed
clock.tick(FPS)
#Process Input/Events
for event in pygame.event.get():
#check for closing window
if event.type == pygame.QUIT:
running = False
#Update
all_sprites.update()
#Draw/Render
screen.fill(BLUE)
all_sprites.draw(screen)
# *after drawing everything, flip the display*
pygame.display.flip()
pygame.quit()
it gives me this error when I run it:
C:\Users\George\PycharmProjects\app\venv1\Scripts\python.exe "C:/Users/George/Documents/School/Year 12/IT/Coursework/SpriteExample.py"
Traceback (most recent call last):
File "C:/Users/George/Documents/School/Year 12/IT/Coursework/SpriteExample.py", line 46, in <module>
player = Player()
File "C:/Users/George/Documents/School/Year 12/IT/Coursework/SpriteExample.py", line 28, in __init__
self.image = pygame.image.load(os.path.join(img_folder, "p1_jump.png")).convert()
pygame.error: Couldn't open C:/Users/George/Documents/School/Year 12/IT/Coursework\img\p1_jump.png
Process finished with exit code 1
In the tutorial video, the guy is using a Mac, and I am using a Windows laptop (running Windows 7).
I have tried researching around the site and I couldn't find anything specific enough to my error. I also tried changing the code in and just above the initialization of the class Player to this:
game_folder = os.path.dirname(os.path.abspath(__file__))
img_folder = os.path.join(game_folder, "img")
image1 = pygame.image.load(os.path.join(img_folder, "p1_jump.png" ))
class Player(pygame.sprite.Sprite):
# sprite for the player
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = image1.convert()
self.image.set_colourkey(BLACK)
self.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT / 2)
and it still didn't work.
If you make a little python file name it my_path.py or similar and place it in documents folder and run it.
It will help you see that the sprite2.py file should be in documents folder and that you will need a sub folder within documents that is labelled 'img' and contains the 'png' file. Then the game should run ok. Therefore the game_folder is actually 'documents folder' and img_folder is img within documents. I hope that is a little clearer then the code above or within sprite2.py can be tinkered with if you have game in another folder
game_folder = os.path.dirname(__file__)
print(game_folder)
img_folder = os.path.join(game_folder, "img")
print(img_folder)