问题
So I have been trying to make it so my cannon image will rotate to where my mouse is, but the code I'm trying is buggy. My cannon dose not follow my mouse and I lose my other sprite when I put my rotating code, I have tried a code that will be show bellow, but the code that I have tried is causing my problems. also below is my cannon and my other sprite.
My code and what I have tried
import pygame,math
pygame.init()
# Windowing screen width and height
width = 700
height = 500
window = pygame.display.set_mode((width,height))
# Name of window
pygame.display.set_caption("Game")
# A Part of cannon rotating
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.cannon2 = pygame.image.load("img/cannon2.png")
self.cannon = pygame.transform.scale(self.cannon,(self.cannon.get_width()//2, self.cannon.get_height()//2))
self.cannon2 = pygame.transform.scale(self.cannon2,(self.cannon2.get_width()//2, self.cannon2.get_height()//2))
self.rect = pygame.Rect(x,y,width,height)
#Another part of cannon roting
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)
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.rect)
player_rect = self.cannon.get_rect(center = self.get_rect().center)
player_rect.centerx -= 0.4
player_rect.centery += 0
window.blit(self.cannon,player_rect)
player_rect = self.cannon2.get_rect(center = self.get_rect().center)
player_rect.centerx -= 0.7
player_rect.centery += 30
window.blit(self.cannon2,player_rect)
# 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)
gun_size = self.image.get_size()
pivot = (8, gun_size[1]//2)
blitRotate(window, self.image, self.rect.center, pivot, angle)
def lookAt( self, coordinate ):
self.look_at_pos = coordinate
# The color white
white = (255,255,255)
# The xy cords, width, height and color of my classes[]
playerman = Player(350,416,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 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
# cannon 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 a is pressed
if keys[pygame.K_d] and playerman.x < 500 - playerman.width - playerman.height:
playerman.x += playerman.speed
# Calling the redraw function
redrawwindow()
# updating game
pygame.display.update()
# quiting the game
pygame.quit()
回答1:
Follow the suggestions in the answers to How to rotate an image(player) to the mouse direction?. You have to consider the orientation of the cannon image:
angle = (180/math.pi) * math.atan2(-dy, dx) - 90
angle = (180/math.pi) * math.atan2(-dy, dx) - 90
See How do I rotate an image around its center using PyGame? and How can you rotate an image around an off center pivot in PyGame.
The 2nd argument (pos
) of blitRotate
is the position of the pivot point in the window and the 3rd argument (originPos
) is the position of the pivot point on the rotating Surface:
blitRotate(window, self.image, self.rect.center, pivot, angle)
gun_size = self.image.get_size()
pivot_abs = player_rect.centerx, player_rect.top + 10
pivot_rel = (gun_size[0] // 2, 105)
blitRotate(window, self.image,pivot_abs, pivot_rel, angle)
Complete Player.draw
method:
class Player:
# [...]
def draw(self):
self.rect.topleft = (self.x,self.y)
player_rect = self.cannon2.get_rect(center = self.get_rect().center)
player_rect.centerx -= 0
player_rect.centery -= 10
# 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 + 10
pivot_rel = (gun_size[0] // 2, 105)
pygame.draw.rect(window,self.color,self.rect)
blitRotate(window, self.image,pivot_abs, pivot_rel, angle)
window.blit(self.cannon2,player_rect)
来源:https://stackoverflow.com/questions/65573379/how-do-i-make-image-rotate-with-mouse-python