在pygame中旋转一个矩形(不是图像)
Posted
技术标签:
【中文标题】在pygame中旋转一个矩形(不是图像)【英文标题】:Rotating a rectangle (not image) in pygame 【发布时间】:2016-04-08 23:15:45 【问题描述】:在 pygame 中,我对程序中的所有矩形都使用 pygame.draw.rect(screen, color, rectangle)
。我希望能够将这些矩形旋转到任何角度。我看过以下代码来旋转 IMAGES,但我的问题是 RECTANGLES。
pygame.transform.rotate(image, angle)
但我正在使用矩形,我没有可以旋转的图像或“表面”。当我尝试用
旋转一个矩形时rect = pygame.draw.rect(screen, self.color, self.get_rectang())
rotatedRect = pygame.transform.rotate(rect, self.rotation)
screen.blit(rotatedRect)
这使得TypeError: must be pygame.Surface, not pygame.Rect
与 .rotate() 一致
我的问题是,如何在 pygame 中旋转并显示 RECTANGLE(x,y,w,h)
,而不是图像。
这是“潜在重复”的链接帖子不是重复的。一个答案解释了旋转矩形的后果,另一个使用代码来旋转图像。
【问题讨论】:
您可以像这样自己旋转 4 个点中的每一个x2= cos a * x1 - sin a y1
y2= sin a *x1 + cos a y1
,但是 rectangle 函数可能只绘制一个与轴对齐的矩形,所以你必须看用于多边形绘图功能。或者,您可以制作带有可见轮廓和透明填充 (alpha) 的surface
,这可能更容易。 rectangle 可能只是 pygame 中的辅助函数,不能直接显示,所以最后一行有两个单独的问题。
我在发布我的问题之前阅读了这一点。这不是重复的,看看答案,他们解释了如何旋转图像。这是来自image2 = pygame.transform.rotate(image1, angle)
答案之一的引述,而接受的答案并没有解释任何关于实际旋转矩形的内容,只是一些意想不到的后果
@roadrunner66 我希望我能够避免在多边形中进行三角和绘图点,但我很欣赏这个建议,如果没有更简单的方法,我会这样做
问题是重复的,因为您无法旋转矩形。您必须创建一个透明的 Surface 并旋转 Surface。
【参考方案1】:
在此处查看第二个答案:Rotating a point about another point (2D)
我认为矩形只能是水平或垂直的。您需要定义角并旋转它们,然后在它们之间绘制和填充。
另一种方法是创建一个类
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)
并改用它,这样您就可以使用变换功能旋转它。
【讨论】:
【参考方案2】:import pygame as py
# define constants
WIDTH = 500
HEIGHT = 500
FPS = 30
# define colors
BLACK = (0 , 0 , 0)
GREEN = (0 , 255 , 0)
# initialize pygame and create screen
py.init()
screen = py.display.set_mode((WIDTH , HEIGHT))
# for setting FPS
clock = py.time.Clock()
rot = 0
rot_speed = 2
# define a surface (RECTANGLE)
image_orig = py.Surface((100 , 100))
# for making transparent background while rotating an image
image_orig.set_colorkey(BLACK)
# fill the rectangle / surface with green color
image_orig.fill(GREEN)
# creating a copy of orignal image for smooth rotation
image = image_orig.copy()
image.set_colorkey(BLACK)
# define rect for placing the rectangle at the desired position
rect = image.get_rect()
rect.center = (WIDTH // 2 , HEIGHT // 2)
# keep rotating the rectangle until running is set to False
running = True
while running:
# set FPS
clock.tick(FPS)
# clear the screen every time before drawing new objects
screen.fill(BLACK)
# check for the exit
for event in py.event.get():
if event.type == py.QUIT:
running = False
# making a copy of the old center of the rectangle
old_center = rect.center
# defining angle of the rotation
rot = (rot + rot_speed) % 360
# rotating the orignal image
new_image = py.transform.rotate(image_orig , rot)
rect = new_image.get_rect()
# set the rotated rectangle to the old center
rect.center = old_center
# drawing the rotated rectangle to the screen
screen.blit(new_image , rect)
# flipping the display after drawing everything
py.display.flip()
py.quit()
【讨论】:
【参考方案3】:快速替换的更复杂版本,您可以在其中为矩形定义任意旋转中心点 - 甚至在矩形之外(在 python3 中测试):
def rectRotated( surface, color, pos, fill, border_radius, rotation_angle, rotation_offset_center = (0,0), nAntialiasingRatio = 1 ):
"""
- rotation_angle: in degree
- rotation_offset_center: moving the center of the rotation: (-100,0) will turn the rectangle around a point 100 above center of the rectangle,
if (0,0) the rotation is at the center of the rectangle
- nAntialiasingRatio: set 1 for no antialising, 2/4/8 for better aliasing
"""
nRenderRatio = nAntialiasingRatio
sw = pos[2]+abs(rotation_offset_center[0])*2
sh = pos[3]+abs(rotation_offset_center[1])*2
surfcenterx = sw//2
surfcentery = sh//2
s = pg.Surface( (sw*nRenderRatio,sh*nRenderRatio) )
s = s.convert_alpha()
s.fill((0,0,0,0))
rw2=pos[2]//2 # halfwidth of rectangle
rh2=pos[3]//2
pg.draw.rect( s, color, ((surfcenterx-rw2-rotation_offset_center[0])*nRenderRatio,(surfcentery-rh2-rotation_offset_center[1])*nRenderRatio,pos[2]*nRenderRatio,pos[3]*nRenderRatio), fill*nRenderRatio, border_radius=border_radius*nRenderRatio )
s = pygame.transform.rotate( s, rotation_angle )
if nRenderRatio != 1: s = pygame.transform.smoothscale(s,(s.get_width()//nRenderRatio,s.get_height()//nRenderRatio))
incfromrotw = (s.get_width()-sw)//2
incfromroth = (s.get_height()-sh)//2
surface.blit( s, (pos[0]-surfcenterx+rotation_offset_center[0]+rw2-incfromrotw,pos[1]-surfcentery+rotation_offset_center[1]+rh2-incfromroth) )
【讨论】:
【参考方案4】:添加旋转的基本 pygame 函数的快速替换:
def rectRotated( surface, color, pos, fill, border_radius, angle ):
"""
- angle in degree
"""
max_area = max(pos[2],pos[3])
s = pg.Surface((max_area,max_area))
s = s.convert_alpha()
s.fill((0,0,0,0))
pg.draw.rect(s, color,(0,0,pos[2],pos[3]),fill, border_radius=border_radius)
s = pygame.transform.rotate(s,angle)
surface.blit( s, (pos[0],pos[1]) )
【讨论】:
【参考方案5】:您不能旋转由pygame.draw.rect
绘制的矩形。你必须创建一个透明的pygame.Surface
并旋转Surface:
rect_surf = pygame.Surface((widht, height), pygame.SRCLAPHA)
rect_surf.fill(color)
请参阅How do I rotate an image around its center using PyGame?,以旋转表面。
【讨论】:
【参考方案6】:此代码模拟旋转的矩形落向地面。我在我的一个游戏中使用它来使背景看起来很棒
import pygame
import random
class Square(pygame.sprite.Sprite):
def __init__(self, x, y):
super(Square, self).__init__()
self.win = win
self.color = (128, 128, 128)
self.speed = 3
self.angle = 0
self.side = random.randint(15, 40)
self.surface = pygame.Surface((self.side, self.side), pygame.SRCALPHA)
self.surface.set_colorkey((200,200,200))
self.rect = self.surface.get_rect(center=(x, y))
def update(self, win):
center = self.rect.center
self.angle = (self.angle + self.speed) % 360
image = pygame.transform.rotate(self.surface , self.angle)
self.rect = image.get_rect()
self.rect.center = center
self.rect.y += 1.5
if self.rect.top >= HEIGHT:
self.kill()
pygame.draw.rect(self.surface, self.color, (0,0, self.side, self.side), 4)
win.blit(image, self.rect)
if __name__ == '__main__':
pygame.init()
SCREEN = WIDTH, HEIGHT = 288, 512
win = pygame.display.set_mode(SCREEN, pygame.NOFRAME)
clock = pygame.time.Clock()
FPS = 60
count = 0
square_group = pygame.sprite.Group()
running = True
while running:
win.fill((200,200,200))
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
count += 1
if count % 100 == 0:
x = random.randint(40, WIDTH-40)
y = 0
square = Square(x, y)
square_group.add(square)
count = 0
square_group.update(win)
pygame.draw.rect(win, (30,30,30), (0, 0, WIDTH, HEIGHT), 8)
clock.tick(FPS)
pygame.display.update()
pygame.quit()
这是输出,虽然不是 gif 图像
现在,如果您想要填充颜色的矩形而不是仅带边框,请在第 31 行更新此行
pygame.draw.rect(self.surface, self.color, (0,0, self.side, self.side))
如果您不希望矩形从第 26 行注释掉下来
【讨论】:
以上是关于在pygame中旋转一个矩形(不是图像)的主要内容,如果未能解决你的问题,请参考以下文章