While loop issue in pygame not pausing for event handler - python

I'm building a multiple choice quiz game in pygame however there is an issue with my while loop.
I successfully built the game in python without the GUI and all the logic works fine, however, when I try and add the GUI to the logic it doesn't work in the same way.
In my working logic game the continuous while loop is paused at every question due to me using the 'raw_input()' function and waits for the user to answer. When I do the GUI version my questions are read in successfully but it reads them all in at once and there is no time to answer.
I've tried adding time.sleep() after reading each question but this means that the program doesn't respond to event handlers. If the event handlers did work then this would be the perfect solution, giving users a certain amount of time to answer.
This example code below won't compile as I have left out many classes and methods but wanted to show this is where my issue lies. I read dictionary keys and values in and then try and match the user input with the index of the correct answer which is always answerMain[0] before getting shuffled.
Has anyone had a similar issue or know of a possible solution?
attemptMain = {'Q': 'Question Here', 'A': 'Answer1','B': 'Answer2','c': 'Answer3','D': 'Answer4', }
def normalQuestions(self, list):
for i in list:
questionMain = self.attemptMain.keys()[i - 1]
answersMain = (self.attemptMain.values()[i - 1])
correctAnswerMain = answersMain[0]
shuffle(answersMain)
answersMainIndex = (1 + answersMain.index(correctAnswerMain) )
self.layout.questionandAnswers(questionMain, answersMain[0], answersMain[1], answersMain[2], answersMain[3])
time.sleep(10)
x = self.layout.controls()
if (x == answersMainIndex):
print("this is the correct answer")
def controls(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
print("here" + str(1))
return '1'
elif event.key == pygame.K_2:
print("here" + str(2))
return '2'
elif event.key == pygame.K_3:
print("here" + str(3))
return '3'
elif event.key == pygame.K_4:
print("here" + str(4))
return '4'

Here's a quiz game example. I use the dt = clock.tick(fps) solution from the linked answer. You can just decrement a time variable by the dt and if it's below 0, switch to the next question. The user can input 1-4 which is then compared with the last element of the question tuple to check if the answer was correct.
import random
import pygame as pg
pg.init()
FONT = pg.font.Font(None, 34)
FONT_SMALL = pg.font.Font(None, 24)
BLUE = pg.Color('steelblue1')
def get_question(questions, question_index):
"""Create a surface with the question and the 4 answer choices."""
question, *answers, _ = questions[question_index]
# Blit the question and answers onto this transparent surface.
question_surface = pg.Surface((500, 150), pg.SRCALPHA)
question_surface.blit(FONT.render(str(question), True, BLUE), (0, 0))
for y, answer in enumerate(answers, 1):
txt = FONT_SMALL.render('{}: {}'.format(y, answer), True, BLUE)
question_surface.blit(txt, (0, 20*y+20))
return question_surface
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
dt = 0
time_to_answer = 5 # User has 5 seconds to answer.
time = time_to_answer
# A list of tuples that contain the question, 4 multiple choice
# answers and the last element is the correct answer.
questions = [
('Is it A, B, C or D?', 'A', 'B', 'C', 'D', '3'),
("What's 2+3?", '23', '5', '3', '2', '2'),
]
random.shuffle(questions)
question_index = 0
question_surface = get_question(questions, question_index)
correct = 0
incorrect = 0
game_over = False
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if not game_over:
user_input = event.unicode
correct_answer = questions[question_index][-1]
if user_input == correct_answer:
print('Correct')
correct += 1
time = time_to_answer
else:
incorrect += 1
time = time_to_answer
question_index += 1
if question_index >= len(questions):
game_over = True
else:
question_surface = get_question(questions, question_index)
else: # Restart.
game_over = False
correct = 0
incorrect = 0
random.shuffle(questions)
question_index = 0
question_surface = get_question(questions, question_index)
if not game_over:
time -= dt
# If the timer is below 0, switch to the next question.
if time <= 0:
question_index += 1
incorrect += 1
if question_index >= len(questions):
game_over = True
else:
time = time_to_answer
print('next')
question_surface = get_question(questions, question_index)
screen.fill((30, 30, 30))
if not game_over:
screen.blit(question_surface, (20, 50))
time_surface = FONT.render(str(round(time, 1)), True, BLUE)
screen.blit(time_surface, (20, 20))
correct_answer_surface = FONT_SMALL.render(
'Correct {}, incorrect {}'.format(correct, incorrect),
True, BLUE)
screen.blit(correct_answer_surface, (20, 250))
pg.display.flip()
dt = clock.tick(30) / 1000
if __name__ == '__main__':
main()
pg.quit()

Related

How do I find the distance from the goal node named target, when I have the below mentioned start node named seeker?

I am trying to find the distance from the start node named seeker to the goal node named target. I have already done most of the implementation of the algorithm and each of the nodes have a coordinate or box on a grid. My python code is lacking and I cannot find the coordinates and distance.
I have tried using the vector in the math class which gave me logical errors.
I also tried sending the actual objects hoping I could use those to reference the coordinates as I'd done in the code but got a TypeError: expected sequence object with len >= 0 or a single integer.
import numpy as np
import pygame as pg
import sys
from Settings import *
from Sprites import *
vec = pg.math.Vector2
class Game:
# initialise game window, etc
def __init__(self):
self.playing = True
pg.init()
self.mover = 'target'
self.screen = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption(Title)
self.clock = pg.time.Clock()
pg.key.set_repeat(500, 100)
self.load_data()
# pg.mouse.set_pos(0, 0)
self.walls = []
def load_data(self):
pass
# start a new game
def new(self):
self.all_sprites = pg.sprite.Group()
self.player = Player(self, 10, 10)
self.target = Target(self, 5, 5)
def load_data(self):
pass
# game loop
def run(self):
while self.playing:
self.dt = self.clock.tick(FPS) / 10000
self.events()
self.update()
self.draw()
def draw_grid(self):
for x in range(0, WIDTH, TILESIZE):
pg.draw.line(self.screen, LIGHTGREY, (x, 0), (x, HEIGHT))
for y in range(0, HEIGHT, TILESIZE):
pg.draw.line(self.screen, LIGHTGREY, (0, y), (WIDTH, y))
def quit(self):
pg.quit()
sys.exit()
def update(self):
# game loop update
self.all_sprites.update()
def events(self):
# game loop events
for event in pg.event.get():
if event.type == pg.QUIT:
self.quit()
if event.type == pg.MOUSEBUTTONDOWN:
mpos = vec(pg.mouse.get_pos()) // TILESIZE
if event.button == 1:
if mpos in g.walls:
g.walls.remove(mpos)
else:
g.walls.append(mpos)
if event.type == pg.KEYDOWN:
if event.key == pg.K_b:
# start breadth first
breadthfirst(self.target, self.player, self.walls, self.screen)
if event.key == pg.K_d:
# start depth first
depthfirst(self.target, self.player, self.walls, self.screen)
if event.key == pg.K_a:
# start A* search
astarsearch(self.target, self.player, self.walls, self.screen)
if event.key == pg.K_ESCAPE:
self.quit()
if event.key == pg.K_t:
self.mover = 'target'
if event.key == pg.K_s:
self.mover = 'seeker'
if self.mover == 'target':
if event.key == pg.K_LEFT:
self.target.move(dx=-1)
if event.key == pg.K_RIGHT:
self.target.move(dx=1)
if event.key == pg.K_UP:
self.target.move(dy=-1)
if event.key == pg.K_DOWN:
self.target.move(dy=1)
else:
if event.key == pg.K_LEFT:
self.player.move(dx=-1)
if event.key == pg.K_RIGHT:
self.player.move(dx=1)
if event.key == pg.K_UP:
self.player.move(dy=-1)
if event.key == pg.K_DOWN:
self.player.move(dy=1)
def draw(self):
# game loop - draw
self.screen.fill(BGCOLOR)
self.draw_grid()
self.all_sprites.draw(self.screen)
for wall in self.walls:
rect = pg.Rect(wall * TILESIZE, (TILESIZE, TILESIZE))
pg.draw.rect(self.screen, GREEN, rect)
# always do the flip after drawing everything
pg.display.flip()
def show_start_screen(self):
# game splash/start screen
pass
def show_go_screen(self):
# game over/continue screen
pass
def breadthfirst(target, seeker, walls, maingrid):
pass
def depthfirst(target, seeker, wall, maingrid):
pass
def astarsearch(target, seeker, wall, maingrid):
# array to store path locations
direct_graph = {}
# target location, returns a tuple
target = np.where(target.pos) # problem area
# seeker location, returns locations
start = np.where(seeker.pos) # problem area
# array of cost to travel so far
g_cost_array = np.zeros(seeker) # problem area
g_cost_array[start] = 0
total_g_cost = 0
# array for heuristic cost
h_cost_array = np.zeros(seeker) # problem area
# need to use a loop unfortunately...
t = 0
# possible steps
steps = ((-1, 0), (+1, 0), (0, -1), (0, +1))
for rows in h_cost_array:
s = 0
for cols in rows:
# check if it's a wall! if not - get the distance to target
loc = (t, s)
if (maingrid[loc]):
pass
else:
dist = abs(target[0] - s) + abs(target[1] - t)
h_cost_array[t, s] = dist
s += 1
t += 1
# total cost = h + g
f_cost_array = g_cost_array + h_cost_array
# closed and open sets
open_set = []
open_set.append(start)
closed_set = []
# actual path
path = []
path.append([tuple(target[0]), tuple(target[1])])
solution_found = False
while (open_set):
open_f_cost = []
# get the heuristic cost for the candidates in the open set
for vals in open_set:
open_f_cost.append(f_cost_array[vals])
# the shortest heuristic now
# the index of the candidate with the lowest distance/heuristic
best_dist_now = open_f_cost.index(min(open_f_cost))
# the current best position
best_pos_now = open_set[best_dist_now]
# if the destination is reached, finish!
if (tuple(best_pos_now) == target):
solution_found = True
break
else:
# remove the best guy from the open_set and add it to the closed set
closed_set.append(open_set.pop(best_dist_now))
# analyze the steps from the current best
for step in steps:
cand = (best_pos_now[0] + step[0], best_pos_now[1] + step[1])
# check if there's a wall or beyond the screen
if cand[0] < 0 or cand[1] < 0 or cand[0] > 39 or cand[1] > 23:
pass
# skip this candidate because it's a wall!
elif maingrid[cand]:
pass
# need an else clause here to weed out the off-screen locations
else:
# check if the candidate is in the closed set
already_seen = False
for dead in closed_set:
if np.all(dead == cand):
already_seen = True
break
# if the cell is in the closed set, skip it
if already_seen:
pass
else:
approx_g_score = g_cost_array[best_pos_now] + 1
# check if it's in the open list:
new = True
for others in open_set:
if np.all(others == cand):
new = False
break
# if a new cell or improved
if (new or approx_g_score < g_cost_array[cand]):
direct_graph[tuple(cand[0]), tuple(cand[1])] = (
tuple(best_pos_now[0]), tuple(best_pos_now[1]))
g_cost_array[cand] = approx_g_score
f_cost_array[cand] = g_cost_array[cand] + h_cost_array[cand]
if new:
open_set.append(cand)
if not solution_found:
return None
else:
recurrentPath(path, direct_graph, target, start)
return path
# takes a dictionary as input
def recurrentPath(final_path, raw_path, dest, origin):
a = raw_path[tuple(dest[0]), tuple(dest[1])]
final_path.append(a)
if (a != origin):
recurrentPath(final_path, raw_path, a, origin)
else:
return final_path
g = Game()
g.show_start_screen()
while True:
g.new()
g.run()
g.show_go_screen()
pg.QUIT
the expected results is to return the correct path to the target object from the seeker object after you press the keyboard character a. Note that with a left click, a wall can be constructed to add a hindrance to the seeking of the goal.

Threading issue with Pygame

I am developing a small game for learning purposes. I have created a simple animation for the title screen. Since there is also a function for full screen in the code, I wanted to create a title screen that:
Displayed the animation
Turned into full screen when the key was activated
Continued the animation at the point it was before activating full screen
In order to do this, I resorted to threading. However, this is the first time I tried to do any multi-threading, and I donĀ“t know what did I do wrong. The result is an undetermined error.
The code for the title screen is this:
try:
GameAnimation = threading.Thread(target=GameTitleAnimation, (Window, WindowDimensions, FontDictionary, CurrentVersion))
GameAnimation.start()
except:
print "There was an error while loading the screen. Press one key to exit the program."
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
Quit()
if event.type == pygame.KEYDOWN:
if event.key == K_ESCAPE:
Quit()
elif event.key == K_f:
Fullscreen(Window, WindowDimensions)
else:
return
The code for the animation is:
TitleWhite = [255, 255, 255, 0]
Black = BASE_BLACK
TitleLetters = ("R", "O", "G", "U", "E", " ", "H", "U", "N", "T", "E", "R")
Title = FontDictionary["TitleFont"][1].render("ROGUE HUNTER", False, TitleWhite)
TextWidth = Title.get_width()
TextHeight = Title.get_height()
TitleXPosition = (WindowDimensions[0] - TextWidth) / 2
TitleYPosition = (WindowDimensions[1] / 2) - (TextHeight / 2)
for letter in TitleLetters:
if letter == " ":
TitleXPosition += CurrentLetterWidth
else:
while TitleWhite[3] < 100:
TitleWhite[3] += 1
CurrentLetter = FontDictionary["TitleFont"][1].render(letter, False, TitleWhite)
CurrentLetter.set_alpha(TitleWhite[3])
Window.blit(CurrentLetter, (TitleXPosition, TitleYPosition))
time.sleep(0.008)
try:
pygame.display.update()
except Exception:
traceback.print_exception
TitleWhite[3] = 0
CurrentLetterWidth = CurrentLetter.get_width()
TitleXPosition += CurrentLetterWidth
FadeInSurface = pygame.Surface((WindowDimensions[0], WindowDimensions[1]))
FadeInSurface.fill(TitleWhite)
OpacityRounds = 1
while TitleWhite[3] < 100.0:
TitleWhite[3] = 1.1 ** OpacityRounds
FadeInSurface.set_alpha(TitleWhite[3])
Window.blit(FadeInSurface, (0, 0))
OpacityRounds += 1
pygame.display.update()
time.sleep (0.015)
time.sleep(0.7)
TitleXPosition = (WindowDimensions[0] - TextWidth) / 2
Version = FontDictionary["BodyFont"][1].render(CURRENT_VERSION, False, TitleWhite)
VersionHeight = Version.get_height()
VersionWidth = Version.get_width()
VersionXPosition = (WindowDimensions[0] - VersionWidth) / 2
VersionYPosition = TitleYPosition + TextHeight
while True:
pygame.draw.rect(Window, Black, (0, 0, WindowDimensions[0], WindowDimensions[1]), 0)
Window.blit(Title, (TitleXPosition, TitleYPosition))
Window.blit(Version, (VersionXPosition, VersionYPosition))
pygame.display.update()
I'd be very grateful if anyone could help me with this. I am going crazy.
There's no reason to use threading in your code. It will only make your code harder to read, harder to debug and error prone.
Usually you want to have some kind of state in your game that you use to determinate what should happen in a frame. You can find a class based example here.
Another way to handle this, which is a bit similar to your code, is to use coroutines.
Look at your animation code and instead of calling pygame.display.update(), give the control back to the main loop. The main loop will handle events, frame limiting and drawing, then give control back to the coroutine (which keeps track of it's own state).
Here's a simple hacky example:
import pygame
import pygame.freetype
pygame.init()
size = (640, 480)
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()
def game_state(surf):
rect = pygame.Rect(200, 200, 32, 32)
while True:
events = yield
pressed = pygame.key.get_pressed()
x = 1 if pressed[pygame.K_RIGHT] else -1 if pressed[pygame.K_LEFT] else 0
rect.move_ip(x*5, 0)
pygame.draw.rect(surf, pygame.Color('dodgerblue'), rect)
yield
def title_state(surf):
text = 'Awesome Game'
colors = [[255, 255, 255, 20] for letter in text]
font = pygame.freetype.SysFont(None, 22)
font.origin = True
while True:
for color in colors:
color[3] += 33
if color[3] > 255: color[3] = 0
x = 200
for (letter, c) in zip(text, colors):
bounds = font.get_rect(letter)
font.render_to(surf, (x, 100), letter, c)
x += bounds.width + 1
font.render_to(surf, (180, 150), 'press [space] to start', pygame.Color('grey'))
events = yield
yield
def main():
title = title_state(screen)
game = game_state(screen)
state = title
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
return
if e.type == pygame.KEYDOWN:
if e.key == pygame.K_ESCAPE:
return
if e.key == pygame.K_SPACE:
state = game if state == title else title
if e.key == pygame.K_f:
if screen.get_flags() & pygame.FULLSCREEN:
pygame.display.set_mode(size)
else:
pygame.display.set_mode(size, pygame.FULLSCREEN)
screen.fill(pygame.Color('grey12'))
next(state)
state.send(events)
pygame.display.update()
clock.tick(60)
if __name__ == '__main__':
main()
See how the main loop is clean and simple, and all of the game state is handled in the coroutines. The title screen part of the code does not care about fullscreen or not or how to switch to fullscreen, and the main loop does not care of what the title screen coroutine does. And we don't need threading.
In practice it's not that different from the class based example I linked above, but using coroutines makes it easy to implement the title screen animation.
Basically you have an endless loop, you mutate some state (like the color of a letter), and then say "now draw this!" by just calling yield.
This is a large chunk of code to debug.
I'm not familiar with pygame or python threading, but it seems to me that you need to include some debug lines to determine exactly where the error occurs during your game animation thread (if it's even occuring there at all).
Something like this pattern should help determine the source of the problem:
import logging
logging.info("start animation initialization")
...
logging.info("begin animation loop")
...
logging.info("end animation loop")
https://docs.python.org/2/howto/logging.html

Can I save the keyboard input in a list?

I have a code, where pressing a key reproduces a sound generated by the computer, my concern is, how can I store the keys in the order they were pressed in a list and print it?
Here is the code:
from array import array
import pygame
from pygame.mixer import Sound, get_init, pre_init
class Note(pygame.mixer.Sound):
def __init__(self, frequency, volume=.1):
self.frequency = frequency
Sound.__init__(self, self.build_samples())
self.set_volume(volume)
def build_samples(self):
period = int(round(get_init()[0] / self.frequency))
samples = array("h", [0] * period)
amplitude = 2 ** (abs(get_init()[1]) - 1) - 1
for time in range(period):
if time < period / 2:
samples[time] = amplitude
else:
samples[time] = -amplitude
return samples
pre_init(44100, -16, 1, 1024)
pygame.init()
screen = pygame.display.set_mode([640, 480], 0)
sounds = {}
keymap = {pygame.K_p: 880, pygame.K_r: 440}
while True:
key_pressed=[]
evt = pygame.event.wait()
if evt.type == pygame.QUIT:
break
elif evt.type == pygame.KEYDOWN:
if evt.key in keymap:
note = Note(keymap[evt.key])
note.play(-1)
sounds[evt.key] = note
key_pressed.append(note)
elif evt.type == pygame.KEYUP:
if evt.key in sounds:
sounds.pop(evt.key).stop()
Here is the problem !!!
while True:
key_pressed=[]
and here is the solution :
key_pressed_list = key_pressed
print(key_pressed_list)

Basic Running Cycle Not working [duplicate]

This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 6 years ago.
I'm still new to python, and have started with pygame. I'm making an endless runner game, but I've run into a problem with my run cycle. Here's my code:
import pygame
import sys
from pygame.locals import *
pygame.init()
clock = pygame.time.Clock()
clock2 = pygame.time.get_ticks()
screen = pygame.display.set_mode((640, 575))
bgx = 0
bgx2 = -800
scroll = 10
pose = 1
background = pygame.image.load("images/background2.png").convert_alpha();
player = pygame.image.load("images/character1.png").convert_alpha();
screen.blit(background, (0, 0))
def draw_screen(x):
screen.blit(background, (x, 0))
def draw_screen2(x2):
screen.blit(background, (x2, 0))
def draw_player(pose):
if pose == 1:
player = pygame.image.load("images/character1.png").convert_alpha();
screen.blit(player, (0, 0))
elif pose == 2:
player = pygame.image.load("images/character2.png").convert_alpha();
screen.blit(player, (0, 0))
elif pose == 3:
player = pygame.image.load("images/character3.png").convert_alpha();
screen.blit(player, (0, 0))
elif pose == 4:
player = pygame.image.load("images/character2.png").convert_alpha();
screen.blit(player, (0, 0))
def set_poses(pose):
if pose == 1:
pose = 2
if pose == 2:
pose = 3
if pose == 3:
pose = 4
if pose == 4:
pose = 1
while True: #Loop
clock2 = pygame.time.get_ticks()
#Quitting Function
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
quit()
clock.tick(50)
#Screen Scrolling
if bgx != 800:
bgx += scroll
else:
bgx = 0
if bgx2 != 0:
bgx2 += scroll
else:
bgx2 = -800
#Drawing Items
draw_screen2(bgx2)
draw_screen(bgx)
draw_player(pose)
if clock2%6 == 0:
set_poses(pose)
pygame.display.update()
So the screen is scrolling, and my character appears but he stays in his first position (Frame I guess.) at the part where it runs set_poses(pose) I tried having it also print something right before setting the pose, which it did, but its not setting the pose. I tried having it printing the pose, and it showed that the poses wasn't changing. So, yea, I've found my problem, but I can't for the life of me find a solution.
Rather than trying to pass by reference - which is what you're doing, try something like this:
def set_pose(pose):
if pose >= 4:
return 1
else:
return pose + 1
Then when you're trying to update the pose variable elsewhere:
pose = set_pose(pose)
Would you agree that you can call the arguments to your function whatever you want? For example, set_pose could look like this and do exactly the same thing:
def set_pose(foo):
if foo >= 4:
return 1
else:
return foo + 1
In other words, just because it's called pose inside the function doesn't mean it will refer to pose outside the function.

Python clicking game, updating score

import pygame
from pygame.locals import *
import random
import time
pygame.init()
randomNumber = random.randint(1,600)
randomNumber2 = random.randint(1,600)
x = 0
text = ""
squareCount = 0
beenHere = 0
# colours = (red, green, blue)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
WHITE = (255, 255, 255)
LBLUE = (0, 123, 255)
colour = RED
# Make a window appear
size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Square Chase | Score: 0")
screen.fill(LBLUE)
pygame.display.flip()
pygame.time.set_timer(USEREVENT + 1, 1500)
done = False
clock = pygame.time.Clock()
while done == False:
for event in pygame.event.get():
print(event)
if event.type == pygame.QUIT:
done = True
if event.type == USEREVENT + 1:
screen.fill(LBLUE)
randomNumber = random.randint(1,625)
randomNumber2 = random.randint(1,420)
mySquare = pygame.draw.rect(screen,colour,(randomNumber,randomNumber2,50,50),5)
squareCount = squareCount + 1
if squareCount == 50:
done == true
pygame.display.flip()
if event.type == pygame.MOUSEBUTTONDOWN:
y, z = pygame.mouse.get_pos()
is_inside = mySquare.collidepoint(y, z)
if is_inside and colour == GREEN:
x = x+1
text = str(x)
pygame.display.set_caption("Square Chase | Score " + text)
colour = RED
elif is_inside:
x = x+1
text = str(x)
pygame.display.set_caption("Square Chase | Score " + text)
colour = GREEN
clock.tick(20)
pygame.quit()
I am aiming to create a game in which the user has to click on a square for their score to increase. They get 50 chances to do this. If they click in the square within the 1.5 seconds the colour of the square changes.
The above code works apart from each time a new square is drawn the user could click on it say 5 times and their score will go up by 5. Any suggestions as to how to get the score to increase by just one? Thanks in advance.
Wish I could just use a comment but I have lack of reputation.
I didn't look through all your code, but your description makes it sound like a simple flag would be able to help you.
Once you recognize it has been clicked, increment the score AND set a boolean.
So in essence you will want something along the lines of
if clicked == false
score = score+1
clicked = true
You will want to clear the flag back to false once another block has appeared.
Wouldn't it be better, if a new square would show up after a successful keypress? That way the game would be more dynamic.
It's easy to change this. Instead of using user events that are called every 1.5 sec, sum the value returned by clock.tick() and when their sum will be greater than 1500 ms, create a new rectangle. This is a better approach, because you can call the method that creates a new square and reset the timer right after a successful keypress.
Some code to get you started:
def new_rect(screen,colour):
screen.fill(LBLUE)
randomNumber = random.randint(1,625)
randomNumber2 = random.randint(1,420)
mySquare = pygame.draw.rect(screen,colour,(randomNumber,randomNumber2,50,50),5)
return mySquare
done = False
clock = pygame.time.Clock()
timer_var = 0
while done == False:
if(timer_var > 1500):
timer_var = 0
mySquare = new_rect(screen,color)
squareCount = squareCount + 1
if squareCount == 50:
done == true
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
y, z = pygame.mouse.get_pos()
is_inside = mySquare.collidepoint(y, z)
if is_inside:
x = x+1
text = str(x)
pygame.display.set_caption("Square Chase | Score " + text)
timer_var = 0
new_rect(screen,colour)
squareCount = squareCount + 1
if squareCount == 50:
done == true
if colour == GREEN:
colour = RED
else:
colour = GREEN
timer_var += clock.tick(20)
pygame.quit()

Categories

Resources