2017-10-17 3 views
1

私は小惑星のクローンを作っていますが、プレイヤーのスプライトの動きの角度をどこに保存するのか、弾丸にアクセスする方法が分かりません。今は、私の船の回転がangle_speed変数に格納されていると思います。これは、弾のdest_xとdest_y(目的地のxとy)座標を生成するために使用しています。しかし、弾丸は(0、0)に撮影を続けます。誰でも助けることができますか?Pygame-どのようにプレイヤーのスプライトの方向に撮影する?

try: 
    import sys 
    import math 
    import os 
    import getopt 
    import pygame 
    from pygame.locals import * 
    from pygame.math import Vector2 
except ImportError, err: 
    print "couldn't load module. %s" % (err) 
    sys.exit(2) 

# these are warnings if font or sound modules are not available. 
if not pygame.font: print 'Warning, fonts disabled' 
if not pygame.mixer: print 'Warning, sound disabled' 

SCREEN_WIDTH = 800 
SCREEN_HEIGHT = 600 

BLACK = (0, 0, 0) 
WHITE = (255, 255, 255) 
RED = (255, 0, 0) 
BLUE = (0, 0, 255) 


class Player(pygame.sprite.Sprite): 
    """moves ship on screen""" 
    def __init__(self, pos=(420,420)): 
     super(Player, self).__init__() # call Sprite initializer 
     self.image = pygame.Surface([20, 20]) 
     self.image.fill(RED) 
     self.original_image = self.image 
     self.rect = self.image.get_rect(center=pos) 
     self.position = Vector2(pos) 
     self.direction = Vector2(0,1) 
     self.speed = 0 
     self.angle_speed = 0 
     self.angle = 0 


    def update(self): 
     if self.angle_speed != 0: 
      # Rotate the direction vector and then the image 
      self.direction.rotate_ip(self.angle_speed) 
      self.angle += self.angle_speed 
      self.image = pygame.transform.rotate(self.original_image, -self.angle) 
      self.rect = self.image.get_rect(midtop=self.rect.midtop) 
     # Update the position vector and the rect. 
     self.position += self.direction * self.speed 
     self.rect.center = self.position 
class Bullet(pygame.sprite.Sprite): 
    """ This class represents the bullet. """ 

    def __init__(self, start_x, start_y, dest_x, dest_y): 
     """ Constructor. 
     It takes in the starting x and y location. 
     It also takes in the destination x and y position. 
     """ 

     # Call the parent class (Sprite) constructor 
     super(Bullet, self).__init__() 

     # Set up the image for the bullet 
     self.image = pygame.Surface([4, 10]) 
     self.image.fill(BLACK) 

     self.rect = self.image.get_rect() 

     # Move the bullet to our starting location 
     self.rect.x = start_x 
     self.rect.y = start_y 

     # Because rect.x and rect.y are automatically converted 
     # to integers, we need to create different variables that 
     # store the location as floating point numbers. Integers 
     # are not accurate enough for aiming. 
     self.floating_point_x = start_x 
     self.floating_point_y = start_y 

     # Calculation the angle in radians between the start points 
     # and end points. This is the angle the bullet will travel. 
     x_diff = dest_x - start_x 
     y_diff = dest_y - start_y 
     angle = math.atan2(y_diff, x_diff); 

     # Taking into account the angle, calculate our change_x 
     # and change_y. Velocity is how fast the bullet travels. 
     velocity = 11 
     self.change_x = math.cos(angle) * velocity 
     self.change_y = math.sin(angle) * velocity 

    def update(self): 
     """ Move the bullet. """ 

     # The floating point x and y hold our more accurate location. 
     self.floating_point_y += self.change_y 
     self.floating_point_x += self.change_x 

     # The rect.x and rect.y are converted to integers. 
     self.rect.y = int(self.floating_point_y) 
     self.rect.x = int(self.floating_point_x) 

     # If the bullet flies of the screen, get rid of it. 
     if self.rect.x < 0 or self.rect.x > SCREEN_WIDTH or self.rect.y < 0 or self.rect.y > SCREEN_HEIGHT: 
      self.kill() 

def main(): 


    pygame.init() 
    pygame.mixer.init() 
    pygame.key.set_repeat(500,30) 


    screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT]) 
    pygame.display.set_caption('Asteroids') 

    screen_rect = screen.get_rect() 

    all_sprites_list = pygame.sprite.Group() 
    # List of each bullet 
    bullet_list = pygame.sprite.Group() 
    bullets = [] 

    player = Player() 
    all_sprites_list.add(player) 

    MAXSPEED = 15 
    MINSPEED = -5 

    clock = pygame.time.Clock() 

    done = False 
    while not done: 
     clock.tick(60) 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       done = True 
      elif event.type == pygame.KEYDOWN: 
       if event.key == pygame.K_UP and player.speed > MINSPEED: 
        player.speed -= 3 
       if event.key == pygame.K_DOWN and player.speed < MAXSPEED: 
        player.speed += 3 
       if event.key == pygame.K_LEFT: 
        player.angle_speed = -3 
       if event.key == pygame.K_RIGHT: 
        player.angle_speed = 3 
       if event.key == pygame.K_SPACE: 

        dest_x = math.sin(player.angle_speed) 
        dest_y = math.cos(player.angle_speed) 
        # Create the bullet based on where we are, and where we want to go. 
        bullet = Bullet(player.rect.x, player.rect.y, dest_x, dest_y) 

        # Add the bullet to the lists 
        all_sprites_list.add(bullet) 
        bullet_list.add(bullet) 
      elif event.type == pygame.KEYUP: 
       if event.key == pygame.K_LEFT: 
        player.angle_speed = 0 
       elif event.key == pygame.K_RIGHT: 
        player.angle_speed = 0 

     all_sprites_list.update() 
     player.rect.clamp_ip(screen_rect) 
     screen.fill((255, 255, 255)) 
     # screen.blit(player.image, player.rect) 
     all_sprites_list.draw(screen) 
     pygame.display.flip() 

if __name__ == '__main__': 
    main() 
    pygame.quit() 

答えて

1

角度は、playerスプライトのself.angle属性に格納されます。 angle_speedは回転だけの速度です。

弾丸の角度と速度を計算する必要はありません。プレイヤースプライトのangledirectionを渡すことができます。

import math 
import pygame 
from pygame.math import Vector2 


SCREEN_WIDTH = 800 
SCREEN_HEIGHT = 600 

BLACK = (0, 0, 0) 
WHITE = (255, 255, 255) 
RED = (255, 0, 0) 


class Player(pygame.sprite.Sprite): 

    def __init__(self, pos=(420, 420)): 
     super(Player, self).__init__() 
     self.image = pygame.Surface([20, 40], pygame.SRCALPHA) 
     self.image.fill(RED) 
     self.original_image = self.image 
     self.rect = self.image.get_rect(center=pos) 
     self.position = Vector2(pos) 
     # The vector points upwards. 
     self.direction = Vector2(0, -1) 
     self.speed = 0 
     self.angle_speed = 0 
     self.angle = 0 

    def update(self): 
     if self.angle_speed != 0: 
      # Rotate the direction vector and then the image 
      self.direction.rotate_ip(self.angle_speed) 
      self.angle += self.angle_speed 
      self.image = pygame.transform.rotate(self.original_image, -self.angle) 
      self.rect = self.image.get_rect(midtop=self.rect.midtop) 
     # Update the position vector and the rect. 
     self.position += self.direction * self.speed 
     self.rect.center = self.position 


class Bullet(pygame.sprite.Sprite): 
    """ This class represents the bullet. """ 

    def __init__(self, pos, direction, angle): 
     """Take the pos, direction and angle of the player.""" 
     super(Bullet, self).__init__() 
     self.image = pygame.Surface([4, 10], pygame.SRCALPHA) 
     self.image.fill(BLACK) 
     # Rotate the image by the player.angle (negative since y-axis is flipped). 
     self.image = pygame.transform.rotozoom(self.image, -angle, 1) 
     # Pass the center of the player as the center of the bullet.rect. 
     self.rect = self.image.get_rect(center=pos) 
     self.position = Vector2(pos) # The position vector. 
     self.velocity = direction * 11 # Multiply by desired speed. 

    def update(self): 
     """Move the bullet.""" 
     self.position += self.velocity # Update the position vector. 
     self.rect.center = self.position # And the rect. 

     if self.rect.x < 0 or self.rect.x > SCREEN_WIDTH or self.rect.y < 0 or self.rect.y > SCREEN_HEIGHT: 
      self.kill() 


def main(): 
    pygame.init() 
    pygame.key.set_repeat(500,30) 

    screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT]) 
    screen_rect = screen.get_rect() 

    all_sprites_list = pygame.sprite.Group() 
    bullet_group = pygame.sprite.Group() # "group" not "list". 

    player = Player() 
    all_sprites_list.add(player) 

    MAXSPEED = 15 
    MINSPEED = -5 

    clock = pygame.time.Clock() 

    done = False 
    while not done: 
     clock.tick(60) 

     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       done = True 
      elif event.type == pygame.KEYDOWN: 
       if event.key == pygame.K_UP and player.speed > MINSPEED: 
        player.speed += 3 
       if event.key == pygame.K_DOWN and player.speed < MAXSPEED: 
        player.speed -= 3 
       if event.key == pygame.K_LEFT: 
        player.angle_speed = -3 
       if event.key == pygame.K_RIGHT: 
        player.angle_speed = 3 
       if event.key == pygame.K_SPACE: 
        # Just pass the rect.center, direction vector and angle. 
        bullet = Bullet(
         player.rect.center, player.direction, player.angle) 
        all_sprites_list.add(bullet) 
        bullet_group.add(bullet) 
      elif event.type == pygame.KEYUP: 
       if event.key == pygame.K_LEFT: 
        player.angle_speed = 0 
       elif event.key == pygame.K_RIGHT: 
        player.angle_speed = 0 

     all_sprites_list.update() 
     player.rect.clamp_ip(screen_rect) 

     screen.fill(WHITE) 
     all_sprites_list.draw(screen) 
     pygame.display.flip() 

if __name__ == '__main__': 
    main() 
    pygame.quit() 
関連する問題