I want to know how to add a timer/cool-down to a specific key-button that is pressed. For example, the user is spamming the attack key (in my case p) and I want to add a cooldown to where the person cannot spam this button (in air and on ground). Here is the problem: https://drive.google.com/file/d/1XH-u-1qm2I0ftlCLPSsPMjTJjJGQdsUp/view?usp=sharing
As you can see in the video the person can spam the attack button indefinitely and removes the purpose of the game.
I have tried setting a sleep timer such as def sleeper(): if input() == "p": s(20) but I dont think that is how you do it. Other than that I dont know any other methods to try.
Link to my entire code: https://hastebin.com/zujanifisu.py
More specific code:
def movement(self, window):
pygame.time.delay(20)
if self.runcount >= 3:
self.runcount = 0
if self.running == True:
window.blit(run[self.runcount],(int(self.player_x),int(self.player_y)))
self.runcount +=1
self.hitbox_running = pygame.Rect(self.player_x+30,self.player_y+20,48,70)
pygame.draw.rect(window,(255,0,0),self.hitbox_running, 2)
if (keys[pygame.K_DOWN]) or ((keys[pygame.K_DOWN]) and keys[pygame.K_p]):
if self.player_y == 378:
self.running = False
if self.slidecount >= 4:
self.slidecount = 0
if self.sliding:
window.blit(slide[self.slidecount],(int(self.player_x),int(self.player_y)))
self.slidecount +=1
pygame.draw.rect(window,(255,0,0),self.hitbox_sliding, 2)
if event.type == pygame.KEYDOWN:
if (event.key == pygame.K_DOWN )and self.player_y < self.width:
self.running = False
self.jumping = False
self.fallspeed += 0.2
if self.fallingcount >= 1:
self.fallingcount = 0
if self.fall:
window.blit(falling[self.fallingcount], (int(self.player_x),int(self.player_y)))
self.hitbox_falling = pygame.Rect(self.player_x+30,self.player_y,35,80)
pygame.draw.rect(window,(255,0,0),self.hitbox_falling, 2)
self.fallingcount +=1
if keys[pygame.K_UP] and keys[pygame.K_p] :
self.fallspeed = 0.3
self.running = False
self.jumping = False
self.sliding = False
if self.attackcount >= 16:
self.attackcount = 0
if self.attacking:
window.blit(attack[self.attackcount],(int(self.player_x),int(self.player_y)))
self.attackcount += 1
self.hitbox_attacking = pygame.Rect(self.player_x+30,self.player_y+20,38,70)
self.hitbox_sword = pygame.Rect(self.player_x+72, self.player_y+20, 20, 50)
pygame.draw.rect(window,(255,0,0),self.hitbox_attacking, 2)
pygame.draw.rect(window,(255,0,0),self.hitbox_sword, 2)
if self.jumpingcount >= 20:
self.jumpingcount = 0
if self.jumping and self.player_y < self.width:
window.blit(jump[self.jumpingcount],(int(self.player_x),int(self.player_y)))
self.hitbox_jumping = pygame.Rect((self.player_x+20),(self.player_y+20),52,55)
pygame.draw.rect(window,(255,0,0),self.hitbox_jumping, 2)
self.jumpingcount +=1
self.fallspeed = 0.3
if keys[pygame.K_UP]:
self.fallspeed = 0.3
self.running = False
if self.jumpingcount >= 20:
self.jumpingcount = 0
if self.jumping and self.player_y < self.width:
window.blit(jump[self.jumpingcount],(int(self.player_x),int(self.player_y)))
self.hitbox_jumping = pygame.Rect((self.player_x+20),(self.player_y+20),52,55)
pygame.draw.rect(window,(255,0,0),self.hitbox_jumping, 2)
self.jumpingcount +=1
self.fallspeed = 0.3
if keys[pygame.K_p] and not keys[pygame.K_UP]:
self.running = False
self.jumping = False
self.sliding = False
if self.attackcount >= 16:
self.attackcount = 0
if self.attacking:
self.hitbox_attacking = pygame.Rect(self.player_x+30,self.player_y+20,38,70)
self.hitbox_sword = pygame.Rect(self.player_x+72, self.player_y+20, 20, 50)
window.blit(attack[self.attackcount],(int(self.player_x),int(self.player_y)))
self.attackcount += 1
pygame.draw.rect(window,(255,0,0),self.hitbox_attacking, 2)
pygame.draw.rect(window,(255,0,0),self.hitbox_sword, 2)
if keys[pygame.K_DOWN] and keys[pygame.K_UP]:
self.running = False
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
self.running = True
self.jumping = True
self.fallspeed = 0.3
if event.key == pygame.K_UP:
self.running=True
if event.key == pygame.K_p:
self.running = True
self.jumping = True
self.sliding = True
Most of the problem is with the keys[pygame.k_p]
I want to add a timer to the overall button p, so when pressed like 2-3 times it cannot be pressed for another 2-3 seconds.
When a key was pressed, then you've to store the time when the key is allowed to be "pressed" again.
Use Dictionary for that:
key_timeout = {}
Write a function in global scope which checks if a key is pressed and allowed to be pressed. The parameters to the function are the state of the keys (pygame.key.get_pressed()
), the key and the time out time in milliseconds:
def getPressed(keys, key, timeout):
If the key is not pressed the function returns False
:
if keys[key] == False:
return False
Use pygame.time.get_ticks()
to get the time in get the time in milliseconds:
current_time = pygame.time.get_ticks()
If a timeout time is stored in the dictionary and and the time is less than the time when the key is allowed to be pressed again, then the function returns False
:
if key in key_timeout and key_timeout[key] > current_time:
return Fase
Add the timeout time to the current time, this is the time when the key is allowed to be pressed again and store it to the dictionary.
key_timeout[key] = current_time + timeout
Full code of the function:
key_timeout = {}
def getPressed(keys, key, timeout):
global key_timeout
if keys[key] == False:
return False
current_time = pygame.time.get_ticks()
if key in key_timeout and key_timeout[key] > current_time:
return False
key_timeout[key] = current_time + timeout
return True
Instead of if keys[pygame.k_p]:
you can call:
if getPressed(keys, pygame.k_p, 2000): # 2000 milliseconds == 2 seconds
# [...]
If you ask for the state of a key (e.g. keys[pygame.k_p]
) multiple times in a function, then you've to store the result of getPressed()
to a variable and use the variable instead. e.g.:
key_p_pressed = getPressed(keys, pygame.k_p, 2000)
if (keys[pygame.K_DOWN]) or ((keys[pygame.K_DOWN]) and key_p_pressed ):
# [...]
if keys[pygame.K_UP] and key_p_pressed:
# [...]
if key_p_pressed and not keys[pygame.K_UP]:
# [...]