Pygame-如何向玩家精灵方向射击?

时间:2017-10-17 17:24:57

标签: python rotation pygame

我正在制作一个小行星克隆,我无法确定在哪里存储玩家精灵的移动角度以及如何让子弹访问(如果这有意义)。现在,我认为我的船的旋转存储在angle_speed变量中,我用它来生成子弹的dest_x和dest_y(目标x和y)坐标。然而子弹继续射击(0,0)。有人可以帮忙吗?

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 个答案:

答案 0 :(得分:1)

角度存储在player精灵的angle_speed属性中。 angle只是它旋转的速度。

没有必要计算子弹的角度和速度,因为你可以传递玩家精灵的directionimport 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()

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.muscleshop\.mx [NC]
RewriteRule ^(.*)$ https://muscleshop.mx/.(.*) [L,R=301]