I am trying to make an aim game where a target pops up and once the player clicks on it, the target vanishes and a new one appears in a random location, I want it so that there is a 10 second timer but it keeps going back to 10 each time a target is "hit"
import pygame, random as r, time
FPS = 60
WIDTH = 900
HEIGHT = 500
WHITE = 255,255,255
BG = 26,26,26
RANGEXMIN = 20
RANGEXMAX = 840
RANGEYMIN = 20
RANGEYMAX = 440
window = pygame.display.set_mode((WIDTH, HEIGHT))
tick = pygame.USEREVENT
pygame.time.set_timer(tick,1000)
pygame.font.init()
FONT = pygame.font.Font('slkscr.ttf', 50)
def aim_train():
def new_target(countdown,text):
clock = pygame.time.Clock()
x = r.randint(RANGEXMIN, RANGEXMAX)
y = r.randint(RANGEYMIN, RANGEYMAX)
hit = False
while not hit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.USEREVENT:
if event.type == tick:
countdown= countdown - 1
text = str(countdown)
clock.tick(FPS)
window.fill(BG)
timer = FONT.render(text, False, WHITE)
window.blit(timer, (435, 20))
pygame.mouse.set_visible(False)
pos = pygame.mouse.get_pos()
pos_x = pos[0]
pos_y = pos[1]
target = pygame.draw.rect(window, WHITE, (x,y,50,50))
cursor_outline = pygame.draw.circle(window, BG, (pos_x,pos_y), 11)
cursor = pygame.draw.circle(window, WHITE,(pos_x,pos_y) ,10)
hit = (pygame.mouse.get_pressed()[0] and target.colliderect(cursor_outline))
pygame.display.update()
run = True
countdown = 10
text = str(countdown)
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill(BG)
pygame.mouse.set_visible(False)
new_target(countdown,text)
pygame.quit()
aim_train()
The variable "counter" somehow gets reset back to 10 after ever successful hit on a target
The problem is that you use a seperate function,
new_target
, for each target.The
countdown
variable is defined inside the scope of the functionaim_train
. Because thenew_target
function is defined inside theaim_train
function, it is a nested function and it can use all the variables that are defined insideaim_train
. However, thenew_target
function still has its own scope. It can make changes to any variables defined insideaim_train
, but those changes remain in its own scope. When a call ofnew_target
is ended, its scope is discarded and all changes to the variables ofaim_target
are undone. This causes thecountdown
variable to be reset every in new call ofnew_target
and thus every time a new target is created.You might also have noticed that you can't close your window. The window doesn't react to clicking the red cross. This is because the same applies to the
run
variable. When you click the red cross, therun
variable is set toTrue
insidenew_target
, but not in the scope ofaim_train
. As such, the main loop inaim_train
is not quitted and the program continues.As a solution to this problem, I would recommend to include all the code of
new_target
into theaim_train
function. Then you only have one function, which makes that all changes to variables are in the same scope and no changes are discarded:Apart from fixing the problem, I have also restructured your code a bit and did the following changes:
I have changed:
into:
Outside of the
aim_train
function, you have stated thattick
andpygame.USEREVENT
are equal. As such, it is useless to compare to them two times, because if the first check is true, then the second one will certainly be.I've placed
pygame.mouse.set_visible(False)
outside of the main loop.Calling the function sets the mouse invisible untill another call changes sets the mouse back to visible. As such, it is useless to call it multiple times in the loop.