【问题标题】:Keyboard Event - Pygame键盘事件 - Pygame
【发布时间】:2014-05-03 16:39:41
【问题描述】:

有谁知道我怎么做才能让我的代码只有在按下空格键时才会发射子弹?现在任何键都可以让我的角色发射子弹,但如果可能的话我想改变它,这是我的代码:

import pygame, sys, random

pygame.init()

screen_width = 800
screen_height = 600
screen = pygame.display.set_mode([screen_width, screen_height])
all_sprites_list = pygame.sprite.Group()
block_list = pygame.sprite.Group()
bullet_list = pygame.sprite.Group()
BLACK    = (   0,   0,   0)
WHITE    = ( 255, 255, 255)
background = pygame.image.load('space.jpg')
pygame.display.set_caption("Alien Invasion!")
explosion = pygame.mixer.Sound('explosion.wav')
score = 0

class Block(pygame.sprite.Sprite):
    def __init__(self, color):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load("spaceship.png")
        self.rect = self.image.get_rect()

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        self.x=0
        self.y=0
        self.image = pygame.image.load("alien.png")
        self.rect = self.image.get_rect()

    def update(self):

        pos = pygame.mouse.get_pos()
        self.rect.x = pos[0]

    def render(self):

        if (self.currentImage==0):
            screen.blit(self.image, (self.x, self.y))

class Bullet(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("bullet.png")
        self.rect = self.image.get_rect()

    def update(self):

        self.rect.y -= 3

for i in range(30):
    block = Block(BLACK)
    block.rect.x = random.randrange(screen_width)
    block.rect.y = random.randrange(330)
    block_list.add(block)
    all_sprites_list.add(block)

player = Player()

all_sprites_list.add(player)

done = False

clock = pygame.time.Clock()

player.rect.y = 480

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

        elif event.type == pygame.KEYDOWN:
            bullet = Bullet()
            bullet.rect.x = player.rect.x
            bullet.rect.y = player.rect.y
            all_sprites_list.add(bullet)
            bullet_list.add(bullet)

    all_sprites_list.update()

    for bullet in bullet_list:

        block_hit_list = pygame.sprite.spritecollide(bullet, block_list, True)

        for block in block_hit_list:
            explosion.play()
            bullet_list.remove(bullet)
            all_sprites_list.remove(bullet)
            score += 10

        if bullet.rect.y < -10:
            bullet_list.remove(bullet)
            all_sprites_list.remove(bullet)

    font = pygame.font.Font(None, 36)
    text = font.render("Score: " + str(score), True, WHITE)
    textpos = text.get_rect(centerx=screen.get_width()/12)

    screen.blit(background, (0,0))

    screen.blit(text, textpos)

    all_sprites_list.draw(screen)

    pygame.display.update()

    clock.tick(80)

pygame.quit()

另外,如果可能的话,我想让它一旦按下退出键,游戏就会退出。为此,我有以下代码:

    if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):

但是由于某种原因它似乎无法正常工作:(我是 python 新手,所以任何帮助都将不胜感激!

【问题讨论】:

    标签: events python-3.x keyboard pygame


    【解决方案1】:

    对!所以首先要做的事情!

    要通过按空格键发射子弹,您需要添加以下内容:

    elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
        bullet = Bullet()
        bullet.rect.x = player.rect.x
        bullet.rect.y = player.rect.y
        all_sprites_list.add(bullet)
        bullet_list.add(bullet)    
    

    上述解决方案将通过按空格键生成子弹

    如果您想按空格键发射一颗子弹,那么您需要 创建一个k_space 变量,该变量将在上述事件中设置为True,并在循环结束时设置为False。

    因此,要执行上述操作,您必须更改一些内容:)

    k_space = False #---- Initialize the boolean for the space key here
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
    
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                k_space = True #----- Set it to true here
    
        if k_space: #---- create a bullet when the k_space variable is set to True
            bullet = Bullet()
            bullet.rect.x = player.rect.x
            bullet.rect.y = player.rect.y
            all_sprites_list.add(bullet)
            bullet_list.add(bullet)   
    
        k_space = False #------ Reset it here
    
        all_sprites_list.update()
    
        for bullet in bullet_list:
    
            block_hit_list = pygame.sprite.spritecollide(bullet, block_list, True)
    
            for block in block_hit_list:
                explosion.play()
                bullet_list.remove(bullet)
                all_sprites_list.remove(bullet)
                score += 10
    
            if bullet.rect.y < -10:
                bullet_list.remove(bullet)
                all_sprites_list.remove(bullet)
    
        font = pygame.font.Font(None, 36)
        text = font.render("Score: " + str(score), True, WHITE)
        textpos = text.get_rect(centerx=screen.get_width()/12)
    
        screen.blit(background, (0,0))
    
        screen.blit(text, textpos)
    
        all_sprites_list.draw(screen)
    
        pygame.display.update()
    
        clock.tick(80)
    

    更改上面的代码只会让每按空格键生成one 子弹! 如果您想通过按空格键来生成多个项目符号,请坚持我建议的第一个更改:)

    最后,如果您希望通过按退出键来关闭程序,那么您只需更改循环中的第一个事件:

    取而代之的是:

    if event.type == pygame.QUIT:
        done = True
    

    您可以将其更改为:

    if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
        done = True
    

    这应该会安全地退出你的程序:)

    希望有所帮助!

    干杯,

    亚历克斯

    (编辑)

    好吧!只需拆分两个退出事件,它应该可以顺利运行:)

        #code above
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            pygame.quit()
            sys.exit()
        #code below
    

    最后 :) 如果你想让子弹正好从飞船的中间产生, 只需在 k_space 检查中添加此代码:

        if k_space:
            bullet = Bullet()
            bullet.rect.x = player.rect.center[0] - bullet.rect.width/2
            bullet.rect.y = player.rect.center[1] - bullet.rect.height/2
            all_sprites_list.add(bullet)
            bullet_list.add(bullet)
    

    呸!希望对伴侣有所帮助:)

    干杯!

    【讨论】:

    • 哇!非常感谢您的回复@Alex,我应用了您的所有更改,并且按照您所说的那样工作,但是一件愚蠢的事情,我忘了提到我希望使用退出键和单击顶部的 x 来关闭窗口右上角?这可能吗?另外,目前子弹没有从我的玩家精灵的中心位置退出并从左侧射击,有什么办法可以改变这个吗?如果没有,非常感谢,我真诚地感谢您的反馈:)
    • 嗯,我按照您更新的建议进行操作,但是现在运行它时,会在短时间内弹出一个黑色窗口,然后立即关闭? :( 知道为什么会发生这种情况吗?我可能犯了一个错误,所以这是我的更新代码:pastebin.com/wfc6KtX8 再次非常感谢您的回复@Alex!
    • 使用k_space 标志不会改变任何东西。在 for 循环内或之后创建 Bullet 实例并不重要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 2018-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多