How do I make smooth movement + rotation in pygame?

≡放荡痞女 提交于 2020-12-31 15:17:12

问题


I am trying to make a spaceship move towards the mouse pointer, rotating to follow the pointer if it moves around. Currently, the rotation works fine and the linear movement works fine, but for some reason if the ship rotates and moves simultaneously, it sort of shakes in place while rotating and doesn't move forward any more. Here is a gif of my problem for clarification. Below I have the relevant code.

EDIT: I just posted the entire class to hopefully make things less confusing.

class player():
    def __init__(self, x_position, y_position, length, height):
        self.x = x_position
        self.y = y_position
        self.l = length
        self.h = height
        self.player_ship = pygame.transform.scale(ships[0], (128, 128))
        self.angle = 0
    def draw(self, win):
        cx, cy = pygame.mouse.get_pos()
        img_copy = pygame.transform.rotate(self.player_ship, math.atan2(self.x - cx, self.y - cy)*57.2957795)
        win.blit(img_copy, (self.x - int(img_copy.get_width() / 2), self.y - int(img_copy.get_height() / 2)))
    def move(self, speed):
        cx, cy = pygame.mouse.get_pos()
        self.angle = math.atan2(cx - self.x, cy - self.y)*57.2957795
        movement_x = math.cos(self.angle) * speed
        movement_y = math.sin(self.angle) * speed
        self.x -= movement_x
        self.y += movement_y

I read somewhere that I should not store my location as integers but I'm not completely sure how else to track location. I greatly appreciate any tips or pointer anyone has to offer.


回答1:


The issue is caused by the code which rotates the sprite.

Rotate the image, and get a pygame.Rect of the coated image. Set the center of the rectangle by the position of the object. Use the rectangle to blit the image.
See How do I rotate an image around its center using Pygame?.

img_copy = pygame.transform.rotate(self.player_ship, self.angle)
rotated_rect = img_copy.get_rect(center = (round(self.x), round(self.y)))

To rotate the image it is sufficient to compute the unit direction vector [See Unit vector.)] from the current position to the mouse position. Scale the vector by the speed and add it to the position:

cx, cy = pygame.mouse.get_pos()
dx, dy = cx - self.x, cy - self.y
if abs(dx) > 0 or abs(dy) > 0:
    dist = math.hypot(dx, dy)
    self.x += min(dist, speed) * dx/dist
    self.y += min(dist, speed) * dy/dist

See the example

class player():
    def __init__(self, x_position, y_position, length, height):
        self.x = x_position
        self.y = y_position
        self.l = length
        self.h = height
        self.player_ship = pygame.transform.scale(ships[0], (128, 128))
        self.angle = 0
    
    def draw(self, win):
     
        cx, cy = pygame.mouse.get_pos()
        dx, dy = cx - self.x, cy - self.y
        if abs(dx) > 0 or abs(dy) > 0:
            self.angle = math.atan2(-dx, -dy)*57.2957795

        img_copy = pygame.transform.rotate(self.player_ship, self.angle)
        rotated_rect = img_copy.get_rect(center = (round(self.x), round(self.y)))
        
        win.blit(img_copy, rotated_rect)
    
    def move(self, speed):
        cx, cy = pygame.mouse.get_pos()
        dx, dy = cx - self.x, cy - self.y
        if abs(dx) > 0 or abs(dy) > 0:
            dist = math.hypot(dx, dy)
            self.x += min(dist, speed) * dx/dist
            self.y += min(dist, speed) * dy/dist



来源:https://stackoverflow.com/questions/62599851/how-do-i-make-smooth-movement-rotation-in-pygame

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!