精灵在圆上的旋转 [英] Rotation of a sprite on a circle

查看:55
本文介绍了精灵在圆上的旋转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个精灵在以屏幕中心为中心、半径 = 30 像素的圆上移动.运动或多或少是可以的,但精灵根本不旋转.我已经尝试了一些教程(例如

导入pygame类敌人强(pygame.sprite.Sprite):def __init__(self):pygame.sprite.Sprite.__init__(self)self.original_image = pygame.image.load(r"arrow_up.png").convert_alpha()self.image = self.original_imageself.rect = self.image.get_rect()self.angle = 0def initLoc(self, pos, radius):self.pos = posself.radius = 半径定义更新(自我):center = pygame.math.Vector2(self.pos) + pygame.math.Vector2(0, -self.radius).rotate(-self.angle)self.image = pygame.transform.rotate(self.original_image, self.angle)self.rect = self.image.get_rect(center = (round(center.x), round(center.y)))定义左转(自我):self.angle = (self.angle + 1) % 360pygame.init()窗口 = pygame.display.set_mode((500, 500))时钟 = pygame.time.Clock()敌人_s = EnemiesStrong()敌人_s.initLoc(window.get_rect().center, 100)all_sprites = pygame.sprite.Group(enemy_s)运行 = 真运行时:时钟滴答(60)对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:运行 = 错误敌人_s.turnLeft()all_sprites.update()window.fill(0)pygame.draw.circle(window, (127, 127, 127), window.get_rect().center, 100, 1)all_sprites.draw(窗口)pygame.display.flip()pygame.quit()出口()

There's a sprite moving on a circle centered around the screen center with radius = 30 pixels. The movement is more or less OK, but the sprite doesn't rotate at all. I've tried some tutorials (e.g. How to animate scale and rotate in pygame using rotozoom), and when the sprite moves along a line or changes its trajectory randomly -there's no problem. So what's wrong when it's moving along the circle? Here's the code:

class EnemiesStrong(pygame.sprite.Sprite):
    
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)     
        self.image = pygame.image.load("enemy3.png").convert_alpha()
        self.image2 = self.image        
        self.rect = self.image2.get_rect()  
        self.angle = 0
        
    def initLoc(self, pos, x_pos, y_pos):
        
        self.rect.x = pos[0]/2 + x_pos
        self.rect.y = y_pos
        
    
    def update(self, pos, x_pos, y_pos, quadrant, newcoord):
        #print(quadrant)
        
        self.rect.y = y_pos
        
        
        if (quadrant==1 and newcoord==0):
            self.rect.x-=1            
        elif (quadrant==1 and newcoord==1):
            self.rect.x=x_pos
                    
        elif (quadrant==2):           
                        
            oldcenter = self.rect.center
            **self.image2 = pygame.transform.rotate(self.image, self.angle)**
            self.rect = self.image2.get_rect()
            self.rect.center = oldcenter  
            self.rect.x+=1
                        
            
        elif (quadrant==3 and newcoord==0):
            self.rect.x+=1   
                                
        elif (quadrant==4 and newcoord==0):
            self.rect.x-=1
        elif (quadrant==4 and newcoord==1):
            self.rect.x=x_pos                   
                
    def turnLeft(self, pos):

        self.angle = (self.angle + 10) % 360
        print(self.angle)
        
    def whereEnemy(self):
        return (self.rect.x, self.rect.y)    

def OrbitalCoordinates(loc, xpos, radius, quadrant):

    #do lots of stuff to determine the location of the ship in the screen
    #and return its Y-coordinate
    disc = np.power(radius,2) - np.power(xpos - loc[0]/2,2)
    ypos = loc[1]/2 - np.sqrt(disc)                
    return ypos

enemy_s = EnemiesStrong()
ypos = OrbitalCoordinates(screenpar, xpos + screenpar[0]/2, radius,2)
enemy_s.initLoc(screenpar, xpos, ypos)
enemiesupdate.add(enemy_s)
where_strong_enemy = enemy_s.whereEnemy()
bg = pygame.image.load("outer_space.jpg")
screenpar = [bg.get_width(), bg.get_height()]

def main():
    #various useless crap
    for enemy_s in enemiesupdate:
            #do lots of stuff to determine the x- position and direction of movement of the ship 
            #and pass these values to OrbitalCoordinates  
            enemy_s.turnLeft(screenpar) 
            ypos = OrbitalCoordinates(screenpar, where_strong_enemy[0], radius, quadrant)
            enemy_s.update(screenpar, where_strong_enemy[0], ypos, quadrant, 0)
            where_strong_enemy = list(enemy_s.whereEnemy())
            #then check if the y-coordinates are close to the middle of the screen to tweak them a                          
            #little bit
screen.blit(bg, [0, 0])   
enemiesupdate.draw(screen)
pygame.display.flip()

I omitted chunks of code that I deem unnecessary. I'm sure there's some stupid mistake I'm making.

解决方案

Read the documentation of pygame.sprite.Group.draw:

Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect for the position.

Therefore, the rotated image must be stored in the image attribute. You will not see any rotation because you save the rotated image in the image2 attribute, but image is the originally rotated image. Store the original image in original_image and the rotated image in image:

class EnemiesStrong(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)     
        self.image = pygame.image.load("enemy3.png").convert_alpha()
        self.image = self.original_image        
        self.rect = self.image.get_rect()  
        self.angle = 0

    def update(self):
        # [...]

        self.image = pygame.transform.rotate(self.original_image, self.angle)
        self.rect = self.image.get_rect(center = oldcenter)

        # [...]      

See also Move and rotate.


Minimal example:

import pygame

class EnemiesStrong(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)     
        self.original_image = pygame.image.load(r"arrow_up.png").convert_alpha()
        self.image = self.original_image        
        self.rect = self.image.get_rect()  
        self.angle = 0

    def initLoc(self, pos, radius):
        self.pos = pos
        self.radius = radius

    def update(self):
        center = pygame.math.Vector2(self.pos) + pygame.math.Vector2(0, -self.radius).rotate(-self.angle) 
        self.image = pygame.transform.rotate(self.original_image, self.angle)
        self.rect = self.image.get_rect(center = (round(center.x), round(center.y)))            

    def turnLeft(self):
        self.angle = (self.angle + 1) % 360
   
pygame.init()
window = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()

enemy_s = EnemiesStrong()
enemy_s.initLoc(window.get_rect().center, 100)
all_sprites = pygame.sprite.Group(enemy_s)

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    enemy_s.turnLeft()
    all_sprites.update()

    window.fill(0)
    pygame.draw.circle(window, (127, 127, 127), window.get_rect().center, 100, 1)
    all_sprites.draw(window)
    pygame.display.flip()

pygame.quit()
exit()

这篇关于精灵在圆上的旋转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆