Oscar
Oscar

Reputation: 107

Keyboard Event - Pygame

Does anyone know how I can make it so my code only fires a bullet if the space bar is pressed? Right now any key makes my character shoot a bullet but I want to change it if possible, heres my code so far:

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()

Also, if possible, I want to make it so that once the escape key is pressed, the game exits. For this I have this code:

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

However it doesnt seem to work properly for some reason :( Im new to python so any help would be appreciated!

Upvotes: 1

Views: 3426

Answers (1)

Alex Koukoulas
Alex Koukoulas

Reputation: 996

Right! So first things first!

To fire bullets by pressing the space bar you would need to add this:

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)    

The above solution will spawn bullets by pressing the space key

If you would like to fire a single bullet by pressing the space key then you would need to create a k_space variable that would be set to True on the above event and would be set to False at the end of the loop.

So to do the above you would have to change some stuff :)

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)

Changing the above code would make only one bullet spawn per space bar press! If you would like multiple bullets to spawn by pressing the space bar just stick to the first change I proposed :)

Finally if you want the program to close by pressing the escape key then you would just have to change the first event in your loop:

Instead of that:

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

You could just change it to:

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

And that should exit your program safely:)

Hope that helped!

Cheers,

Alex

(EDIT)

Allright! just split the two quit events and it should work smoothly :)

    #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

Lastly :) if you want the bullets to spawn exactly from the middle of the spaceship, just add this code in the k_space check:

    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)

Phew! Hope that helped mate:)

Cheers!

Upvotes: 4

Related Questions