2017-12-14 1 views
2

Ich erstelle ein grundlegendes Panzerspiel und arbeite gerade an der Kanone des Panzers. Ich habe es geschafft, die Waffe um eine Achse rotieren zu lassen und sie bewegt sich, wenn man die "a" und "d" Tasten drückt, aber manchmal, wenn die Waffe gedreht wurde und dann bewegt wird, bewegt sie sich aus irgendeinem Grund nach rechts. Hier ist der Code:Pygame sprite springt herum, nachdem es gedreht und dann bewegt wurde

class tankGun(pygame.sprite.Sprite): 
    def __init__(self): 
     super().__init__() 
     self.image = tankGunImage 
     self.rect = self.image.get_rect() 
     self.x = 400 
     self.xx = 410 
     self.y = 400 
     self.rect.x = self.x 
     self.rect.y = self.y 
     self.angle = 0 
     self.original = self.image 
     tankGunList.add(self) 
     tankGunList.draw(gameDisplay) 

def rotate(self, chk): 
    test = False 
    if chk == 1: 
     self.angle += 1 
    elif chk == 2: 
     self.angle -= 1 
    if self.angle > 0 and self.angle < 180: 
     test = True 
    else: 
     if chk == 1: 
      self.angle = 180 
     elif chk == 2: 
      self.angle = 0 
    if test == True: 
     self.image = pygame.transform.rotate(self.original, self.angle) 
     tankGunList.clear(gameDisplay, background) 
     tankGunList.draw(gameDisplay) 
     self.rect = self.image.get_rect(center = self.rect.center) 

def move(self, chk): 
    self.x += chk 
    self.xx = self.x + 10 
    self.rect.x = self.x 
    tankGunList.clear(gameDisplay, background) 
    tankGunList.draw(gameDisplay)   

(Randbemerkung: chk entweder +1 eingesandt oder -1 für die Bewegung und 1 oder 2 für die Rotation Es ist nur eine Art und Weise des Erfassens der Taste gedrückt wurde.).

+0

BTW: 'self.x' hat immer den gleichen Wert wie' self.rect.x', so dass Sie nur 'self.rect.x' verwenden können, und entfernen Sie' self.x' - das gleiche mit ' self.y' – furas

+0

es scheint, dass Sie 'tankGunList.draw (gameDisplay)' an drei Stellen verwenden. Sie sollten nur einmal - in Hauptschleife zeichnen – furas

Antwort

0

Ich weiß nicht, warum Sie ein Problem haben - ich kann es nicht ausführen, um das Problem zu sehen.

Aber ich zeige was ich ändern würde. Vielleicht wird es helfen.

Zuerst würde ich besser lesbare Namen anstelle von chk - dh verwenden. direction, step

class tankGun(pygame.sprite.Sprite): 

    def __init__(self): 
     super().__init__() 

     self.original = tankGunImage 
     self.image = self.original 

     self.rect = self.image.get_rect() 
     self.rect.x = 400 
     self.rect.y = 400 

     self.xx = self.rect.x + 10 

     self.angle = 0 

     tankGunList.add(self) 

    def rotate(self, direction): 
     rotate_image = False 

     if direction == 1: 
      if self.angle < 180 
       self.angle += 1 
       rotate_image = True 
     elif direction == 2: 
      if self.angle > 0 
       self.angle -= 1 
       rotate_image = True 

     if rotate_image == True: 
      self.image = pygame.transform.rotate(self.original, self.angle) 
      self.rect = self.image.get_rect(center=self.rect.center) 

    def move(self, step): 
     self.rect.x += step 
     self.xx = self.rect.x + 10 

# --- in mainloop --- 

tankGunList.clear(gameDisplay, background) 
tankGunList.draw(gameDisplay) 
0

Das Problem tritt auf, weil Sie die self.x Position nach einer Drehung nicht aktualisieren. Wenn Sie ein Bild drehen, wird seine Begrenzungsboxgröße geändert, und die Position des neuen Rects x self.rect.x wird geändert. Das self.x Attribut bleibt jedoch immer gleich und wenn Sie den Tank das nächste Mal bewegen, synchronisieren Sie self.x und self.rect.x erneut und es springt.

das Problem zu beheben, nur self.x nach einer Drehung aktualisieren:

if turn == True: 
    self.image = pg.transform.rotate(self.original, self.angle) 
    self.rect = self.image.get_rect(center=self.rect.center) 
    self.x = self.rect.x 

ich eher die x und y Attribute für die Mitte coords und setzte self.rect.center = (self.x, self.y) dann verwenden würde, so dass Sie nicht zu Aktualisieren Sie die self.x nach einer Drehung.

import pygame as pg 


pg.init() 
screen = pg.display.set_mode((640, 480)) 
tankGunImage = pg.Surface((30, 50), pg.SRCALPHA) 
tankGunImage.fill((70, 200, 30)) 


class tankGun(pg.sprite.Sprite): 
    def __init__(self): 
     super().__init__() 
     self.image = tankGunImage 
     self.rect = self.image.get_rect() 
     self.x = 300 # Center x. 
     self.xx = 310 
     self.y = 200 # Center y. 
     # Set the center attributes. 
     self.rect.centerx = self.x 
     self.rect.centery = self.y 
     self.angle = 0 
     self.original = self.image 

    def rotate(self, chk): 
     turn = False 
     if chk == 1: 
      self.angle += 4 
     elif chk == 2: 
      self.angle -= 4 
     if self.angle > 0 and self.angle < 180: 
      turn = True 
     else: 
      if chk == 1: 
       self.angle = 180 
      elif chk == 2: 
       self.angle = 0 

     if turn == True: 
      self.image = pg.transform.rotate(self.original, self.angle) 
      self.rect = self.image.get_rect(center=self.rect.center) 
      # No need to update the `self.x` now, since the center stays the same. 

    def move(self, chk): 
     self.x += chk 
     self.xx = self.x + 10 
     self.rect.center = (self.x, self.y) 


def main(): 
    clock = pg.time.Clock() 
    color = pg.Color(30, 30, 30) 
    all_sprites = pg.sprite.Group() 
    tank = tankGun() 
    all_sprites.add(tank) 

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

     keys = pg.key.get_pressed() 
     if keys[pg.K_a]: 
      tank.rotate(1) 
     if keys[pg.K_d]: 
      tank.rotate(2) 
     if keys[pg.K_j]: 
      tank.move(-4) 
     if keys[pg.K_l]: 
      tank.move(4) 
     all_sprites.update() 

     screen.fill(color) 
     all_sprites.draw(screen) 
     pg.display.flip() 
     clock.tick(30) 


if __name__ == '__main__': 
    main() 
    pg.quit() 
Verwandte Themen