Creating a Cooldown for games in python

Question:

I want to create space invaders. I want to make it so you can not just shoot like crazy and there is a cooldown on how fast you can shoot.

I have this code:

class Laser(Turtle):
    def __init__(self):
        super().__init__()
        self.penup()
        self.lasers = []

    def shoot(self):
        new_laser = Turtle(shape="square")
        self.lasers.append(new_laser)
        new_laser.penup()
        new_laser.setheading(90)
        global PLAYER_X
        new_laser.goto(x=PLAYER_X, y=-260)
        new_laser.shapesize(stretch_wid=0.2, stretch_len=2)
        new_laser.color("white")

This is in a file and then this code in main.py

from player import Player, Laser
from turtle import *
import time

screen = Screen()
player = Player()
laser = Laser()

screen.setup(height=600, width=550, starty=-50)
screen.bgcolor("black")
screen.title("Space Invaders")
screen._root.resizable(False, False)
screen.tracer(0)

screen.listen()
screen.onkey(player.go_left, "Left")
screen.onkey(player.go_right, "Right")
screen.onkey(laser.shoot, "space")

while True:
    screen.update()
    time.sleep(0.02)

    for item in laser.lasers:
        item.forward(10)

I want to make it so I can add a cooldown for the shooting speed because if I put in time.sleep(1) it freezes the whole thing. Does anyone have any ideas? Thanks

Asked By: MIchael Dearing

||

Answers:

Using pygame’s tick system changes the colors of a screen every 2 seconds you can use this in your project for the shooting could down.

import random
import pygame

pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Hello World")
start_ticks = pygame.time.get_ticks()  # starter tick

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

    seconds = (pygame.time.get_ticks() - start_ticks)/1000  # convert millisecond to seconds
    if seconds > 2:  # if more than 2 seconds 
        screen.fill((random.randint(0,225), random.randint(0,225), random.randint(0,225)))
        start_ticks = pygame.time.get_ticks()  # reset tick
    pygame.display.update()

Example:

Example

Answered By: Flow

You should use time to control it.

At start you could set variable self.next_shoot = 0 and when you
shoot then check time.time() >= self.next_shoot and if it is time for shoot then create new laser and set self.next_shoot = time.time() + self.delay


Full working code (with other changes: ie. now you can keep pressed space to shoot).

import turtle  # PEP8 `import *` is not preferred
import time

class Player(turtle.Turtle):
    
    def __init__(self):
        self.x = 0
        self.y = -250
        
        self.speed = 0
        self.left = False
        self.right = False
        
        self.player = turtle.Turtle(shape="square")
        self.player.penup()
        self.player.setheading(90)
        self.player.color("white")
        self.player.goto(self.x, self.y)
        
    def go_left(self):
        self.left = True
        
    def go_right(self):
        self.right = True

    def stop_left(self):
        self.left = False
        
    def stop_right(self):
        self.right = False

    def move(self):
        self.speed = 0
        
        if self.left:
            self.speed -= 10
        if self.right:
            self.speed += 10
            
        self.x += self.speed
        
        if self.x < -250:
            self.x = -250
        if self.x > 250:
            self.x = 250
            
        self.player.goto(self.x, self.y)
        
class Laser(turtle.Turtle):

    def __init__(self, player):
        super().__init__()

        self.player = player # access player position (without using global variables)

        self.shooting = False
        
        self.penup()
        self.lasers = []
        self.next_shoot = 0  # value as start
        self.delay = 1       # 1 second 

    def start_press(self):
        self.shooting = True
        
    def stop_press(self):
        self.shooting = False
        
    def shoot(self):
        #print(self.next_shoot, time.time())
            
        if time.time() >= self.next_shoot:
            self.next_shoot = time.time() + self.delay
            
            new_laser = turtle.Turtle(shape="square")
            self.lasers.append(new_laser)
            
            new_laser.penup()
            new_laser.setheading(90)
            new_laser.goto(x=player.x, y=-260)
            new_laser.shapesize(stretch_wid=0.2, stretch_len=2)
            new_laser.color("white")

    def move(self):
        if self.shooting:
            self.shoot()
            
        for item in self.lasers:
            item.forward(10)
        
        
screen = turtle.Screen()
player = Player()
laser = Laser(player)

screen.setup(height=600, width=550, starty=-50)
screen.bgcolor("black")
screen.title("Space Invaders")
screen._root.resizable(False, False)
screen.tracer(0)

screen.listen()
screen.onkeypress(player.go_left, "Left")
screen.onkeypress(player.go_right, "Right")
screen.onkeyrelease(player.stop_left, "Left")
screen.onkeyrelease(player.stop_right, "Right")

screen.onkeypress(laser.start_press, "space")
screen.onkeyrelease(laser.stop_press, "space")

while True:
    screen.update()
    time.sleep(0.02)
    player.move()
    laser.move()
Answered By: furas
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.