如何在 pygame 中发射子弹?

How do I fire a bullet in pygame?

我的objective是做一个space入侵者类型的游戏,space船可以上下左右移动,向外星人发射子弹。

我还没有在代码中加入碰撞部分,因为我卡在了发射子弹的部分。

我已指定 spacebar 发射子弹,但我看不到任何子弹发射。 请帮帮我。

import pygame
import random

# for initialising pygame (req for every pygame app)
pygame.init()

# making the basic window (dimensions must be written inside a tuple )
screen = pygame.display.set_mode((500, 500))

# background
background = pygame.image.load('C:/Users/aryan/Downloads/background.jpg')

# load and set the logo
logo = pygame.image.load('C:/Users/aryan/Downloads/bp.png')  # directory of logo
pygame.display.set_icon(logo)
pygame.display.set_caption("space wars")  # program name

# define a variable to control the main loop
running = True

# player
playerimg = pygame.image.load('C:/Users/aryan/Downloads/spaceship.png')
playerX = 218  # x and y coordinates of image
playerY = 350
playerxchange = 0  # this will be the change in movement in x direction of our image
playerychange = 0  # this will be the change in movement in y direction of our image


def player(x, y):
    screen.blit(playerimg, (x, y))  # blit draws our image on the surface(basically the background)
    # syntax for blit(imagename, (xcoordinate,ycoordinate))


# enemy
enemyimg = pygame.image.load('C:/Users/aryan/Downloads/enemy.png')
enemyX = random.randint(0, 476)
enemyY = 20
enemyxchange = 0.2
enemyychange = 40

# game over
overimg = pygame.image.load('C:/Users/aryan/Downloads/gameover.png')

# bullet
bulletimg = pygame.image.load('C:/Users/aryan/Downloads/bullet.png')
bulletX = 0
bulletY = 350
bulletxchange = 0
bulletychange = 7
bullet_state = "ready"              # "ready" you cant see bullet on screen
                                    # "fire" you can see bullet firing

def enemy(x, y):
    screen.blit(enemyimg, (x, y))  # blit draws our image on the surface(basically the background)
    # syntax for blit(imagename, (xcoordinate,ycoordinate))


def firebullet(x, y):
    global bullet_state
    bullet_state = "ready"
    screen.blit(bulletimg, (x+12, y+6))


# main loop
while running:
    screen.fill((120, 120, 120))  # in order (r, g, b) . (0, 0, 0) is black (255, 0, 0) is red...
    screen.blit(background, (0, 0))
    # event handling, gets all event from the event queue
    for event in pygame.event.get():
        # only do something if the event is of type QUIT
        if event.type == pygame.QUIT:
            # change the value to False, to exit the main loop
            running = False

        # checking keystroke
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                playerxchange += 0.2  # change in movement will be 0.2 towards the right
            if event.key == pygame.K_LEFT:
                playerxchange -= 0.2  # change in movement will be 0.2 towards the right
            #if event.key == pygame.K_UP:
            #    playerychange -= 0.2
            #if event.key == pygame.K_DOWN:
            #   playerychange += 0.2
            if event.key == pygame.K_SPACE:
                bullet_state = "fire"
                firebullet(playerX, bulletY)
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: #or event.key == pygame.K_DOWN or event.key == pygame.K_UP:
                playerxchange = 0
                playerychange = 0

    playerY += playerychange
    playerX += playerxchange  # the value of playerx changes by +- 0.1 depending on keystroke

    if playerX <= -64:  # this teleports the spaceship from left end to right end
        playerX = 564
    elif playerX >= 564:  # this teleports spaceship from right end to left
        playerX = -64

    if playerY >= 436:  # this prevents spaceship from leaving vertically
        playerY = 436
    if playerY <= 0:
        playerY = 0

    # enemy movement
    enemyX += enemyxchange

    if enemyY >= 476:
        enemyY = 476
        enemyYchange = 0
        enemyXchange = 0

    if enemyX <= 0:
        enemyxchange = 0.1
        enemyY += enemyychange
    elif enemyX >= 465:
        enemyxchange = -0.1
        enemyY += enemyychange

    # bullet movement
    if bullet_state is "fire":
        firebullet(playerX, bulletY)
        bulletY -= bulletychange

    player(playerX, playerY)  # player method is called AFTER screen.fill otherwise the screen will fill after image has been blitted
    enemy(enemyX, enemyY)

    pygame.display.update()  # necessary for events to keep updating

另外,评论可能看起来很琐碎,但我是初学者。

您没有看到子弹发射,因为您在 firebullet 函数中只调用了一次 screen.blit(bulletimg, (x+12, y+6))。在此之后,一个新的循环开始,背景用 screen.blit(background, (0, 0)) 打印在它上面,并且不再调用代码来渲染你的子弹。您需要做的是将每个项目符号保存在内存中,并在每次循环迭代时调用 .blit(),以便它们全部正确打印。

这是一个基本的解决方案:

...
bullets = [] #Array to store the position of the bullets
...

def firebullet(x, y):
    global bullet_state
    bullet_state = "ready"
    bullets.append([x + 12, y + 6]) # Creating a new bullet

...

while running:
    ...

    if bullet_state is "fire":
        firebullet(playerX, bulletY)
        # bulletY -= bulletychange # No longer necessary, we'll do this right afterwards

    for bullet in bullets:
        screen.blit(bulletimg, (bullet[0], bullet[1])) # Print a bullet
        bullet[0] -= bulletxchange # Updates its position
        bullet[1] -= bulletychange
        if bullet[1] < 0:
            bullets.remove(bullet) # If the bullet goes offscreen, delete it from the array