Python Pygame变换:按键旋转形状

Python Pygame变换:按键旋转形状,python,pygame,Python,Pygame,我是Pygame的新手,似乎找不到可靠的答案。我有一个形状,特别是一个椭圆,我想左右旋转。键绑定将是a和d,因为箭头键已绑定为在x、y轴上左右移动 我知道它涉及到pygame.transform.rotate,但我似乎无法正确实现这一点 def main(): #设置pygame的基本变量和方法 pygame.init() 窗宽=800 窗高=700 fps=45 clock=pygame.time.clock() gameWindow=pygame.display.set_模式((窗口宽度、窗

我是Pygame的新手,似乎找不到可靠的答案。我有一个形状,特别是一个椭圆,我想左右旋转。键绑定将是
a
d
,因为箭头键已绑定为在x、y轴上左右移动

我知道它涉及到
pygame.transform.rotate
,但我似乎无法正确实现这一点

def main():
#设置pygame的基本变量和方法
pygame.init()
窗宽=800
窗高=700
fps=45
clock=pygame.time.clock()
gameWindow=pygame.display.set_模式((窗口宽度、窗口高度))
surface=pygame.surface((50,50))
黑色=(0,0,0)
白色=(255,255,255)
shipX=窗宽/2
shipY=窗宽/2
船速=4
虽然(正确):
pygame.draw.ellipse(游戏窗口,白色,(shipX,shipY,20,30))
#监控游戏的FPS
时钟滴答声(fps)
对于pygame.event.get()中的事件:
# ________________________________________
如果event.type==pygame.QUIT:
gameExit()
旋转=0
pressed=pygame.key.get_pressed()
如果按下[pygame.K_UP]和shipY>shipSpeed:shipY-=shipSpeed
如果按下[pygame.K_DOWN]并shipYshipSpeed:shipX-=shipSpeed
如果按下[pygame.K_RIGHT]并shipX
预期结果是形状将改变其角度,然后相应地移动


再说一次,我对pygame非常陌生,因此任何详细的帮助都将不胜感激。

您应该为您的对象创建一个类:

class myRect(pygame.Surface):
    def __init__(self, parent, xpos, ypos, width, height):
      super(myRect, self).__init__(width, height)
      self.xpos = xpos
      self.ypos = ypos
      self.parent = parent

    def update(self, parent):
      parent.blit(self, (self.xpos, self.ypos))

    def rotate(self, angle):
      #(your rotation code goes here)

您的问题是您直接在屏幕上绘制椭圆,但您应该在另一个屏幕上绘制椭圆

然后,您可以使用旋转来旋转新的

下面是一个简单的例子:

import pygame
import random

def main():
    pygame.init()
    screen = pygame.display.set_mode((500, 500))
    screen_rect = screen.get_rect()
    clock = pygame.time.Clock()
    surface = pygame.Surface((100, 200))
    surface.set_colorkey((2, 3, 4))
    surface.fill((2, 3, 4))
    rect = surface.get_rect(center=(100, 100))
    pygame.draw.ellipse(surface, pygame.Color('white'), (0, 0, 100, 200))
    angle = 0    
    dt = 0
    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return

        pressed = pygame.key.get_pressed()
        if pressed[pygame.K_UP]: rect.move_ip(0, -5)
        if pressed[pygame.K_DOWN]: rect.move_ip(0, 5)
        if pressed[pygame.K_LEFT]: rect.move_ip(-5, 0)
        if pressed[pygame.K_RIGHT]: rect.move_ip(5, 0)
        if pressed[pygame.K_a]: angle += 1
        if pressed[pygame.K_d]: angle -= 1

        rotated = pygame.transform.rotate(surface, angle)
        rect = rotated.get_rect(center=rect.center)

        rect.clamp_ip(screen_rect)

        screen.fill(pygame.Color('dodgerblue'))
        screen.blit(rotated, rect.topleft)
        pygame.display.update()
        dt = clock.tick(60)

if __name__ == '__main__':
    main()
请注意,我使用a来存储对象的位置,因为这样很容易围绕其中心旋转
曲面
(通过设置其
中心
属性),并确保
曲面
不会超出屏幕(通过使用)

另外,始终旋转源
曲面
,而不是已旋转的
曲面
,这一点很重要。否则,您将得到扭曲


请注意,这里有三件事:一个图像、一个位置和一些行为逻辑。每当你看到这些东西时,考虑把它们组合成一个类。Pygame已经为此提供了一个很好的类,名为

下面是相同的示例,但基于Sprite的:

import pygame
import random

class Thingy(pygame.sprite.Sprite):
    def __init__(self, area):
        super().__init__()
        # image is what get's painted on the screen
        self.image = pygame.Surface((100, 200))
        self.image.set_colorkey((2, 3, 4))
        self.image.fill((2, 3, 4))
        pygame.draw.ellipse(self.image, pygame.Color('white'), (0, 0, 100, 200))
        # we keep a reference to the original image
        # since we use that for rotation to prevent distortions
        self.original = self.image.copy()
        # rect is used to determine the position of a sprite on the screen
        # the Rect class also offers a lot of useful functions
        self.rect = self.image.get_rect(center=(100, 100))
        self.angle = 0  
        self.area = area

    def update(self, events, dt):
        pressed = pygame.key.get_pressed()
        if pressed[pygame.K_UP]: self.rect.move_ip(0, -5)
        if pressed[pygame.K_DOWN]: self.rect.move_ip(0, 5)
        if pressed[pygame.K_LEFT]: self.rect.move_ip(-5, 0)
        if pressed[pygame.K_RIGHT]: self.rect.move_ip(5, 0)
        if pressed[pygame.K_a]: self.angle += 1
        if pressed[pygame.K_d]: self.angle -= 1

        # let's rotate the image, but ensure that we keep the center position
        # so it doesn't "jump around"
        self.image = pygame.transform.rotate(self.original, self.angle)
        self.rect = self.image.get_rect(center=self.rect.center)
        self.rect.clamp_ip(self.area)

def main():
    pygame.init()
    screen = pygame.display.set_mode((500, 500))
    screen_rect = screen.get_rect()
    clock = pygame.time.Clock()
    sprites = pygame.sprite.Group(Thingy(screen_rect))
    dt = 0
    while True:
        # nice clean main loop
        # all game logic goes into the sprites

        # handle "global" events
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return

        # update all sprites
        sprites.update(events, dt)

        # draw everything
        screen.fill(pygame.Color('dodgerblue'))
        sprites.draw(screen)
        pygame.display.update()
        dt = clock.tick(60)

if __name__ == '__main__':
    main()

我懂了。所以转换代码进入了旋转定义,并且在按键时调用了这个类?有道理。我将尝试在您想要创建对象时调用outClass。现在您只需在按键上调用
class instance.rotate()