So I been having this problem with my rectangle/projectile rotation, I want it so that my rectangle/projectile will rotate with my rotating sprite but the code I'm trying for it is not working for me, The code that I'm trying is giving me this error. 'pygame.Surface' object has no attribute 'x'
I have tried moving the code around, I have also tried to change the code so I wont get the error no more, and I have tried using a hitbox but I still keep getting the error. This is my two sprites
The code I'm trying
self.dist = 100
dx = self.pin.x + self.dist*math.cos(-self.pin.angle*(math.pi/180)) -65 # why offset needed ?
dy = self.pin.y + self.dist*math.sin(-self.pin.angle*(math.pi/180)) -50 # why offset needed ?
self.rect.topleft = (dx,dy)
pygame.draw.rect(window,self.color,self.rect)
My full code
import pygame,math,random
pygame.init()
# Windowing screen width and height
width = 500
height = 500
window = pygame.display.set_mode((width,height))
# Name of window
pygame.display.set_caption("Game")
# The Background
background = pygame.image.load("img/BG.png")
def blitRotate(surf, image, pos, originPos, angle):
# calcaulate the axis aligned bounding box of the rotated image
w, h = image.get_size()
sin_a, cos_a = math.sin(math.radians(angle)), math.cos(math.radians(angle))
min_x, min_y = min([0, sin_a*h, cos_a*w, sin_a*h + cos_a*w]), max([0, sin_a*w, -cos_a*h, sin_a*w - cos_a*h])
# calculate the translation of the pivot
pivot = pygame.math.Vector2(originPos[0], -originPos[1])
pivot_rotate = pivot.rotate(angle)
pivot_move = pivot_rotate - pivot
# calculate the upper left origin of the rotated image
origin = (pos[0] - originPos[0] + min_x - pivot_move[0], pos[1] - originPos[1] - min_y + pivot_move[1])
# get a rotated image
rotated_image = pygame.transform.rotate(image, angle)
# rotate and blit the image
surf.blit(rotated_image, origin)
# Player class
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.speed = 4
self.cannon = pygame.image.load("img/Cannon.png")
self.cannon = pygame.transform.scale(self.cannon,(self.cannon.get_width()//2, self.cannon.get_height()//2))
self.rect = pygame.Rect(x,y,width,height)
self.hitbox = (self.x,self.y,30,30)
self.image = self.cannon
self.rect = self.image.get_rect(center = (self.x, self.y))
self.look_at_pos = (self.x, self.y)
self.isLookingAtPlayer = False
self.look_at_pos = (x,y)
self.angle = 0
def get_rect(self):
self.rect.topleft = (self.x,self.y)
return self.rect
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.hitbox)
player_rect = self.cannon.get_rect(center = self.get_rect().center)
player_rect.centerx -= 0
player_rect.centery += 90
# Another part of cannon rotating
dx = self.look_at_pos[0] - self.rect.centerx
dy = self.look_at_pos[1] - self.rect.centery
angle = (180/math.pi) * math.atan2(-dy, dx) - 90
gun_size = self.image.get_size()
pivot_abs = player_rect.centerx, player_rect.top + 13
pivot_rel = (gun_size[0] // 2, 105)
pygame.draw.rect(window,self.color,self.rect)
blitRotate(window, self.image,pivot_abs, pivot_rel, angle)
def lookAt( self, coordinate ):
self.look_at_pos = coordinate
# Players gun
class projectile(object):
def __init__(self,x,y,dirx,diry,color):
self.x = x
self.y = y
self.dirx = dirx
self.diry = diry
self.pin = pygame.image.load("img/Pin.png")
self.pin = pygame.transform.scale(self.pin,(self.pin.get_width()//6, self.pin.get_height()//6))
self.rect = self.pin.get_rect()
self.topleft = ( self.x, self.y )
self.speed = 10
self.color = color
self.hitbox = (self.x + 20, self.y, 30,40)
def move(self):
self.x += self.dirx * self.speed
self.y += self.diry * self.speed
def draw(self):
self.rect.topleft = (round(self.x), round(self.y))
window.blit(self.pin,self.rect)
self.hitbox = (self.x + 20, self.y,30,30)
# For rotating the the projectile
self.dist = 100
dx = self.pin.x + self.dist*math.cos(-self.pin.angle*(math.pi/180)) -65 # why offset needed ?
dy = self.pin.y + self.dist*math.sin(-self.pin.angle*(math.pi/180)) -50 # why offset needed ?
self.rect.topleft = (dx,dy)
pygame.draw.rect(window,self.color,self.rect)
# The color white
white = (255,255,255)
# The xy cords, width, height and color of my classes[]
playerman = Player(350,385,34,75,white)
# This is where my balloons get hit by the bullet and disappers
# redrawing window
def redrawwindow():
window.fill((0,0,0))
# Drawing the window in
window.blit(background,(0,0))
# drawing the player in window
playerman.draw()
# Drawing the players bullet
for bullet in bullets:
bullet.draw()
# Frames for game
fps = 30
clock = pygame.time.Clock()
#projectile empty list
bullets = []
# main loop
run = True
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
if len(bullets) < 6700:
mousex , mousey = pygame.mouse.get_pos()
start_x , start_y = playerman.rect.x + 12, playerman.rect.y - 3
mouse_x , mouse_y = event.pos
dir_x , dir_y = mouse_x - start_x , mouse_y - start_y
distance = math.sqrt(dir_x**2 + dir_y**2)
if distance > 0:
new_bullet = projectile(start_x, start_y, dir_x/distance , dir_y/distance, (0,0,0))
bullets.append(new_bullet)
for bullet in bullets[:]:
bullet.move()
if bullet.x < 0 or bullet.x > 900 or bullet.y < 0 or bullet.y > 900:
bullets.pop(bullets.index(bullet))
# gun rotation
mousex, mousey = pygame.mouse.get_pos()
if not playerman.isLookingAtPlayer:
playerman.lookAt((mousex, mousey))
# telling game that key means when a key get pressed
keys = pygame.key.get_pressed()
# The player moving when the key a is pressed
if keys[pygame.K_a] and playerman.x > playerman.speed:
playerman.x -= playerman.speed
# The player moving when the key d is pressed
if keys[pygame.K_d] and playerman.x < 500 - playerman.width - playerman.speed:
playerman.x += playerman.speed
# Calling the redraw function
redrawwindow()
# updating game
pygame.display.update()
# quiting the game
pygame.quit()