'ball' object has no attribute 'top' - python

I am trying to make a pong game but for some reason i am getting a error
'ball' object has no attribute 'top'
ball1.x -= ball1.speed
ball1.y += ball1.speed
if ball1.top <= 0 or ball1.bottom >= 500:
ball1.speed *= -1
if ball1.left <= 0 or ball1.right >= 500:
ball1.speed *= -1
the ball class
# this is the moving ball
class ball:
def __init__(self,x,y,height,width,color):
self.x =x
self.y = y
self.height = height
self.width = width
self.color = color
self.speed = 5
self.rect = pygame.Rect(x,y,height,width)
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.circle(window, self.color, self.rect.center,10)
ball1 = ball(290,200,20,20,white)

You just need to add top, bottom, left and right to your class. Something like this:
class ball:
def __init__(self,x,y,height,width,color):
self.x =x
self.y = y
self.height = height
self.width = width
self.color = color
self.speed = 5
self.rect = pygame.Rect(x,y,height,width)
self.top = self.y
self.bottom = self.y + height
self.left = self.x
self.right = self.x + width
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.circle(window, self.color, self.rect.center,10)

Related

how to move a rectangle in a pygame program [duplicate]

This question already has answers here:
How can I make a sprite move when key is held down
(6 answers)
Closed last month.
Good day, I am writing a pygame program that uses sockets. Right now I am just trying to get the rectangles to move in the x-axis and I keep getting this error
self.rect.x += self.dx
AttributeError: 'tuple' object has no attribute 'x' ".
My goal is just to move the rect left and right. using the move method below.
import pygame
class Player():
def __init__(self, x, y, width, height, color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.rect = pygame.Rect((x, y, width, height))
self.vel = 3
self.dx = 0
self.dy = 0
self.jump = False
def draw(self, win):
pygame.draw.rect(win, self.color, self.rect)
def move(self, screen_width, screen_height):
SPEED = 10
dx = 0
dy = 0
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.dx = -SPEED
if keys[pygame.K_RIGHT]:
self.dx = SPEED
self.update()
def update(self):
# update player position
self.rect.x += self.dx
self.rect.y += self.dy
self.rect = (self.x, self.y, self.width, self.height)
self.dx = 0
self.dy = 0
I see that you already created a pygame.Rect object and updated it correct, why recreate that object?
Change this:
def update(self):
# update player position
self.rect.x += self.dx
self.rect.y += self.dy
self.rect = (self.x, self.y, self.width, self.height)
self.dx = 0
self.dy = 0
To:
def update(self):
# update player position
self.rect.x += self.dx
self.rect.y += self.dy
self.dx = 0
self.dy = 0
Also you might want to remove this as it doesn't do anything:
self.x = x
self.y = y
Unless you need the position where it was first created

Rect argument is invalid [duplicate]

This question already has answers here:
How do I detect collision in pygame?
(5 answers)
Pygame Drawing a Rectangle
(6 answers)
Closed 5 months ago.
I'm building a game with Sprites, using almost exactly the same code for all the sprites. But when it comes to my ship its telling me I have no rect or colliderect is invalid etc etc etc.
I tried to put a box around my 'rect' to make sure it was loaded correctly but I just get this error.
My code for the ship is
class Spaceship(pygame.sprite.Sprite):
def __init__(self, x, y, scale):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("ship.png")
self.image = pygame.transform.scale(self.image, (int(self.image.get_width() * scale), int(self.image.get_height() * scale)))
self.rect = self.image.get_rect() # isn't this correct to get a rect!?
self.rect.center = [x, y]
self.pos = pygame.mouse.get_pos()
self.alive = True
self.speed = 100
self.dx = 0
self.dy = 0
self.x = 0
self.y = 0
def update(self):
pygame.draw.rect(screen,(GREEN), self.rect, 2) # Trying to establish rect object
self.pos = pygame.mouse.get_pos()
self.dx = (self.pos[0])
self.dy = (self.pos[1])
if self.x +20 <= self.dx:
self.x += speed
if self.x +20 >= self.dx:
self.x -= speed
self.y = (self.pos[1])
if self.y +20 <= self.dy:
self.y += speed
if self.y +20 >= self.dy:
self.y -= speed
print(self.pos[0])
print(self.pos[1])
if self.x >= SW - 40:
self.x = SW - 40
if self.x <= 0:
self.x = 0
if self.y >= SH -40:
self.y = SH - 40
if self.y <= SH - 600:
self.y = SH - 600
self.blit = (self.x, self.y)
self.rect = (self.x, self.y)
If I can't get this rect right I can't check rect collisions.
Thanks for any thoughts.

Breakout Game erasing rectangles pygame

I'm making a breakout game using the pygame module, and I've established most of the functionalities. However, I'm having a hard time making the ball collide with the blocks at the top of the screen. Specifically in the "collisions" method in the main class. I wrote a for loop to iterate through the block list to check if the block collided with the ball, and if it did, then it would remove from the row_1 list the respective index of the block, theoretically erasing the block from the screen. But I get an AttributeError: 'pygame.Rect' object has no attribute 'collidirect'. I appreciate the help.
import pygame, sys
pygame.init()
clock = pygame.time.Clock()
screen_width = 600
screen_height = 750
black = (0, 0, 0)
white = (255, 255, 255)
purple = (138, 43, 226)
red = (255, 0, 0)
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Breakout Game")
class BLOCK:
def __init__(self):
self.width = 54
self.height = 20
self.row_1 = [[5, 20]]
self.blocks = []
for i in range(9):
self.row_1.append(self.row_1[-1][:])
self.row_1[-1][0] += 59
def draw_blocks(self):
for cor in self.row_1:
block_rect = pygame.Rect(cor[0], cor[1], self.width, self.height)
self.blocks.append(block_rect)
pygame.draw.rect(screen, red, block_rect)
class BALL:
def __init__(self):
self.width = 15
self.height = 15
self.x = screen_width/2 - self.width/2
self.y = screen_height/2 - self.height/2
self.speed_x = 5
self.speed_y = 5
self.ball_rect = pygame.Rect(self.x, self.y, self.width, self.height)
def draw_ball(self):
pygame.draw.ellipse(screen, white, self.ball_rect)
def move_ball(self):
self.x += self.speed_x
self.y += self.speed_y
self.ball_rect.topleft = (self.x, self.y)
def wall_collision(self):
if self.x >= screen_width - self.width:
self.speed_x *= -1
if self.x <= 0:
self.speed_x *= -1
if self.y >= screen_height - self.height:
self.x = screen_width/2 - self.width/2
self.y = screen_height / 2 - self.height/2
if self.y <= 0:
self.speed_y *= -1
class PADDLE:
def __init__(self):
self.width = 100
self.height = 10
self.x = screen_width/2 - self.width/2
self.y = 600
self.speed = 7
self.paddle_rect = pygame.Rect(self.x, self.y, self.width, self.height)
def draw_paddle(self):
pygame.draw.rect(screen, purple, self.paddle_rect)
def move_paddle(self):
key = pygame.key.get_pressed()
if key[pygame.K_LEFT]:
self.x -= self.speed
if key[pygame.K_RIGHT]:
self.x += self.speed
self.paddle_rect.topleft = (self.x, self.y)
class MAIN:
def __init__(self):
self.block = BLOCK()
self.ball = BALL()
self.paddle = PADDLE()
def draw(self):
self.block.draw_blocks()
self.ball.draw_ball()
self.paddle.draw_paddle()
def move(self):
self.ball.move_ball()
self.paddle.move_paddle()
def collisions(self):
self.ball.wall_collision()
if self.ball.ball_rect.colliderect(self.paddle.paddle_rect):
self.ball.speed_y *= -1
for block in self.block.blocks:
if block.collidirect(self.ball.ball_rect):
self.block.row_1.pop(self.block.blocks.index(block))
main = MAIN()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill(black)
main.draw()
main.move()
main.collisions()
pygame.display.flip()
clock.tick(60)
It's a typo. The name of the method is colliderect rather then collidirect:
if block.collidirect(self.ball.ball_rect):
if block.colliderect(self.ball.ball_rect):

self.rect = pygame.Rect(x,y,width,height) TypeError: Argument must be rect style object [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I'm having this error when I made my bullets, I do not know why it is not working because before I made my bullet class it was working perfectly fine. I have tried rewriting this part of the the code but that did not work
self.rect = pygame.Rect(x,y,width,height)
TypeError: Argument must be rect style object
I do not know how to fix the error even though I am defiantly sure I wrote it right. the error is happening in my player class
the player class and were the error is happening
# Class Player
class player:
def __init__(self,x,y,width,height,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.speed = 4
self.color = color
self.rect = pygame.Rect(x,y,width,height)
self.ss1 = pygame.image.load("heroplane1.png")
self.ss1 = pygame.transform.scale(self.ss1,(self.ss1.get_width()//9,self.ss1.get_height()//9))
def draw(self):
self.rect.topleft=(self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
player_rect = self.ss1.get_rect(center = self.rect.center)
player_rect.centerx += -7
player_rect.centery += -6
window.blit(self.ss1,player_rect)
my full code
import pygame
pygame.init()
# Build The Screen
window = pygame.display.set_mode((700,500))
# Name Screen
pygame.display.set_caption("Noobs first Game")
bg = pygame.image.load("skybg1.png")
bg_shift = 0
# Class Player
class player:
def __init__(self,x,y,width,height,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.speed = 4
self.color = color
self.rect = pygame.Rect(x,y,width,height)
self.ss1 = pygame.image.load("heroplane1.png")
self.ss1 = pygame.transform.scale(self.ss1,(self.ss1.get_width()//9,self.ss1.get_height()//9))
def draw(self):
self.rect.topleft=(self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
player_rect = self.ss1.get_rect(center = self.rect.center)
player_rect.centerx += -7
player_rect.centery += -6
window.blit(self.ss1,player_rect)
# Class Enemy
class enemy:
def __init__(self,x,y,width,height,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.speed = 4
self.color = color
self.rect = pygame.Rect(x,y,width,height)
self.ss1 = pygame.image.load("enemyplane1.png")
self.ss1 = pygame.transform.scale(self.ss1,(self.ss1.get_width()//9,self.ss1.get_height()//9))
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
enemy_rect = self.ss1.get_rect(center = self.rect.center)
enemy_rect.centerx += -2
enemy_rect.centery += -6
window.blit(self.ss1,enemy_rect)
# Class Enemy2
class enemy2:
def __init__(self,x,y,width,height,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.rect = pygame.Rect(x,y,width,height)
self.ss1 = pygame.image.load("enemyplane2.png")
self.ss1 = pygame.transform.scale(self.ss1,(self.ss1.get_width()//9,self.ss1.get_height()//9))
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
enemy2_rect = self.ss1.get_rect(center = self.rect.center)
enemy2_rect.centerx += -4
enemy2_rect.centery += -6
window.blit(self.ss1,enemy2_rect)
# Class Enemy3
class enemy3:
def __init__(self,x,y,width,height,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.rect = pygame.Rect(x,y,width,height)
self.ss1 = pygame.image.load("enemyplane3.png")
self.ss1 = pygame.transform.scale(self.ss1,(self.ss1.get_width()//9,self.ss1.get_height()//9))
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
enemy3_rect = self.ss1.get_rect(center = self.rect.center)
enemy3_rect.centerx += -4
enemy3_rect.centery += -6
window.blit(self.ss1,enemy3_rect)
class projectile(object):
def __init__(self, x, y,color):
self.x = x
self.y = y
self.slash = pygame.image.load("herogun1.png")
self.rect = self.slash.get_rect()
self.rect.topleft = ( self.x, self.y )
self.speed = 10
self.color = color
def draw(self, window):
self.rect.topleft = ( self.x,self.y )
window.blit(slash, self.rect)
class enemygun:
def __init__(self,x,y,width,height,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.rect = pygame.Rect(x,y,width,height)
self.ss1 = pygame.image.load("enemygun1.png")
self.ss1 = pygame.transform.scale(self.ss1,(self.ss1.get_width()//11,self.ss1.get_height()//11))
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
enemy3_rect = self.ss1.get_rect(center = self.rect.center)
enemy3_rect.centerx += -7
enemy3_rect.centery += -2
window.blit(self.ss1,enemy3_rect)
# Color
white = (255,255,255)
# Draw Player
playerman = player(5,250,90,40,white)
# For Enemy
enemy1 = enemy(400,100,90,40,white)
enemy4 = enemy(400,400,90,40,white)
# For Enemy2
enemy21 = enemy2(400,300,90,40,white)
# For Enemy3
ememy31 = enemy3(400,400,90,40,white)
egun1 = enemygun(250,300,30,20,white)
enemys = [enemy1,enemy4]
# enemys
enemyGroup = pygame.sprite.Group()
level1 = [
" 1",
" 1",
" 1",
" 1",
" 1",
" 1",
" 1",]
for iy, row in enumerate(level1):
for ix, col in enumerate(row):
if col == "1":
new_enemy = enemy(ix*70,iy*70,90,40,(255,255,255))
enemys.append(new_enemy)
# Redrawwinodw
def redrawwindow():
window.fill((0,0,0))
bg_width = bg.get_width()
bg_offset = bg_shift % bg_width
window.blit(bg, (-bg_offset, 0))
window.blit(bg, (bg_width - bg_offset, 0))
# Draw playerman
playerman.draw()
# Draw enemy
for enemy in enemys:
enemy.draw()
# Draw enemy2
enemy21.draw()
# Draw enemy3
ememy31.draw()
# Draw enemygun
egun1.draw()
# FPS Cnd Clock
fps = (30)
clock = pygame.time.Clock()
bullets = []
# Main Loop
run = True
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_f]:
for bullet in bullets:
if bullet.x < 500 and bullet.x > 0:
bullet.x += bullet.speed
else:
bullets.pop(bullets.index(bullet))
if len(bullets) < 2:
bullets.append(projectile(round(playerman.x+playerman.width//2),round(playerman.y + playerman.height-54),(0,0,0)))
for enemy in enemys:
enemy.x -= enemy.speed
bg_shift += round(3/2)
# Keys For Playerman
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and playerman.x > playerman.speed:
playerman.x -= playerman.speed
if keys[pygame.K_d] and playerman.x < 260 - playerman.width - playerman.speed:
playerman.x += playerman.speed
if keys[pygame.K_w] and playerman.y > playerman.speed:
playerman.y -= playerman.speed
if keys[pygame.K_s] and playerman.y < 500 - playerman.height - playerman.speed:
playerman.y += playerman.speed
if keys[pygame.K_SPACE]:
if playerman.left:
facing = -1
else:
facing = 1
if len(bullets) < 5: # This will make sure we cannot exceed 5 bullets on the screen at once
bullets.append(player(round(playerman.x+playerman.width//2), round(playerman.y + playerman.height//2), 6, (255,255,255), white))
# Update And Other Sutff
redrawwindow()
for bullet in bullets:
bullet.draw()
pygame.display.update()
pygame.quit()
The problem is in the lines
if len(bullets) < 5: # This will make sure we cannot exceed 5 bullets on the screen at once
bullets.append(player(round(playerman.x+playerman.width//2), round(playerman.y + playerman.height//2), 6, (255,255,255), white))
You are trying to pass (255,255,255) as the height. It needs to be a number, not a tuple.

Can Someone Tell Me Why My Projectiles Arent Showing Up On My Screen Test Shows The Projectiles are firing doesnt display on my screen?

on my output idle its printing that the bullets are firing but they arent showing up on my screen
if len(bulls):
bull = Bullet(round(smallice1.x+dir_x), round(smallice1.y+dir_y))
bulls.append(bull)
if round(pygame.time.get_ticks()/1000) % 3 == 0:
print("shooting")
if bulls != []: #Firing bullets
for bull in bulls:
bulls.append(bull)
if bull.y < 400: #Bullet movement
bull.x += bull.v
else:
bulls.pop(bulls.index(bull)) #Poping bullets from list
keys = pygame.key.get_pressed()
the bullets class
# enemys bullets
class Bullet:
def __init__(self, x, y, bull_x, bull_y, color):
self.x = x
self.y = y
self.dirx = bull_x
self.diry = bull_y
self.slash = pygame.image.load("heart.png")
self.rect = self.slash.get_rect()
self.rect.topleft = ( self.x, self.y )
self.speed = 10
self.color = color
def move(self):
self.x += self.bull_x * self.speed
self.y += self.bull_y * self.speed
def draw(self, window):
self.rect.topleft = (round(self.x), round(self.y))
window.blit(self.slash,self.rect)
even tho i rain this function below
for bull in bulls:
bull.draw(window)
full code
https://pastebin.com/EN6pU7bR
I redone my bullet class
class Bullet(object):
def __init__(self, x, y,color):
self.x = x
self.y = y
self.slash = pygame.image.load("littleboy.png")
self.rect = self.slash.get_rect()
self.rect.topleft = ( self.x, self.y )
self.speed = 10
self.color = color
def draw(self, window):
self.rect.topleft = ( self.x,self.y )
window.blit(slash, self.rect)
and shorten the firing part for the player added a variable list outside of my main loop called bulls = [] then used that I am bad at explainging things the
code is simple I can you can read it
for bull in bulls:
if bull.x < 500 and bull.x > 0:
bull.x += bull.speed
else:
bulls.pop(bulls.index(bull))
if len(bulls) < 2:
bulls.append(Bullet(round(smallice1.x+smallice1.width//2),round(smallice1.y + smallice1.height-60),(0,0,0)))

Categories