2017-12-05 31 views
1

私は数日前にこれについて頭を悩まされてきました。私はその中央軸上のスプライトを回転させるようにしようとしていると同じ問題について、この前の記事を参照されています:Pygame + Spriteの回転は中央に残っていない

How do I rotate an image around its center using Pygame?

私は以前の記事で説明したように正確に同じコードを使用していますし、また、連続的な回転で画像を歪ませないようにimage_clean属性を利用する。スプライトを回転させようとすると、イメージの中心が2つのポイント間を行き来します。

rot_sprite.get_rect().center = loc 

が画像中心に loc値を代入していないよう:

def rotate_center(image, angle): 
    """rotate a Surface, maintaining position.""" 
    loc = image.get_rect().center #rot_image is not defined 
    rot_img = pg.transform.rotate(image, angle) 
    print('') 
    print('>>> before: ' + str(rot_img.get_rect().center)) 
    rot_img.get_rect().center = loc 
    print('>>> after: ' + str(rot_img.get_rect().center)) 
    return rot_img 

print文はその行を確認してください。出力は常に次のようになります。

>>> before: (32, 32) 
>>> after: (32, 32) 

>>> before: (37, 37) 
>>> after: (37, 37) 

>>> before: (41, 41) 
>>> after: (41, 41) 

>>> before: (43, 43) 
>>> after: (43, 43) 

>>> before: (45, 45) 
>>> after: (45, 45) 

>>> before: (45, 45) 
>>> after: (45, 45) 

>>> before: (43, 43) 
>>> after: (43, 43) 

>>> before: (41, 41) 
>>> after: (41, 41) 

>>> before: (37, 37) 
>>> after: (37, 37) 

私は常にセンターを(32,32)にします(私は信じています)。どんな助けでも大歓迎です。

コード:

def main(): 
    pg.init() 

# Screen Setup 
size = (SCREEN_WIDTH, SCREEN_HEIGHT) 
screen = pg.display.set_mode(size) 
screen_flags = screen.get_flags() 
pg.display.set_caption(GAME_NAME) 
done = False 
clock = pg.time.Clock() 

# SPRITE GROUPS 
all_sprites = pg.sprite.Group() 
turrets = pg.sprite.Group() 

turret = Tower2((SCREEN_WIDTH/2, SCREEN_HEIGHT/2)) 
turrets.add(turret) 
all_sprites.add(turret) 

# -------- Main Program Loop ----------- 
while not done: 
    # Process Incoming Events 
    for event in pg.event.get(): 
     if event.type == pg.QUIT: 
      done = True 
     if event.type == pg.KEYDOWN: 
      if event.key == pg.K_q: 
       done = True 
      if event.key == pg.K_f: 
       if screen_flags & pg.FULLSCREEN == False: 
        screen_flags |= pg.FULLSCREEN 
        pg.display.set_mode(size, screen_flags) 
       else: 
        screen_flags ^= pg.FULLSCREEN 
        pg.display.set_mode(size, screen_flags) 


    turret.angle += 10 
    turret.image = rotate_center(turret.image_clean, turret.angle) 


    screen.fill(WHITE) 
    all_sprites.draw(screen) 
    pg.display.flip() 
    clock.tick(15) 

pg.quit() 


class Tower2(pg.sprite.Sprite): 
    def __init__(self, pos, image, tRange, attackSpeed=1): 
     super().__init__() 
     self.image = image 
     self.image_clean = image 
     self.rect = self.image.get_rect() 
     self.rect.center = pos 
     self.range = tRange 
     self.attackSpeed = attackSpeed 
     self.lastAttack = time.time() 
     self.angle = 0 

    def __iter__(self): 
     return self 

    def canAttack(self): 
     if time.time() - self.lastAttack > self.attackSpeed: 
      return True 
     else: 
      return False 

    def rotate(self): 
     pass 

    def update(self): 
     self.angle += 10 
     self.image = pg.transform.rotate(self.image_clean, self.angle) 
     self.image.get_rect().center = self.image_clean.get_rect().center 



class Turret1(Tower2): 
    def __init__(self, pos):  
     TOWER_WIDTH = 64 
     TOWER_HEIGHT = 64 
     INIT_RANGE = 200 
     INIT_RATE = 1 
     SPEED = 1 
     tower_img = pg.image.load('imgs/test_rotate.png') 
     tower_img = pg.transform.scale(tower_img, (TOWER_WIDTH, TOWER_HEIGHT)) 
     super().__init__(pos, tower_img, INIT_RANGE, SPEED) 
+1

それは常に新しいrectangeを作成するため、 'get_rect()'すべての時間を使用していない - とあなたが値を変更元のものにない新しい矩形。 – furas

答えて

1

あなたはそれがスプライトの実際の位置を保持しているため、同様スプライトの矩形を渡し、その後.get_rectに中央COORDSを渡したり、新たな矩形のcenterに割り当てる必要があります。 .get_rect()を呼び出すだけでは、topleft coords(0、0)でrectを得ることができます。

def rotate_center(image, rect, angle): 
    """Rotate a Surface, maintaining position.""" 
    rot_img = pg.transform.rotate(image, angle) 
    # Get a new rect and pass the center position of the old 
    # rect, so that it rotates around the center. 
    rect = rot_img.get_rect(center=rect.center) 
    return rot_img, rect # Return the new rect as well. 


# In the main while loop. 
turret.angle += 10 
# Also pass the turret's rect which holds the position of the sprite. 
image, rect = rotate_center(turret.image_clean, turret.rect, turret.angle) 
turret.image = image # Assign the new image. 
turret.rect = rect # Assign the new rect. 

また、スプライトのupdate方法でこれを行うことができます:

import pygame as pg 


WHITE = pg.Color('white') 

class Tower2(pg.sprite.Sprite): 
    def __init__(self, pos, tRange=1, attackSpeed=1): 
     super().__init__() 
     self.image = your_image 
     self.image_clean = self.image 
     self.rect = self.image.get_rect() 
     self.rect.center = pos 
     self.angle = 0 

    def update(self): 
     self.angle += 10 
     self.image = pg.transform.rotate(self.image_clean, self.angle) 
     self.rect = self.image.get_rect(center=self.rect.center) 


def main(): 
    pg.init() 

    SCREEN_WIDTH = 640 
    SCREEN_HEIGHT = 480 
    size = (SCREEN_WIDTH, SCREEN_HEIGHT) 
    screen = pg.display.set_mode(size) 
    done = False 
    clock = pg.time.Clock() 

    all_sprites = pg.sprite.Group() 

    turret = Tower2((SCREEN_WIDTH/2, SCREEN_HEIGHT/2)) 
    all_sprites.add(turret) 

    while not done: 
     for event in pg.event.get(): 
      if event.type == pg.QUIT: 
       done = True 

     all_sprites.update() 

     screen.fill(WHITE) 
     all_sprites.draw(screen) 
     pg.display.flip() 
     clock.tick(15) 

main() 
pg.quit() 
2

get_rect()のすべての時間を使用しないでください - それは、常に新しい矩形を作成し、この新しい四角形ではなく、元の位置を変更します。そして、後で位置を表示するために再び新しい矩形を取得します。

画像の位置が保持されず、一度矩形を取得して位置を保持する必要があります。

loc = image.get_rect().center 

rot_img = pg.transform.rotate(image, angle) 

# get rectangle and keep it 
rot_img_rect = rot_img.get_rect() 

# change position in rectangle 
rot_img_rect.center = loc 

# display position 
print('>>> after: ', rot_img_rect.center) 

# return image and position in `rot_img_rect` 
return rot_img, rot_img_rect 
+0

ありがとう! get_rect()が新しい矩形を作成していることを指摘したので意味があります。戻り値をキャッチすることがスプライトのように見えるかどうか知っていますか? sprite.rectにrot_img_rectが代入されていますか? Sprite.image、sprite.rect = rotate_center(sprite.image_clean、sprite.angle)はスプライト全体を(0,0)に置きます。 – Brand0R

+0

私の質問はrot_img_rectがスプライト上でどこに割り当てられるのですか? – Brand0R

関連する問題