I tried to draw obstacle on screen but got an error in return and now im stuck :/
Here is my obstacle class :
class Obstacle(pygame.sprite.Sprite):
def __init__(self,type):
super().__init__()
if type == 'fly':
self.snail_1 = pygame.image.load("graphics\\snail1.png").convert_alpha()
self.snail_2 = pygame.image.load("graphics\\snail2.png").convert_alpha()
self.snail_frames = [self.snail_1,self.snail_2]
self.snail_index = 0
else:
self.fly_1 = pygame.image.load("graphics\\fly1.png").convert_alpha()
self.fly_2 = pygame.image.load("graphics\\fly2.png").convert_alpha()
self.fly_frames = [self.fly_1, self.fly_2]
self.fly_index = 0
self.rect = self.fly_1.get_rect(midbottom = (200,210))
Here is sprite.Group:
obstacle_group = pygame.sprite.Group()
obstacle_group.add(Obstacle('fly'))
and here is my method to draw:
obstacle_group.draw(screen)
What i'm doing wrong here ?
Traceback (most recent call last):
File "C:\Users\Marcin\PycharmProjects\tutorial\main.py", line 105, in <module>
obstacle_group.draw(screen)
File "C:\Users\Marcin\PycharmProjects\tutorial\venv\lib\site-packages\pygame\sprite.py", line 552, in draw
zip(sprites, surface.blits((spr.image, spr.rect) for spr in sprites))
File "C:\Users\Marcin\PycharmProjects\tutorial\venv\lib\site-packages\pygame\sprite.py", line 552, in <genexpr>
zip(sprites, surface.blits((spr.image, spr.rect) for spr in sprites))
AttributeError: 'Obstacle' object has no attribute 'image'
Process finished with exit code 1
pygame.sprite.Group.draw() and pygame.sprite.Group.update() is a method which is provided by pygame.sprite.Group. It uses the image and rect attributes of the contained pygame.sprite.Sprites to draw the objects — you have to ensure that the pygame.sprite.Sprites have the required attributes. See pygame.sprite.Group.draw():
Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect. [...]
Therefore the pygame.sprite.Sprite must have an image and a rect attribute which can be used to draw the object. e.g.:
class Obstacle(pygame.sprite.Sprite):
def __init__(self,type):
super().__init__()
if type == 'fly':
self.snail_1 = pygame.image.load("graphics\\snail1.png").convert_alpha()
self.snail_2 = pygame.image.load("graphics\\snail2.png").convert_alpha()
self.snail_frames = [self.snail_1,self.snail_2]
self.snail_index = 0
self.image = self.snail_1
self.rect = self.image.get_rect(midbottom = (200,210))
else:
self.fly_1 = pygame.image.load("graphics\\fly1.png").convert_alpha()
self.fly_2 = pygame.image.load("graphics\\fly2.png").convert_alpha()
self.fly_frames = [self.fly_1, self.fly_2]
self.fly_index = 0
slef.image = self.fly_1
self.rect = self.image.get_rect(midbottom = (200,210))
Related
i am running into two error going two routes the ball is find works great but the score text wont work, every time i implement it it throws the two errors.
from superwires import games, color
from random import *
"""Main application file"""
#the screen width and height
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
points = 0
score = 0
"""Paddle object that is controlled by the player. Moves up and down. Collides with the ball. Points are added when ball is collided with"""
class Paddle(games.Sprite):
HEIGHT = 480/20
paddle_image = games.load_image('paddle.png', transparent=True)
def __init__(self):
super(Paddle, self).__init__(image = Paddle.paddle_image,
x = 40,
y = 50,
is_collideable=True)
self.score = games.Text(value = 0,
size = 30,
color = color.green,
x = SCREEN_WIDTH - 25,
y = SCREEN_HEIGHT - 431)
games.screen.add(self.score)
games.screen.mainloop()
""" updates Position based on mouse Position"""
def update(self):
self.y = games.mouse.y
self.Check_Collision()
def Check_Collision(self):
for PongBall in self.overlapping_sprites:
PongBall.handle_collide()
"""actual ball in play """
class PongBall(games.Sprite):
#velocity variables
vel_x = 5
vel_y = 0
#pos of boundry to ball pos
lower_bounds_check = 0
upper_bounds_check = 0
#checks if paddle gets collided with
def handle_collide(self):
if((SCREEN_WIDTH/2) < self.x):
PongBall.vel_x = randint(-10,-5)
PongBall.vel_y = randint(-10,-5)
elif((SCREEN_WIDTH/2) > self.x):
PongBall.vel_x = randint(5,10)
PongBall.vel_y = randint(5,10)
#checks if it hit the bottom; bool function
def check_boundry_lower(self):
PongBall.lower_bounds_check = (SCREEN_HEIGHT/2)
return ((self.y - PongBall.upper_bounds_check) > PongBall.lower_bounds_check)
#checks if it hits the top; bool function
def check_boundry_upper(self):
PongBall.upper_bounds_check = (SCREEN_HEIGHT/2)
return ((self.y + PongBall.upper_bounds_check) < PongBall.upper_bounds_check)
#Resets the velocity based on boundry collision
def boundry_update(self):
if(self.check_boundry_upper()):
PongBall.vel_y = randint(5,10)
return
elif(self.check_boundry_lower()):
PongBall.vel_y = randint(-10,-5)
return
def update(self):
self.boundry_update()
self.x += PongBall.vel_x
self.y += PongBall.vel_y
"""
Entry point Function
"""
# Create background, paddle, and ball. Then call the game mainloop.
# crate the window
games.init(SCREEN_WIDTH, SCREEN_HEIGHT, 50, virtual = False)
#sets/loads background
background = games.load_image(f"background.png", transparent=True)
games.screen.background = background
# paddle image
paddle_image = games.load_image(f"paddle.png", transparent = True)
#PingPong ball
PingPongBall = games.load_image(f"Ball.png", transparent = True)
#paddle Right and left
paddle_1 = Paddle()
paddle_2 = Paddle()
#pingball ball instance
ball = PongBall(image = PingPongBall, x = 150, y = 250, is_collideable=True)
#adding all three sprites to screen
games.screen.add(ball)
games.screen.add(paddle_1)
games.screen.add(paddle_2)
#each instance update function
ball.update()
paddle_1.update()
paddle_2.update()
#adding text
#main loop
games.screen.mainloop()
i get this error;
Traceback (most recent call last):
File "C:\Users\gamer\Desktop\PingPong\main.py", line 15, in <module>
class Paddle(games.Sprite):
File "C:\Users\gamer\Desktop\PingPong\main.py", line 17, in Paddle
paddle_image = games.load_image('paddle.png', transparent=True)
File "C:\Users\gamer\AppData\Local\Programs\Python\Python310\lib\site-packages\superwires\games.py", line 836, in load_image
if not screen.virtual:
AttributeError: 'NoneType' object has no attribute 'virtual'
Please help i cant seem to escape the error even if i dont pass through the constructor i get text object doesnt not have handle_collide() attribute
-Thanks guys
new error:
Traceback (most recent call last):
File "C:\Users\gamer\Desktop\PingPong\main.py", line 153, in <module>
games.screen.mainloop()
File "C:\Users\gamer\AppData\Local\Programs\Python\Python310\lib\site-packages\superwires\games.py", line 783, in mainloop
sprite._process_sprite()
File "C:\Users\gamer\AppData\Local\Programs\Python\Python310\lib\site-packages\superwires\games.py", line 440, in _process_sprite
self.update()
File "C:\Users\gamer\Desktop\PingPong\main.py", line 40, in update
self.Check_Collision()
File "C:\Users\gamer\Desktop\PingPong\main.py", line 36, in Check_Collision
PongBall.handle_collide()
AttributeError: 'Text' object has no attribute 'handle_collide'
You need to have the games.load in the __init__ function so as not to call it before the environment is set up.
Replace this:
class Paddle(games.Sprite):
HEIGHT = 480/20
paddle_image = games.load_image('paddle.png', transparent=True)
def __init__(self):
super(Paddle, self).__init__(image = Paddle.paddle_image,
x = 40,
y = 50,
is_collideable=True)
with this:
class Paddle(games.Sprite):
HEIGHT = 480/20
def __init__(self):
self.paddle_image = games.load_image('paddle.png', transparent=True)
super(Paddle, self).__init__(image = self.paddle_image,
x = 40,
y = 50,
is_collideable=True)
I am trying to get pixel perfect collision but I keep running into this error:
Traceback (most recent call last):
File "D:\Projects\games\venv\lib\site-packages\pygame\sprite.py", line 1528, in collide_circle
xdistance = left.rect.centerx - right.rect.centerx
AttributeError: 'pygame.mask.Mask' object has no attribute 'rect'
Process finished with exit code 1
I am not sure of what's going wrong. Is it my implementation or logic or maybe both?
My code:
class AlienShooting(pygame.sprite.Sprite):
def __init__(self, w=640, h=640):
# init display
# init game state
self.spaceship_main = pygame.image.load('spacecraft_1.png').convert_alpha()
self.alien_spacecraft1 = pygame.image.load('spacecraft_alien.png').convert_alpha()
self.alien_spacecraft_rec1 = self.alien_spacecraft1.get_rect()
self.mask1 = pygame.mask.from_surface(self.alien_spacecraft1)
self.main_spaceship_mask = pygame.mask.from_surface(self.spaceship_main)
def play_step(self):
# user input
# Move the spaceship
# check if game over
game_over = False
if self._is_collision():
game_over = True
# Add new alien spaceships
# Randomly move alien spaceships
# update ui and clock
# return game over and score
return False
def _is_collision(self):
if pygame.sprite.collide_circle(self.mask1, self.main_spaceship_mask):
return True
return False
It might be because both my main space ship and my alien spaceship are in the same class, but I'm not sure.
See How do I detect collision in pygame? and Pygame mask collision. If you want to use pygame.sprite.collide_circle() or pygame.sprite.collide_mask you have to create pygame.sprite.Sprite objects.
spaceship_main and alien_spacecraft1 have to be Sprite objects. Sprite objects must have a rect and image attribute and can optionally have a mask attribute.
e.g.:
class AlienShooting():
def __init__(self, w=640, h=640):
self.spaceship_main = pygame.sprite.Sprite()
self.spaceship_main.image = pygame.image.load('spacecraft_1.png').convert_alpha()
self.spaceship_main.rect = self.spaceship_main.image.get_rect(center = (140, 140))
self.spaceship_main.mask = pygame.mask.from_surface(self.spaceship_main.image)
self.alien_spacecraft1 = pygame.sprite.Sprite()
self.alien_spacecraft1.image = pygame.image.load('spacecraft_alien.png').convert_alpha()
self.alien_spacecraft1.rect = self.alien_spacecraft1.image.get_rect(center = (160, 160))
self.alien_spacecraft1.mask = pygame.mask.from_surface(self.alien_spacecraft1.image)
def _is_collision(self):
if pygame.sprite.collide_mask(self.spaceship_main, self.alien_spacecraft1):
return True
return False
I'm creating a Pong game as a fun project to learn python and pygame. I am currently having an issue, mentioned above. Please ignore my slop that is code lol. The relevant code:
ballVelX = 5
ballVelY = 5
ballWidth = 15
ballHeight = 15
ballX = 450
ballY = 300
class ballcl:
def __init(self, ballX, ballY, ballVelX, ballVelY, ballWidth, ballHeight):
self.ballX = ballX
self.ballY = ballY
self.ballVelX = ballVelX
self.ballVelY = ballVelY
self.ballWidth = ballWidth
self.ballHeight = ballHeight
def ball(self):
ball = pygame.draw.rect(screen, white, [self.ballX, self.ballY, self.ballWidth, self.ballHeight])
ball
#ball movement
self.ballX += self.ballVelX
ballOb = ballcl()
gameRunning = True
while gameRunning:
ballOb.ball()
The error i receive is:
Traceback (most recent call last):
File "d:/Ping/Main.py", line 67, in <module>
ballOb.ball()
File "d:/Ping/Main.py", line 49, in ball
ball = pygame.draw.rect(screen, white, [self.ballX, self.ballY, self.ballWidth, self.ballHeight])
AttributeError: 'ballcl' object has no attribute 'ballX'
See Classes. The name of the constructor of a class is __init__ rather than __init:
class ballcl:
def __init__(self, ballX, ballY, ballVelX, ballVelY, ballWidth, ballHeight):
# [...]
I get an error from my code and I don't know why, but syntactically, it's correct, I guess
import pygame
class BaseClass(pygame.sprite.Sprite):
allsprites = pygame.sprite.Group()
def __init__(self, x, y, width, height, image_string):
pygame.sprite.Sprite.__init__(self)
BaseClass.allsprites.add(self)
self.image = pygame.image.load("Images\lebron.png")
self.rectangle = self.image.get_rect()
self.rectangle.x = x
self.rectangle.y = y
self.width = width
self.height = height
class Lebron(BaseClass):
List = pygame.sprite.Group()
def __init__(self, x, y, width, height, image_string):
BaseClass.__init__(self, x, y, width, height, image_string)
Lebron.List.add(self)
self.velx = 0
def movement(self):
self.rectangle.x += self.velx
so if i compile this to my main file, code below
import pygame, sys
from classes import *
from process import process
pygame.init()
WIDTH, HEIGHT = 640, 360
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
FPS = 24
lebron = Lebron(0, 100, 104, 120, "Images\lebron.png")
while True:
process()
#LOGIC
lebron.movement()
#LOGIC
#DRAW
BaseClass.allsprites.draw(screen)
screen.fill((0,0,0))
pygame.display.flip()
#DRAW
clock.tick(FPS)
I get an error which is attribute error: Lebron object has no attribute rect. what's wrong? The traceback:
Traceback (most recent call last):
File "MAIN.py", line 24, in <module>
BaseClass.allsprites.draw(screen)
File "C:\Python27\lib\site-packages\pygame\sprite.py", line 409, in draw
self.spritedict[spr] = surface_blit(spr.image, spr.rect)
AttributeError: 'Lebron' object has no attribute 'rect'
It appears from the posted traceback (they look much better when you indent them by 4 spaces, and even better when you edit the question to include them) that the PyGame draw() method expects your attribute to provide a rect attribute. At a guess, if you replace every occurrence of rectangle with rect you will make at least some progress.
Basically, PyGame wants to draw your object but it can't find out how.
I'm trying to make a play surface out of rects in pygame. I'm not sure what the problem is exactly but I believe it has something to do with the actual iteration of the list when creating the rects. Sorry, noob here. :)
import pygame
w = 800
h = 600
board_pos = 0, 0
tile = 27
playfield = 0
class Board(object):
def __init__(self, surface, pos, tile_size):
self.surface = surface
self.x, self.y = pos
self.tsize = tile_size
self.color = 50, 50, 50
playfield = [list(None for i in xrange(22)) for i in xrange(10)]
def draw(self):
for i in xrange(10):
for j in xrange(22):
playfield[i][j] = pygame.draw.rect(self.surface, self.color,
(self.x + (i * self.tsize),
self.y + (j * self.tsize),
self.tsize, self.tsize))
pygame.display.init()
screen = pygame.display.set_mode((w, h))
board = Board(screen, board_pos, tile)
board.draw()
while __name__ == '__main__':
pygame.display.flip()
I keep getting this error:
Traceback (most recent call last):
File "C:\Documents and Settings\Administrator\My
Documents\Dropbox\Programming\DeathTris
\test2.py", line 30, in <module>
board.draw()
File "C:\Documents and Settings\Administrator\My
Documents\Dropbox\Programming\DeathTris
\test2.py", line 24, in draw
self.tsize, self.tsize))
TypeError: 'int' object has no attribute '__getitem__'
Any help would be appreciated. Thanks!
Your line playfield = [list(None for i in xrange(22)) for i in xrange(10)] creates a local variable inside the __init__ function. That variable disappears after the __init__ function returns. Later in draw when you do playfield[i][j], you are accessing the global value of playfield, which is still 0 (since you initialized it to 0 at the beginning).
If you want to overwrite the global playfield from inside your __init__, you need to do global playfield before you assign to it. (But. . . why are you using a global variable for this anyway?)