简体   繁体   English

在pygame中旋转

[英]Rotation in pygame

I've been looking for solutions on how to make my image rotate around a single point but from what I've found nothing has really worked. 我一直在寻找如何使我的图像围绕一个点旋转的解决方案,但从我发现的一切都没有真正起作用。

What I know 我知道的

  • I can rotate using pygame.transform.rotate(surface, angle) 我可以使用pygame.transform.rotate(surface, angle)旋转pygame.transform.rotate(surface, angle)

  • I need to constantly reset the center so the image does not rotate on its rotated self. 我需要不断重置中心,以便图像不会在旋转的自身上旋转。

  • Need to update image to eliminate distortion 需要更新图像以消除失真

At first the image looks like this 起初图像看起来像这样 Pygame屏幕

Then when I rotate it a couple times it looks like this 然后,当我旋转它几次时它看起来像这样 Pygame屏幕2

Here's my code 这是我的代码

import pygame


class pyGameSetup:

def __init__(self, title, width, height):

    # initialize pygame library
    pygame.init()

    # set up specific display properties
    self.game_display = pygame.display.set_mode((width, height))
    pygame.display.set_caption(title)

    # update display
    pygame.display.update()

    # create new global variables for the class
    # game state
    self.running = True

    # colors, only main
    # TODO: implement more color RGB values, if updated, update corresponding method
    self.white = (255, 255, 255)
    self.black = (0, 0, 0)
    self.grey = (128, 128, 128)
    self.pink = (255, 102, 178)
    self.blue = (0, 0, 255)
    self.red = (255, 0, 0)
    self.green = (0, 255, 0)
    self.purple = (127, 0, 255)
    self.yellow = (255, 255, 0)
    self.teal = (0, 204, 204)
    self.orange = (255, 128, 0)

    # player coordinates and properties
    self.player_x = int(width / 2)
    self.player_y = int(height / 2)
    self.player_width = 100
    self.player_height = 50
    self.player_speed_x = 0
    self.player_speed_y = 0
    self.move_speed = 5

    # FPS controllers (note start speed should always be 60 / 5 so, 1 / 300
    self.clock = pygame.time.Clock()
    self.fps = 60

    # screen values
    self.width = width
    self.height = height

    # rotation for car
    self.angle = 200

    # car image
    self.car1 = pygame.image.load("Images\\Car1.png")
    self.update_size()
    self.car_rect = self.car1.get_rect()
    self.car_rect.center = (self.player_x, self.player_y)


def exit(self):
    pygame.quit()
    self.running = False
    quit()

def game_loop(self):
    while self.running:
        for event in pygame.event.get():
            self.event_handler(event)

        # update player position
        # self.player_x += self.player_speed_x
        self.angle = self.player_speed_x
        self.player_y += self.player_speed_y

        # check to make sure it's in bounds
        self.check_valid_move()

        # reprint canvas
        self.game_display.fill(self.white)

        # update angle
        self.update_angle()

        # print player
        self.game_display.blit(self.car1, (self.player_x, self.player_y, self.player_width,
                                           self.player_height))

        # update display
        pygame.display.update()

        # FPS
        self.clock.tick(self.fps)

def event_handler(self, e):
    if e.type == pygame.QUIT:
        self.exit()
    if e.type == pygame.KEYDOWN:
            if e.key == pygame.K_LEFT:
                self.player_speed_x = -self.move_speed
            if e.key == pygame.K_RIGHT:
                self.player_speed_x = self.move_speed
            if e.key == pygame.K_UP:
                self.player_speed_y = -self.move_speed
            if e.key == pygame.K_DOWN:
                self.player_speed_y = self.move_speed
    if e.type == pygame.KEYUP:
            if e.key == pygame.K_LEFT:
                self.player_speed_x = 0
            if e.key == pygame.K_RIGHT:
                self.player_speed_x = 0
            if e.key == pygame.K_UP:
                self.player_speed_y = 0
            if e.key == pygame.K_DOWN:
                self.player_speed_y = 0

def check_valid_move(self):
    if self.player_x <= 0:
        self.player_x = 0
    if self.player_x >= self.width - self.player_width:
        self.player_x = self.width - self.player_width
    if self.player_y <= 0:
        self.player_y = 0
    if self.player_y >= self.height - self.player_height:
        self.player_y = self.height - self.player_height

def update_size(self):
    self.car1 = pygame.transform.scale(self.car1, (self.player_width, self.player_height))
    self.car1 = pygame.transform.rotate(self.car1, -90)

def update_angle(self):
    old_center = self.car_rect.center
    self.car1 = pygame.transform.rotate(self.car1, self.angle)
    self.car_rect.center = old_center

x = pyGameSetup('Game', 800, 600)
x.game_loop()

The error is in update_angle where I honestly am completely lost and do not even know what it's doing. 错误发生在update_angle中,老实说,我完全迷失了,甚至不知道它在做什么。 Thanks in advance. 提前致谢。

This result seems to be pretty normal for the image of low resolution rotated several times without antialiasing. 对于没有抗锯齿的情况下旋转几次的低分辨率图像,这个结果似乎很正常。 What you should do is: 你应该做的是:

  • Use the source image exactly 2x bigger, if possible. 如果可能,请将源图像精确地放大2倍。 Rotate it FIRST and then scale down exactly 2x - if possible, during blit, so you don't need to scale it as a separate step. 首先旋转它,然后精确缩小2倍 - 如果可能的话,在blit期间,所以你不需要将它作为单独的步骤缩放。
  • Don't rotate rotated image. 不要旋转旋转的图像。 Ie don't rotate it 3 times by 5 degrees, but every time copy the original image and rotate it by 5, 10, 15 degrees. 即不要将它旋转3次5度,但每次复制原始图像并将其旋转5度,10度,15度。 This way you will keed distortion to the minimum and also won't have to re-assign the center. 通过这种方式,您可以将失真降至最低,也无需重新分配中心。

Your problem is that you are rotating a rotated image. 您的问题是您正在旋转旋转的图像。 Thus, the image is looking skewed, which would be expected. 因此,图像看起来是倾斜的,这是预期的。 Instead, have two variables, one for the original variable, one for the most recent rotation. 相反,有两个变量,一个用于原始变量,一个用于最近的旋转。

So instead of: 所以代替:

car1 = original_image_rect
car1 = pygame.transform.rotate(car1, 10)
car1 = pygame.transform.rotate(car1, 10)
...

You would do: 你会这样做:

car1 = original_image_rect
car2 = pygame.transform.rotate(car1, 10)
car2 = pygame.transform.rotate(car1, 20)
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM