首页 > 解决方案 > 我正在尝试使用 pygame 制作狂野西部游戏,但我无法让射击功能正常工作

问题描述

我一直在尝试在 Pygame 中制作一款狂野西部游戏,其中玩家与 NPC 决斗,但我无法让射击功能正常工作。我基本上试图保持简单,并且我有一系列功能可以让子弹穿过屏幕,但它们不起作用。这是代码:

import pygame, time
pygame.init()

display_width = 800
display_height = 600

win = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('The Old Wild West')

black = (0,0,0)
white = (255,255,255)

clock = pygame.time.Clock()
dead = False
avatar = pygame.image.load('cowboy.jfif')
avatar2 = pygame.image.load('enemy.jfif')
bullet = pygame.image.load('bullet.png')
bx2 = 330
bx3 = 440
bx4 = 550
bx = 220
by = 220
bspeed = 165
x =  50
ex = 550
ey = 225
y = 200
x_change = 0
speed = 0

def cowboy(x,y):
    win.blit(avatar, (x,y))
def enemy(ex, ey):
    win.blit(avatar2, (ex, ey))
def shootframe1():
    win.blit(bullet, (bx, by))
def antiframe1():
    pygame.draw.rect(win, (255, 255, 255), (bx, by, 50, 150))
def shootframe2():
    win.blit(bullet, (bx2, by))
def antiframe2():
    pygame.draw.rect(win, (255, 255, 255), (bx2, by, 50, 150))
def shootframe3():
    win.blit(bullet, (bx3, by))
def antiframe3():
    pygame.draw.rect(win, (255, 255, 255), (bx3, by, 50, 150))
def shootframe4():
    win.blit(bullet, (bx4, by))
def antiframe4():
    pygame.draw.rect(win, (255, 255, 255), (bx4, by, 50, 150))
  
while not dead:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            dead = True
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                x_change = -5
            elif event.key == pygame.K_RIGHT:
                x_change = 5
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                x_change = 0
        if event.type == pygame.K_SPACE:
            if event.key == pygame.K_SPACE:
                shootframe1()
                time.sleep(0.5)
                antiframe1()
                shootframe2()
                time.sleep(0.5)
                antiframe2()
                shootframe3()
                time.sleep(0.5)
                antiframe3()
                shootframe4()
                time.sleep(0.5)
                antiframe4()
        
   x += x_change

   win.fill(white)
   cowboy(x,y)
   enemy(ex, ey)

    
   pygame.display.update()
   clock.tick(60)

pygame.quit()
quit()

这是cowboy.jfif、enemy.jfif和bullet.png:

子弹.png

牛仔.jfif

敌人.jfif

请帮我解决这个困惑。

标签: pygame2d

解决方案


我彻底更新了您的代码,我尝试很好地评论所有内容,以便清楚发生了什么。

首先,在将子弹绘制到屏幕上之后,您将屏幕填充为白色,因此它从未出现过。

其次,空格键没有触发,因为您正在检查空格键是否是事件类型。所以我把它移到了event.type == pygame.KEYDOWN

第三,使用 time.sleep(0.5) 会使游戏窗口冻结和卡顿很多,所以我会避免这样做。

如果您对更改有任何疑问,请随时提问。

import pygame, time
pygame.init()

display_width = 800
display_height = 600

win = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('The Old Wild West')

black = (0,0,0)
white = (255,255,255)

clock = pygame.time.Clock()
dead = False
avatar = pygame.image.load('cowboy.jfif')
avatar2 = pygame.image.load('enemy.jfif')
bullet = pygame.image.load('bullet.png')
bx2 = 330
bx3 = 440
bx4 = 550
bx = 220
by = 220
bspeed = 165
x =  50
ex = 550
ey = 225
y = 200
x_change = 0
speed = 0

def cowboy(x,y):
    win.blit(avatar, (x,y))
def enemy(ex, ey):
    win.blit(avatar2, (ex, ey))

# A single shoot function that appends a new bullet to our bullet list below.
def shoot():
    bullet_list.append(Bullet(bx, by))

# A bullet class that holds information about a single bullet
class Bullet:
    def __init__(self, x, y):
        # Initializing variables for the bullet
        self.x = x
        self.y = y
        self.image = pygame.image.load('bullet.png')
        self.bullet_speed = 165

    # Moves the bullet accross the screen by updating the x variable after each draw()
    def _move_bullet(self):
        self.x += self.bullet_speed

    def draw(self):
        # Get the surface (window)
        surface = pygame.display.get_surface()
        # Blit the bullet to the screen
        surface.blit(self.image, (self.x, self.y))
        # Update its position with the function above
        self._move_bullet()

bullet_list = [] # Since the user can have multiple bullets firing, we need to keep track of them
while not dead:
    win.fill(white) #Move this to the top so you're filling the screen before drawing anything
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            dead = True
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                x_change = -5
            elif event.key == pygame.K_RIGHT:
                x_change = 5
            if event.key == pygame.K_SPACE: # Moved this up here
                shoot() # Spawn the bullet
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                x_change = 0

    x += x_change
    cowboy(x,y)
    enemy(ex, ey)

    # Draw each bullet onto the screen by iterating over the list
    for bullet in bullet_list:
        # If the bullet has exited the screen we remove it from the list so they are not kept in memory
        if bullet.x > display_width:
            bullet_list.remove(bullet)
        # Draw the bullet (called from the Class)
        bullet.draw()
    
    pygame.display.update()
    clock.tick(60)

pygame.quit()
quit()

推荐阅读