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):
# [...]
Related
I wanted to add a gun for the player so that he could shoot at enemies. However, because of this, the game refuses to work. Nothing is displayed. Only a black screen for a few seconds.
About this error:
'NoneType' object is not iterable
I've heard, but I don't know exactly how to write it correctly so that everything is displayed.
The code looks fine, but it still doesn't work.
Can you tell me why this is happening and how to change it?
from sprite_object import *
class Weapon(AnimatedSprite):
def __init__(self, game, path='resources/sprites/weapon/shotgun/0.png', scale=0.4, animation_time=90):
super().__init__(game=game, path=path, scale=scale, animation_time=animation_time)
self.images = deque(
[pg.transform.smoothscale(img, (self.image.get_width() * scale, self.image.get_height() * scale))
for img in self.images])
self.weapon_pos = (HALF_WIDTH - self.images[0].get_width() // 2, HEIGHT - self.images[0].get_height())
self.reloading = False
self.num_images = len(self.images)
self.frame_counter = 0
self.damage = 50
def animate_shot(self):
if self.reloading:
self.game.player.shot = False
if self.animation_trigger:
self.images.rotate(-1)
self.image = self.images[0]
self.frame_counter += 1
if self.frame_counter == self.num_images:
self.reloading = False
self.frame_counter = 0
def draw(self):
self.game.screen.blit(self.images[0], self.weapon_pos)
def update(self):
self.check_animation_time()
self.animate_shot()
File "C:\Users\79853\pythonProject1\Doom\main.py", line 72, in <module>
game = Game()
^^^^^^
File "C:\Users\79853\pythonProject1\Doom\main.py", line 25, in __init__
self.new_game()
File "C:\Users\79853\pythonProject1\Doom\main.py", line 33, in new_game
self.weapon = Weapon(self)
^^^^^^^^^^^^
File "C:\Users\79853\pythonProject1\Doom\weapon.py", line 8, in __init__
[pg.transform.smoothscale(img, (self.image.get_width() * scale, self.image.get_height() * scale))
TypeError: 'NoneType' object is not iterable
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))
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 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?)