使用Pygame和Pyganim旋转时如何保持图像居中

时间:2014-06-04 14:24:45

标签: python rotation pygame image-rotation

Python版本:3.4

我最近开始使用Pygame,然后我开始使用模块pyganim来处理sprite的动画。 http://inventwithpython.com/pyganim/

当我尝试旋转动画时,我遇到了一个问题。它有一个奇怪的效果,如本例http://i.imgur.com/g6Os9.gif所示,来自这个问题:

Weird shifting when using pygame.transform.rotate()

我尝试了多种修复方法,例如找到图像的中心等,但因为它是一个pyganim对象,我对我的表面如下:(屏幕是我的表面)

player.blit(screen, playerpos)

改变它的中心似乎没有效果。

我还尝试将我用的图像换成一个完整的黑色方块,而且我仍然没有运气调试它。

我认为这是因为我将pyganim对象与我的表面进行了对比,而且我需要将它blit到另一个表面并旋转它? < - 猜测!

我认为这个问题就在这里,

# Set player position and rotation
position = pygame.mouse.get_pos()
angle = math.atan2(position[1]-(playerpos[1]),position[0]-(playerpos[0]))
player.clearTransforms()
player.rotate((360-angle*57.29)-90)
playerpos1 = (playerpos[0]-(player.getRect().width/2), playerpos[1]-(player.getRect().height/2))
player.blit(screen, playerpos1) 

由于Pyganim对象的实际矩形没有变化,无论对它进行什么旋转(我都有一些屏幕记录,我验证了这一点)。我认为修正的标准方法是无效的。

如果任何有使用Pyganim的经验的人都能发光,那就太棒了!

以下是完整的代码......

# Import modules
import pygame
from pygame.locals import *
import pyganim
import math

# Initialise
pygame.init()
width, height = 640, 480
screen=pygame.display.set_mode((width, height))
keys = [False, False, False, False]
playerpos=[100,100]

# Load images
player = pyganim.PygAnimation([('resources/images/tdt/p1.png', 0.3), ('resources/images/tdt/p2.png', 0.3), ('resources/images/tdt/p3.png', 0.3), ('resources/images/tdt/p2.png', 0.3)])
player.play()
grass = pygame.image.load("resources/images/tdt/bg.png")
grasswidth = grass.get_width()
grassheight = grass.get_height()
myfont = pygame.font.SysFont("monospace", 20)


# loop
while 1:
# clear the screen before re-drawing
screen.fill(0)

# draw the screen elements
for x in range(width//grasswidth+1):
    for y in range(height//grassheight+1):
        screen.blit(grass,(x*100,y*100))

# Set player position and rotation
position = pygame.mouse.get_pos()
angle = math.atan2(position[1]-(playerpos[1]),position[0]-(playerpos[0]))
player.clearTransforms()
player.rotate((360-angle*57.29)-90)
playerpos1 = (playerpos[0]-(player.getRect().width/2), playerpos[1]-(player.getRect().height/2))
player.blit(screen, playerpos1) 


# render text
label = myfont.render("X pos: "+str(playerpos[0])+"| Y pos: "+str(playerpos[1]), 1, (255,255,0))
screen.blit(label, (20, 20))    

# Update the screen
pygame.display.flip()

# loop through the events
for event in pygame.event.get():
    #check if the event is the X button
    if event.type==pygame.QUIT:
        ##if it is, quit the game
        pygame.quit()
        exit(0)

    if event.type == pygame.KEYDOWN:
        if event.key==K_w:
            keys[0]=True
        elif event.key==K_a:
            keys[1]=True
        elif event.key==K_s:
            keys[2]=True
        elif event.key==K_d:
            keys[3]=True
    if event.type == pygame.KEYUP:
        if event.key==pygame.K_w:
            keys[0]=False
        elif event.key==pygame.K_a:
            keys[1]=False
        elif event.key==pygame.K_s:
            keys[2]=False
        elif event.key==pygame.K_d:
            keys[3]=False

# Move player
if keys[0]: # W
    playerpos[1]-=2
elif keys[2]: # S
    playerpos[1]+=2
if keys[1]: # A
    playerpos[0]-=2
elif keys[3]: # D
    playerpos[0]+=2

我已经在这方面取得了一些进展...我现在编写的代码是基本的,适用于有问题的形状,因为它很容易被4整除! :D但是,我会重新编写它以便能够处理所有可能性,但是,可能是方框必须是方形的:现在是代码:

playerpos1 = rMoveAmount(playerpos,angle, 44)
player.blit(screen, playerpos1) 

rMoveAmount为:

def rMoveAmount(position, degrees, picsize):
#MOVE A BOX DEPENDING ON THE AMOUNT ROTATED
degTest = int(((360-degrees*57.29)-180)%90) 
#Has to be split up into two sections, before the half 90 degree rotation
if degTest < 45:
    t = int((((360-angle*57.29)-180)%45)//4) 
    nPos = (position[0] - t , position[1] - t )
#And after
if degTest > 44: 
    t = int((((360-angle*57.29)-180)%45)//4) 
    nPos = (position[0] + t - 11, position[1] + t - 11)

return nPos

所以 它需要1/4的角度(在0到11之间) 然后它使用它作为偏移(因为我的pic是44px,总是需要移动1/4)

如您所见,目前使用的是pic尺寸。而且我认为只是运气,我的照片尺寸为44,并且非常贴合到90度旋转的中间,并且还可以除以11.但是,我将努力使用更灵活的尺寸并更新。

编辑3:

好的,这个应该适用于所有方形图像,它也会正确地居中光标。我将只显示所做的更改,而不是再次显示整个代码:

# 3 - Load images
player = pyganim.PygAnimation([('resources/images/tdt/p1.png', 0.3), ('resources/images/tdt/p2.png', 0.3), ('resources/images/tdt/p3.png', 0.3), ('resources/images/tdt/p2.png', 0.3)])
player.play()
playerSize = player.getRect().width


 # 6.1 - Set player position and rotation
position = pygame.mouse.get_pos()
angle = math.atan2(position[1]-(playerpos[1]+(playerSize/2)),position[0]-(playerpos[0]+(playerSize/2)))
player.clearTransforms()
player.rotate((360-angle*57.29)-90)
playerpos1 = rMoveAmount(playerpos,angle, playerSize)
player.blit(screen, playerpos1)

rMoveAmount方法改变了:

def rMoveAmount(position, degrees, picsize):
#MOVE A BOX DEPENDING ON THE AMOUNT ROTATED
degTest = int(((360-degrees*57.29)-180)%90)
quartsize = picsize / 4
#Has to be split up into two sections, before the half 90 degree rotation
if degTest < 45:
    #t = int((((360-angle*57.29)-180)%45)//4)
    jump = (quartsize / 44)
    nPos = (position[0] - (jump * degTest)   , position[1] - (jump * degTest)  )
#And after
if degTest > 44:
    jump = (quartsize / 44)
    nPos = (position[0] + (jump * degTest) - (picsize/2) , position[1] + (jump * degTest) - (picsize/2))
return nPos

现在可以使用任何方形图像。

0 个答案:

没有答案