如何解决如何使我的矩形与旋转精灵一起旋转
所以我的矩形/弹丸旋转遇到了这个问题,我想要它,这样我的矩形/弹丸就会随着我的旋转精灵旋转,但我正在尝试的代码对我不起作用,我的代码我正在尝试给我这个错误。 'pygame.Surface' object has no attribute 'x'
我试过移动代码,我也试过更改代码,这样我就不会再出现错误了,我也尝试过使用命中框,但我仍然不断收到错误消息。这是我的两个精灵
我正在尝试的代码
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)
我的完整代码
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,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.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.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,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,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,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,self.rect)
# The color white
white = (255,255,255)
# The xy cords,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))
# 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))
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()
解决方法
您已经在 projectile.move
方法中移动了图钉。在 projectile.draw
方法中,您只需旋转图钉。请参阅 How do I rotate an image around its center using PyGame? 和 How to rotate an image(player) to the mouse direction?:
class projectile(object):
# [...]
def draw(self):
self.rect.center = (round(self.x),round(self.y))
angle = math.degrees(math.atan2(-self.diry,self.dirx)) - 90
rotated_pin = pygame.transform.rotate(self.pin,angle)
rotated_rect = rotated_pin.get_rect(center = self.rect.center)
pygame.draw.rect(window,self.color,rotated_rect)
window.blit(rotated_pin,rotated_rect)
self.hitbox = (self.x + 20,self.y,30,30)
您必须找到引脚的起始位置。销应该从吹管顶部的某个地方开始。向 get_pivot
类添加 Player
方法:
class Player:
# [...]
def get_pivot(self):
player_rect = self.cannon.get_rect(center = self.get_rect().center)
return player_rect.centerx,player_rect.top + 103
添加一个计算吹管角度的get_angle
方法:
class Player:
# [...]
def get_angle(self):
pivot_abs = self.get_pivot()
dx = self.look_at_pos[0] - pivot_abs[0]
dy = self.look_at_pos[1] - pivot_abs[1]
return math.degrees(math.atan2(-dy,dx))
使用此方法计算吹管的顶部:
class Player:
# [...]
def get_top(self):
pivot_x,pivot_y = self.get_pivot()
angle = self.get_angle()
length = 100
top_x = pivot_x + length * math.cos(math.radians(angle))
top_y = pivot_y - length * math.sin(math.radians(angle))
return top_x,top_y
您还可以在 get_pivot
方法中使用 get_angle
和 draw
方法:
class Player:
# [...]
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.hitbox)
gun_size = self.image.get_size()
pivot_abs = self.get_pivot()
pivot_rel = (gun_size[0] // 2,105)
angle = self.get_angle() - 90
pygame.draw.rect(window,self.rect)
blitRotate(window,self.image,pivot_abs,pivot_rel,angle)
使用get_top
设置引脚的起始位置:
mousex,mousey = pygame.mouse.get_pos()
start_x,start_y = playerman.get_top()
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))
bullets.append(new_bullet)
在吹管之前将销子拉入,使销子看起来像是从吹管中出来:
def redrawwindow():
window.fill((0,0))
# Drawing the window in
window.blit(background,0))
# Drawing the players bullet
for bullet in bullets:
bullet.draw()
# drawing the player in window
playerman.draw()
完整示例:
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,height)
self.hitbox = (self.x,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 get_pivot(self):
player_rect = self.cannon.get_rect(center = self.get_rect().center)
return player_rect.centerx,player_rect.top + 103
def get_angle(self):
pivot_abs = self.get_pivot()
dx = self.look_at_pos[0] - pivot_abs[0]
dy = self.look_at_pos[1] - pivot_abs[1]
return math.degrees(math.atan2(-dy,dx))
def get_top(self):
pivot_x,top_y
def draw(self):
self.rect.topleft = (self.x,angle)
def lookAt( self,coordinate ):
self.look_at_pos = coordinate
# Players gun
class projectile(object):
def __init__(self,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.center = ( self.x,self.y )
self.speed = 10
self.color = color
self.hitbox = (self.x + 20,40)
def move(self):
self.x += self.dirx * self.speed
self.y += self.diry * self.speed
def draw(self):
self.rect.center = (round(self.x),30)
# The color white
white = (255,255,255)
# The xy cords,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))
# Drawing the players bullet
for bullet in bullets:
bullet.draw()
# drawing the player in window
playerman.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.get_top()
mouse_x,mouse_y = event.pos
dir_x,mouse_y - start_y
distance = math.sqrt(dir_x**2 + dir_y**2)
if distance > 0:
new_bullet = projectile(start_x,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()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。