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
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.
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):
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.
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)))