0

I'm new to programming and this is the first real game I've made/making. Basically the game has you as a player shooting "bullets" at the enemy. With some objects moving around in the middle to try and stop all your bullets getting through.

I felt as though the speed at which the player could fire the bullet was too fast. So I did some research and found something that would help. The time.sleep(sec). When I used it though the whole game would stop and wait for the time delay to be over.

I used the time.sleep(sec) in main program loop when the player presses down the mouse button to fire a bullet. This in turn affects the whole game by making all of it to delay for 5 seconds.

So how would I have it wait without affecting the whole game?

Here is my game code:

import pygame
import random
import time

enemy_speed = 5
running = 1




# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)

# --- Classes
class Enemy(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("enemy.png").convert()
        self.rect = self.image.get_rect()
        self.image.set_colorkey(WHITE)
    def update(self):
        self.rect.x += 7
        if self.rect.x >= 610:
            self.rect.x = random.randrange(50,610)

class Hand(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("hand.png").convert()
        self.rect = self.image.get_rect()
        self.image.set_colorkey(WHITE)
    def update(self):
        self.rect.y = 300
        self.rect.x += 5
        if self.rect.x >= 610:
            self.rect.x = random.randrange(50,610)

class Hand2(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("hand2.png").convert()
        self.rect = self.image.get_rect()
        self.image.set_colorkey(WHITE)
    def update (self):
        self.rect.y = 100
        self.rect.x -= 5
        if self.rect.x <= 90:
            self.rect.x = random.randrange(50,610)
class Hand3(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("hand3.png").convert()
        self.rect = self.image.get_rect()
        self.image.set_colorkey(WHITE)
    def update (self):
        self.rect.y = 200
        self.rect.x += 3
        if self.rect.x >= 610:
            self.rect.x = random.randrange(50,610)

class Hand4(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("hand4.png").convert()
        self.rect = self.image.get_rect()
        self.image.set_colorkey(WHITE)
    def update (self):
        self.rect.y = 50
        self.rect.x += 3
        if self.rect.x >= 610:
            self.rect.x = random.randrange(50,610)


class Hand5(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("hand5.png").convert()
        self.rect = self.image.get_rect()
        self.image.set_colorkey(WHITE)
    def update (self):
        self.rect.y = 350
        self.rect.x -= 3
        if self.rect.x >= 610:
            self.rect.x = random.randrange(50,610)   




class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("player.png").convert()
        self.rect = self.image.get_rect()
        self.image.set_colorkey(WHITE)
    def update(self):
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                self.rect.x -= 4
            if event.key == pygame.K_RIGHT:
                self.rect.x += 4
            if self.rect.x <= 50:
                self.rect.x = 60
            if self.rect.x >= 610:
                self.rect.x = 600

class Pellet(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface([4,10])
        self.image.fill(RED)
        self.rect = self.image.get_rect()
    def update(self):
        speed_p = -3
        self.rect.y -= speed_p



class Bullet(pygame.sprite.Sprite):
    """ This class represents the bullet . """
    def __init__(self):
        # Call the parent class (Sprite) constructor
        super().__init__()

        self.image = pygame.Surface([4, 10])
        self.image.fill(BLUE)

        self.rect = self.image.get_rect()

    def update(self):
        """ Move the bullet. """
        speed_b = 3
        self.rect.y -= speed_b


# --- Create the window

# Initialize Pygame
pygame.init()

# Set the height and width of the screen
screen_width = 700
screen_height = 400
screen = pygame.display.set_mode([screen_width, screen_height])
pygame.display.set_caption("Cannon Battle")



all_sprites_list = pygame.sprite.Group()
enemy_list = pygame.sprite.Group()
player_list = pygame.sprite.Group()
hand_list = pygame.sprite.Group()
hand2_list = pygame.sprite.Group()
hand3_list = pygame.sprite.Group()
hand4_list = pygame.sprite.Group()
hand5_list = pygame.sprite.Group()


bullet_list = pygame.sprite.Group()
pellet_list = pygame.sprite.Group()
enemy = Enemy()
enemy_list.add(enemy)
all_sprites_list.add(enemy_list)

hand = Hand()
hand_list.add(hand)
all_sprites_list.add(hand_list)

hand2 = Hand2()
hand2_list.add(hand2)
all_sprites_list.add(hand2)

hand3 = Hand3()
hand3_list.add(hand3)
all_sprites_list.add(hand3)

hand4 = Hand4()
hand4_list.add(hand4)
all_sprites_list.add(hand4)

hand5 = Hand5()
hand5_list.add(hand5)
all_sprites_list.add(hand5)









player = Player()
player_list.add(player)
all_sprites_list.add(player_list)





done = False

clock = pygame.time.Clock()


player.rect.y = 370
behind = pygame.image.load("grassland.png").convert()

# -------- Main Program Loop 
while not done:
    screen.blit(behind, [0,0])
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        elif event.type == pygame.MOUSEBUTTONDOWN:
            bullet = Bullet()
            bullet.rect.x = player.rect.x
            bullet.rect.y = player.rect.y
            all_sprites_list.add(bullet)
            bullet_list.add(bullet)
            time.sleep(5)
        elif event.type == pygame.MOUSEBUTTONUP:
            pellet = Pellet()
            pellet.rect.x = enemy.rect.x
            pellet.rect.y = enemy.rect.y
            all_sprites_list.add(pellet)
            pellet_list.add(pellet)






    # --- Game logic

    # Call the update() method on all the sprites
    all_sprites_list.update()

    for pellet in pellet_list:
        player_hit_list = pygame.sprite.spritecollide(pellet,player_list,True)
        if pellet.rect.y >= 510:
            pellet_list.remove(pellet)
            all_sprites_list.remove(pellet)
        for player in player_hit_list:
            done = True
            print("You Lost!")
            print("But thanks for playing!")
            print("Made by Oankar Studios")

    for bullet in bullet_list:
        enemy_hit_list = pygame.sprite.spritecollide(bullet,enemy_list,True)
        if bullet.rect.y <= -10:
            bullet_list.remove(bullet)
            all_sprites_list.remove(bullet)
        if bullet.rect.x == hand.rect.x:
            bullet_list.remove(bullet)
            all_sprites_list.remove(bullet)
        if bullet.rect.x == hand2.rect.x:
            bullet_list.remove(bullet)
            all_sprites_list.remove(bullet)
        if bullet.rect.x == hand3.rect.x:
            bullet_list.remove(bullet)
            all_sprites_list.remove(bullet)
        if bullet.rect.x == hand4.rect.x:
            bullet_list.remove(bullet)
            all_sprites_list.remove(bullet)
        if bullet.rect.x == hand5.rect.x:
            bullet_list.remove(bullet)
            all_sprites_list.remove(bullet)
        for enemy in enemy_hit_list:
            done = True
            print("You Won!")
            print("Made by Oankar Studios")




    # Clear the screen


    # Draw all the spites
    all_sprites_list.draw(screen)



    # Go ahead and update the screen with what we've drawn.
    pygame.display.flip()

    # --- Limit to 20 frames per second
    clock.tick(60)




pygame.quit()

Here is where I use the time.sleep(sec), it is in the main program loop:

elif event.type == pygame.MOUSEBUTTONDOWN:
    bullet = Bullet()
    bullet.rect.x = player.rect.x
    bullet.rect.y = player.rect.y
    all_sprites_list.add(bullet)
    bullet_list.add(bullet)
    time.sleep(5)
0z00
  • 3
  • 1

3 Answers3

0

You can store the time of the last shot bullet, and ignore all presses until 5 seconds pass. So, at the top

last_bullet_shot_time = None

Then

elif event.type == pygame.MOUSEBUTTONDOWN:
    if last_bullet_shot_time is None or 
        time.now() - last_bullet_shot_time > datetime.timedelta(seconds = 5):

        bullet = Bullet()
        bullet.rect.x = player.rect.x
        bullet.rect.y = player.rect.y
        all_sprites_list.add(bullet)
        bullet_list.add(bullet)
        last_bullet_shot_time = time.now()
maniexx
  • 625
  • 1
  • 12
  • 28
0

As you already found out time.sleep() halts the whole program(or thread to be exact) which usually isn't what you want. One possible solution is to compare the the times as @maniexx mentioned.

As you are using pygame I'd recommend using pygame.time.get_ticks() in basically the same way, as described in this answer.

Community
  • 1
  • 1
MoRoBe
  • 119
  • 2
  • 11
0

You can use pygame's ability to generate events on the basis of a timer along with a unique user-defined event to have it create an notification event after the desired amount of time has passed. Here's the changes you would need:

# globals
TIMEOUT_EXPIRED = pygame.USEREVENT+1
shooting_allowed = True

Then in the body of the game:

# in the event processing loop
elif event.type == pygame.MOUSEBUTTONDOWN:
    if shooting_allowed:
        bullet = Bullet()
        bullet.rect.x = player.rect.x
        bullet.rect.y = player.rect.y
        all_sprites_list.add(bullet)
        bullet_list.add(bullet)
        # disable shooting for 5 seconds
        shooting_allowed = False
        pygame.time.set_timer(TIMEOUT_EXPIRED, 5000)
elif event.type == TIMEOUT_EXPIRED:
    # re-enable shooting
    shooting_allowed = True
    pygame.time.set_timer(TIMEOUT_EXPIRED, 0)  # stop generation of event
martineau
  • 119,623
  • 25
  • 170
  • 301