How create a leaderboard in python - python

I have created a memory matching game where the player has to match up 15 similar pairs and they are timed. Once all pairs have been matched their end score is displayed in a final scree which says "Your final time was ...". I have also created a Main menu screen where the player has to login with a username and password. I want to add a leaderboard system to this game where the players name and final score is displayed in a table.
Here is the code for my Main menu w/o the login bit:
import pygame, sys, random
from GAME import *
from Time_Trial import *
##from Button import *
#initialises pygame
pygame.init()
#set screen width and height
SCREEN = pygame.display.set_mode((700, 610))
pygame.display.set_caption("Memory Game") # Add window title
orange = (255,97,3)
def get_font(size): # defines desired font and size
return pygame.font.Font("freesansbold.ttf", size)
class Button():
def __init__(self, image, pos, text_input, font, base_color, hovering_color):
self.image = image
self.x_pos = pos[0]
self.y_pos = pos[1]
self.font = font
self.base_color, self.hovering_color = base_color, hovering_color
self.text_input = text_input
self.text = self.font.render(self.text_input, True, self.base_color)
if self.image is None:
self.image = self.text
self.rect = self.image.get_rect(center=(self.x_pos, self.y_pos))
self.text_rect = self.text.get_rect(center=(self.x_pos, self.y_pos))
def update(self, screen):
if self.image is not None:
screen.blit(self.image, self.rect)
screen.blit(self.text, self.text_rect)
def checkForInput(self, position):
if position[0] in range(self.rect.left, self.rect.right) and position[1] in range(self.rect.top, self.rect.bottom):
return True
return False
def changeColor(self, position):
if position[0] in range(self.rect.left, self.rect.right) and position[1] in range(self.rect.top, self.rect.bottom):
self.text = self.font.render(self.text_input, True, self.hovering_color)
else:
self.text = self.font.render(self.text_input, True, self.base_color)
def play():
while True:
PLAY_MOUSE_POS = pygame.mouse.get_pos()
#Fill the next screen turquoise when Play is clicked
SCREEN.fill("turquoise")
GAME()
#When clicked play button, the next screen will display this
#Creates the exit button in next screen
PLAY_EXIT = Button(image=None, pos=(580, 560),
text_input="EXIT", font=get_font(75), base_color="White", hovering_color="orange")
#Exit button changes colour when mouse hovers over button
PLAY_EXIT.changeColor(PLAY_MOUSE_POS)
#Updates screen when the exit button is clicked
PLAY_EXIT.update(SCREEN)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if PLAY_EXIT.checkForInput(PLAY_MOUSE_POS): # if exit button in play screen is clicked then return back to menu
main_menu()
pygame.display.update()
def time_trial():
while True:
TIME_MOUSE_POS = pygame.mouse.get_pos()
#Fill the next screen turquoise when TIME TRIAL is clicked
SCREEN.fill("turquoise")
Time_Trial()
#Creates the exit button in next screen
TIME_EXIT = Button(image=None, pos=(580, 560),
text_input="EXIT", font=get_font(75), base_color="black", hovering_color="orange")
#Exit button changes colour when mouse hovers over button
TIME_EXIT.changeColor(TIME_MOUSE_POS)
#Updates screen when the exit button is clicked
TIME_EXIT.update(SCREEN)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if TIME_EXIT.checkForInput(TIME_MOUSE_POS): # if exit button in play screen is clicked then return back to menu
main_menu()
pygame.display.update()
def leaderboard():
while True:
leaderboard_MOUSE_POS = pygame.mouse.get_pos()
#Fill the next screen turquoise when leaderboard is clicked
SCREEN.fill("#008000")
#Text inside the leaderboard screen
leaderboard_TEXT = get_font(15).render("This is the leaderboard screen.", True, "Black")
#leaderboard button
leaderboard_RECT = leaderboard_TEXT.get_rect(center=(310, 220))
SCREEN.blit(leaderboard_TEXT, leaderboard_RECT)
#Exit button inside the leaderboard screen
leaderboard_EXIT = Button(image=None, pos=(580, 560),
text_input="EXIT", font=get_font(75), base_color="Black", hovering_color="orange")
#Exit button changes colour when mouse hovers over button
leaderboard_EXIT.changeColor(leaderboard_MOUSE_POS)
#Updates screen when the exit button is clicked
leaderboard_EXIT.update(SCREEN)
for event in pygame.event.get():
if event.type == pygame.QUIT: # if user quits the window then the game ends
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if leaderboard_EXIT.checkForInput(leaderboard_MOUSE_POS): # if exit in leaderboard is clicked, return back to main menu
main_menu()
pygame.display.update()
def main_menu():
while True:
#sets desired colour for the main menu screen
SCREEN.fill('#008000')
MENU_MOUSE_POS = pygame.mouse.get_pos()
#Adds the title Main menu
MENU_TEXT = get_font(50).render("MAIN MENU", True, orange)
MENU_RECT = MENU_TEXT.get_rect(center=(330, 40))
#creates the Play button in main menu screen
PLAY_BUTTON = Button(image=pygame.image.load("assets/Play Rect.png"), pos=(330, 145),
text_input="PLAY", font=get_font(60), base_color="#d7fcd4", hovering_color="orange")
###creates time trial button in the main menu screen
TIME_TRIAL_BUTTON = Button(image=pygame.image.load("assets/Time Rect.png"), pos=(330, 275),
text_input="Time Trial", font=get_font(60), base_color="#d7fcd4", hovering_color="orange")
#creates the leaderboard button in main menu screen
leaderboard_BUTTON = Button(image=pygame.image.load("assets/Options Rect.png"), pos=(370, 400),
text_input="leaderboard", font=get_font(50), base_color="#d7fcd4", hovering_color="orange")
#creates the quit button in main menu screen
QUIT_BUTTON = Button(image=pygame.image.load("assets/Quit Rect.png"), pos=(330, 530),
text_input="QUIT", font=get_font(60), base_color="#d7fcd4", hovering_color="orange")
SCREEN.blit(MENU_TEXT, MENU_RECT)
for button in [PLAY_BUTTON, leaderboard_BUTTON, TIME_TRIAL_BUTTON, QUIT_BUTTON]:
button.changeColor(MENU_MOUSE_POS)
button.update(SCREEN)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if PLAY_BUTTON.checkForInput(MENU_MOUSE_POS): # If the play button is clicked then display the Play screen
play()
if TIME_TRIAL_BUTTON.checkForInput(MENU_MOUSE_POS): #If the leaderboard button is clicked then display the leaderboard screen
time_trial()
if leaderboard_BUTTON.checkForInput(MENU_MOUSE_POS): #If the leaderboard button is clicked then display the leaderboard screen
leaderboard()
if QUIT_BUTTON.checkForInput(MENU_MOUSE_POS): # If Quit button in main menu is clicked then close the program
pygame.quit()
sys.exit()
pygame.display.update()
main_menu()
Here is the code for my Game:
# build a guessing game!
import pygame, random, sys
global options_list, spaces, used, new_board, first_guess, second_guess, first_guess_num, second_guess_num, score, matches, game_over, rows, cols, correct, time
pygame.init()
# game variables and constants
screen_width = 600
screen_height = 600
white = (255, 255, 255)
black = (0, 0, 0)
orange = (255,97,3)
turquoise = (0, 206, 209)
green = (0, 255, 0)
fps = 60
timer = pygame.time.Clock()
rows = 5
cols = 6
correct = [[0, 0, 0, 0, 0, 0,],
[0, 0, 0, 0, 0, 0,],
[0, 0, 0, 0, 0, 0,],
[0, 0, 0, 0, 0, 0,],
[0, 0, 0, 0, 0, 0]]
options_list = []
spaces = []
used = []
new_board = True
first_guess = False
second_guess = False
#Guess is assigned an index value. Checks what number is clicked
first_guess_num = 0
second_guess_num = 0
score = 0
matches = 0
game_over = False
cards_left_covered = 0
#timer start time
start_time = pygame.time.get_ticks()
time = 0
# create screen
screen = pygame.display.set_mode([screen_width, screen_height])
pygame.display.set_caption('Memory Game!')
#sets fonts
large_font = pygame.font.Font('freesansbold.ttf', 56)
small_font = pygame.font.Font('freesansbold.ttf', 26)
def generate_board():
global options_list, spaces, used
for item in range(rows * cols // 2):
options_list.append(item)
# goes through list of options between 1-24. Guarantees that only 2 cards can be selected
for item in range(rows * cols):
card = options_list[random.randint(0, len(options_list) - 1)]
spaces.append(card)
if card in used:
used.remove(card)
options_list.remove(card)
else:
used.append(card)
#Sets background colours and shapes
def draw_backgrounds():
global start_time, time
top_menu = pygame.draw.rect(screen, orange, [0, 0, screen_width, 75])
score_text = small_font.render(f'Player 1 score : {score}', True, white)
screen.blit(score_text, (20, 20))
board_space = pygame.draw.rect(screen, turquoise, [0, 100, screen_width, screen_height - 200], 0)
bottom_menu = pygame.draw.rect(screen, orange, [0, screen_height - 100, screen_width, 100], 0)
time = 0 + int((pygame.time.get_ticks() / 1000))
time_text = small_font.render(f'Your time: {time}', True, white)
screen.blit(time_text, (20, 550))
def draw_cards():
global rows, columns, correct
card_list = []
for i in range(cols):
for j in range(rows):
#draws the cards and sets their size and position
card = pygame.draw.rect(screen, orange,[i * 85 + 48, j *78 + 110, 61, 65], 0, 4)
card_list.append(card)
## randomly adds numbers onto the cards. to make sure that the black numbers dont populate instantly when game is created
'''card_text = small_font.render(f'{spaces[i * rows + j]}', True, black)
screen.blit(card_text, (i * 75 + 18, j * 65 + 120))'''
for r in range(rows):
for c in range(cols):
if correct[r][c] == 1:
#creates green border around cards when match is made
pygame.draw.rect(screen, green, [c * 85 + 48, r * 78 + 110, 61, 65], 3, 4)
card_text = small_font.render(f'{spaces[c * rows + r]}', True, black)
screen.blit(card_text, (c * 85 + 55, r * 78 + 125))
return card_list
def check_guesses(first, second):
global spaces, correct, score, matches
if spaces[first] == spaces[second]:
#floor division
col1 = first // rows
col2 = second // rows
row1 = first - (first // rows * rows)
row2 = second - (second // rows * rows)
#checks for match and score incremented by 1
if correct[row1][col1] == 0 and correct[row2][col2] == 0:
correct[row1][col1] = 1
correct[row2][col2] = 1
score += 1
matches += 1
running = True
while running:
timer.tick(fps)
screen.fill(turquoise)
if new_board:
generate_board()
new_board = False
draw_backgrounds()
board = draw_cards()
if first_guess and second_guess:
check_guesses(first_guess_num, second_guess_num)
##delays code for miliseconds to see second guess
pygame.time.delay(1000)
first_guess = False
second_guess = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
for i in range(len(board)):
button = board[i]
#can guess as long as it's not game over
if not game_over:
if button.collidepoint(event.pos) and not first_guess:
first_guess = True
first_guess_num = i
##ensures that the same card cannot be clicked twice
if button.collidepoint(event.pos) and not second_guess and first_guess and i != first_guess_num:
second_guess = True
second_guess_num = i
#Checks for game over
if matches == rows * cols // 2:
if not game_over:
end_time = time
game_over = True
winner = pygame.draw.rect(screen, turquoise,[0, 0, 600, 600])
winner_text = large_font.render(f'YOUR TIME WAS {end_time} !!', True, orange)
screen.blit(winner_text, (30, screen_height - 350))
#allows card to be flipped to show number
if first_guess:
card_text = small_font.render(f'{spaces[first_guess_num]}', True, black)
location = (first_guess_num // rows * 85 + 55, (first_guess_num - (first_guess_num // rows * rows)) * 78 + 125)
screen.blit(card_text, (location))
if second_guess:
card_text = small_font.render(f'{spaces[second_guess_num]}', True, black)
location = (second_guess_num // rows * 85 + 55, (second_guess_num - (second_guess_num // rows * rows)) * 78 + 125)
screen.blit(card_text, (location))
pygame.display.flip()
pygame.quit()

Related

I want the user to only be able to input mouse input once text is done displaying [duplicate]

I have this code
import pygame, random, sys
from pygame.locals import *
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0 , 0, 255)
WIDTH = 20
HEIGHT = 20
WIDTH1 = 30
HEIGHT1 = 30
MARGIN = 5
MARGIN1 = 10
array_width = 4
array_height = 8
grid = []
guess1 = 'white'
guess2 = 'yellow'
guess3 = 'blue'
guess4 = 'green'
guess5 = 'red'
guess6 = 'pink'
guess7 = 'purple'
guess8 = 'orange'
loop = ()
computerguess = []
# CREATING RANDOM COLOUR SEQUENCE TO GUESS
for i in range(4):
loop = random.randint(1,8)
if loop == 1:
computerguess.append(guess1)
if loop == 2:
computerguess.append(guess2)
if loop == 3:
computerguess.append(guess3)
if loop == 4:
computerguess.append(guess4)
if loop == 5:
computerguess.append(guess5)
if loop == 6:
computerguess.append(guess6)
if loop == 7:
computerguess.append(guess7)
if loop == 8:
computerguess.append(guess8)
print(computerguess)
for row in range(10):
grid.append([])
for column in range(10):
grid[row].append(0)
colors = [(0, 0, 0) for i in range(array_width * array_height)]
blocks = [False for i in range(array_width * array_height)]
indicator_grid = [[None for column in range(4)] for row in range(8)]
pygame.init()
# Set the HEIGHT and WIDTH of the screen
WINDOW_SIZE = [300, 300]
WINDOW_SIZE2 = [300, 300]
screen = pygame.display.set_mode(WINDOW_SIZE)
screen2 = pygame.display.set_mode(WINDOW_SIZE2)
# Set title of screen
pygame.display.set_caption("MASTERMIND GAME")
done = False
clock = pygame.time.Clock()
# -------- Main Program Loop -----------
#TEXT BOX VARIABLES AND DATA
base_font = pygame.font.Font(None, 20)
user_text = ""
input_rect = pygame.Rect (10,250,100,50)
color_active = pygame.Color('lightskyblue3')
color_passive = pygame.Color('gray15')
color=color_passive
active = False
current_color = "white"
grid = [[current_color for column in range(4)] for row in range(8)]
#----MAIN PROGRAM LOOP----#
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
column = pos[0] // (WIDTH + MARGIN)
row = pos[1] // (HEIGHT + MARGIN)
# check if column and row are valid grid indices
if 0 <= row < array_height and 0 <= column < array_width:
try:
grid[row][column] = current_color
except:
print("invalid color")
# TEXT BOX CREATION AND USAGE
if event.type == pygame.MOUSEBUTTONDOWN:
if input_rect.collidepoint(event.pos):
active = True
else:
active = False
if event.type == pygame.KEYDOWN:
if active == True:
if event.key == pygame.K_BACKSPACE:
user_text = user_text[0:-1]
else:
user_text += event.unicode
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
user_text = user_text
if user_text != "":
current_color = user_text
user_text = ""
if active:
color = color_active
else:
color=color_passive
#TEXT FOR THE GUI TO MAKE IT EASIER FOR THE USER
screen.fill(0)
pygame.draw.rect(screen,color,input_rect,2)
text_surface= base_font.render(user_text,True,(255,255,255))
screen.blit(text_surface, (input_rect.x +5, input_rect.y + 5))
text1 = base_font.render("WORK BOTTOM TO TOP ", True, (0, 50, 255))
text2 = base_font.render('POSSIBLE CHOICES:', True, (250, 0, 0))
text3 = base_font.render('WHITE BLUE RED', True, (0, 128, 0))
text4 = base_font.render('GREEN ORANGE PINK', True, (0,128,0))
text5= base_font.render('PURPLE YELLOW', True, (0, 128, 0))
screen.blit(text1,(140, 200))
screen.blit(text2,(140, 220))
screen.blit(text3,(140, 240))
screen.blit(text4,(140, 260))
screen.blit(text5,(140, 280))
screen.blit(text5,(140, 280))
for row, gridrow in enumerate(grid):
for column, color in enumerate(gridrow):
pygame.draw.rect(screen,
color,
[(MARGIN + WIDTH) * column + MARGIN,
(MARGIN + HEIGHT) * row + MARGIN,
WIDTH,
HEIGHT])
if gridrow == computerguess:
text = base_font.render("Correct, you win!!!!!", True, (255, 128, 0))
screen.blit(text,
(10, 220 ))
x = 100 + (MARGIN + WIDTH) * column + MARGIN
y = (MARGIN + HEIGHT) * row + MARGIN
color = "grey"
pygame.draw.circle(screen, color, (x + WIDTH // 2, y + WIDTH // 2), WIDTH // 2)
for row, gridrow in enumerate(grid):
if computerguess[0] == gridrow[0]:
color = "red"
pygame.draw.circle(screen, color, (x + WIDTH // 2, y + WIDTH // 2), WIDTH // 2)
if computerguess[1] == gridrow[1]:
color = "purple"
pygame.draw.circle(screen, color, (x + WIDTH // 2, y + WIDTH // 2), WIDTH // 2)
if computerguess[2] == gridrow[2]:
color = "red"
pygame.draw.circle(screen, color, (x + WIDTH // 2, y + WIDTH // 2), WIDTH // 2)
if computerguess[3] == gridrow[3]:
color = "red"
pygame.draw.circle(screen, color, (x + WIDTH // 2, y + WIDTH // 2), WIDTH // 2)
clock.tick(60)
pygame.display.flip()
pygame.quit()
i would like to add a title screen, that says start in the form of a button and then would transfer them to the code to begin playing, but i'm not very sure how to do it, i have added a new window (WINDOW_SIZE2), but i am not sure where to go from there
Any help is much appreciated
Thanks
The implementation of a button is answered several times. For example Pygame mouse clicking detection, How do I detect if the mouse is hovering over a button? PyGame button class is not displaying the text or changing colour on hover or How can I add an image or icon to a button rectangle in Pygame? and myn more.
Create 2 scenes with 2 application loops. The first loop shows the title screen and waits for button 2 to be pressed. The 2nd loop is the game loop:
button_rect = pygame.Rect(x, y, width, height) # start button rectangle
abort = False
start = False
while not abort and not start:
for event in pygame.event.get():
if event.type == pygame.QUIT:
abort = True
if event.type == MOUSEBUTTONDOWN:
if button_rect.collidepoint(event.pos):
start = True
# draw title screen
# [...]
done = abort
while not done:
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# game
# [...]
Alternatively, you can combine both scenes in one loop.Add a variable game_state, implement event handling and draw the scenes depending on the value of game_state. Change the game_state when the start button is pressed:
game_state = 'title'
done = False
while not done:
# event handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if game_state == 'title':
if event.type == MOUSEBUTTONDOWN:
if button_rect.collidepoint(event.pos):
game_state = 'game'
elif game_state == 'game':
# handle game events:
# [...]
# drawing
if game_state == 'title':
# draw title screen
# [...]
elif game_state == 'game':
# game
# [...]

Clicking recs in Pygame

I am currently starting on python3 in the past few days and started in developing minor projects, but i'm having some trouble, so sorry if i cant use top notch proffessional coders language.
How can I make a pygame.draw.rect rectangle become clickable?
I know about the pygame.mouse. ones, but there might be something wrong in the code.
I want it so that when i press the red rect it will decreese i health and will add a "burn" stat (its just text for now).
Here's the code:
import pygame
import random
import sys
pygame.init()
#Screen Size
screen_width = 600
screen_height = 600
#Screen Settings
screen = pygame.display.set_mode((screen_width, screen_height))
br_color = (0, 0, 0)
pygame.display.set_caption("Type Effect Beta 0.0.1")
#Game Over Bullian
game_over = False
#Other Defenitions
clock = pygame.time.Clock()
myFont = pygame.font.SysFont("arial", 20)
#Basic Recources
health = 50
score = 0
status = "none"
#Colors for the Text
white = (255, 255, 255)
red = (255, 0, 0)
#Mouse Things
mouse_location = pygame.mouse.get_pos()
print(mouse_location)
#Status Text Helpers
burning = "Burning"
#Cards
card_size_x = 45
card_size_y = 60
fire_car_color = (255, 0 ,0)
fire_card_posx = 300
fire_card_posy = 300
card_button_fire = pygame.Rect(fire_card_posx, fire_card_posy, card_size_x, card_size_y)
#Functions
def health_decrease_burn(health, status):
health -= 1
status = "burning"
return health and status
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if pygame.mouse.get_pressed()[0] and card_button_fire.collidepoint(mouse_location):
health_decrease_burn()
if health_decrease_burn(health, status) and health <= 0:
game_over = True
text = "Score:" + str(score)
lable = myFont.render(text, 1, white)
screen.blit(lable, (10, 10))
text = "Health:" + str(health)
lable = myFont.render(text, 1, red)
screen.blit(lable, (10, 30))
text = "Status:" + str(status)
lable = myFont.render(text, 1, white)
screen.blit(lable, (10, 50))
pygame.draw.rect(screen, fire_car_color, (fire_card_posx, fire_card_posy, card_size_x, card_size_y))
clock.tick(30)
pygame.display.update()
You need to grab the mouse_location every iteration of your main loop, as the mouse position/state is constantly changing. The current code is only fetching the mouse position once, on start.
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.MOUSEBUTTONUP: # if mouse button clicked
mouse_location = pygame.mouse.get_pos() # <-- HERE
if pygame.mouse.get_pressed()[0] and card_button_fire.collidepoint(mouse_location):
health_decrease_burn()
#[...etc ]

How can you make the previous line disappear in python?

I'm making a constellation that starts from (0,0). The previous line has to disappear after a two second delay and when the left is clicked within the two second delay, white circles should appear. I don't know why my timer isn't working and I'm not sure how to make the line disappear. Also the circles don't appear. This is my code
from pygame import *
import random
init()
size = width, height = 700, 700
screen = display.set_mode(size)
button = 0
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0,0,255)
WHITE = (255,255,255)
colors = (RED,GREEN,BLUE)
time.set_timer(USEREVENT, 2000)
mx = 0
my = 0
def drawScene(screen, button):
if button == 1:
draw.circle(screen,RED,(mx,my), 5)
draw.line(screen,RED,(mx,my),(lx,ly),2)
draw.circle(screen,RED,(lx,ly), 5)
display.flip()
if button == 3:
draw.line(screen,random.choice(colors),(mx,my),(lx,ly),2)
draw.circle(screen,random.choice(colors),(lx,ly), 5)
display.flip()
running = True
myClock = time.Clock()
start = time.get_ticks()
# Game Loop
while running:
lx = mx
ly = my
for evnt in event.get(): # checks all events that happen
if evnt.type == QUIT:
running = False
if evnt.type == MOUSEBUTTONDOWN:
mx,my = evnt.pos
button = evnt.button
cx,cy = mouse.get_pos()
draw.circle(screen,WHITE,(cx,cy),5)
if evnt.type == USEREVENT:
my_event = event.Event(USEREVENT)
time.set_timer(my_event , 2000)
drawScene(screen, button)
myClock.tick(60) # waits long enough to have 60 fps
quit()
I hope this is what you were wanting and the comments are clear.
from pygame import *
import random
init()
size = width, height = 700, 700
screen = display.set_mode(size)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
WHITE = (255, 255, 255)
colors = (RED, GREEN, BLUE)
time.set_timer(USEREVENT, 2000)
mx = 0
my = 0
def drawScene(screen, button, prev_point, new_point):
if button == 1:
draw.circle(screen, RED, prev_point, 5)
draw.circle(screen, WHITE, new_point, 5)
draw.line (screen, RED, prev_point, new_point, 2)
display.flip()
if button == 3:
draw.line (screen, random.choice(colors), prev_point, new_point,2)
draw.circle(screen, random.choice(colors), new_point, 5)
display.flip()
running = True
myClock = time.Clock()
prev_render = time.get_ticks() #time in ticks that last render occured
prev_point = (mx, my) #where previous line ended
#function for when to re draw the scene
#ternary if. if override == True, then return true. Else return if time since last update > 2secs
rerender = lambda time_since_update, override: (time_since_update>2000, True)[override]
# Game Loop
while running:
override = False
for evnt in event.get(): # checks all events that happen
if evnt.type == QUIT:
running = False
if evnt.type == MOUSEBUTTONDOWN:
override = True #force window to rerender
new_point = evnt.pos #(mx, my)
button = evnt.button
#rerender window only if necessary. (personal preference)
updated_at = time.get_ticks()
dt = updated_at-prev_render #time difference
if(rerender(dt, override)):
screen.fill(BLACK)
drawScene(screen, button, prev_point, new_point)
prev_point = new_point
prev_render = updated_at
display.update()
myClock.tick(60) # waits long enough to have 60 fps
quit()
This is not a complete solution, but I'll give you a general idea how how to start
Create a list of times and a list of lines:
lines = []
Get the current time in the main application loop:
current_time = pygame.time.get_ticks()
When the mouse is clicked then compute the time when the line has to disappear (current_time + 2000) and compute a random color.
Add a Dictionary with the start point, the end point, the time when the line has to disappear and the color to the list of lines.
If the list of lines is empty, then the start point of the line is (0, 0) else the start point is the end point of the last line in the list:
if event.type == pygame.MOUSEBUTTONDOWN:
disappear_time = current_time + 2000
line_color = random.choice(colors)
prev_pt = (0, 0) if len(lines) == 0 else lines[-1]['end']
lines.append({'start': prev_pt, 'end': event.pos, 'time': disappear_time, 'color': line_color})
When the current time exceeds the time which is stored in time, then remove a point and a time form the lists of lines:
if len(times) > 0 and current_time > times[0]:
del lines[0]
Draw the lines by and circles in a loop:
screen.fill(BLACK)
for li in lines:
pygame.draw.line(screen, li['color'], li['start'], li['end'], 2)
pygame.draw.circle(screen, li['color'], li['start'], 5)
pygame.draw.circle(screen, li['color'], li['end'], 5)
See the example:
import pygame
import random
pygame.init()
size = width, height = 700, 700
screen = pygame.display.set_mode(size)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0,0,255)
WHITE = (255,255,255)
colors = (RED,GREEN,BLUE)
lines = []
running = True
myClock = pygame.time.Clock()
while running:
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
disappear_time = current_time + 2000
line_color = random.choice(colors)
prev_pt = (0, 0) if len(lines) == 0 else lines[-1]['end']
lines.append({'start': prev_pt, 'end': event.pos, 'time': disappear_time, 'color': line_color})
if len(lines) > 0 and current_time > lines[0]['time']:
del lines[0]
screen.fill(BLACK)
for li in lines:
pygame.draw.line(screen, li['color'], li['start'], li['end'], 2)
pygame.draw.circle(screen, li['color'], li['start'], 5)
pygame.draw.circle(screen, li['color'], li['end'], 5)
pygame.display.flip()
myClock.tick(60)
quit()

Comparing keypressed to a char

I want to make some sort of typing game in python using pygame. So, if the key pressed character is the same as the character in the word, it should return true... Is there any way to do this in python?
For example:
the word is "cat", if the user presses the key 'c', then it returns true... and so on for the rest of the characters.
here's my main.py file
from time import sleep
import pygame
import random
import winsound
from words import Words
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
BLUE = ( 0, 0, 255)
GREEN = ( 0, 255, 0)
RED = (255, 0, 0)
pygame.init()
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
done = False
clock = pygame.time.Clock()
screen = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT))
w1 = Words(screen) #making a single word (for now) to see if typing works
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(WHITE)
w1.draw()
#attempting to write code here to compare word and user input
pygame.display.flip()
clock.tick(60)
pygame.init()
exit()
here's my words.py file
from random_words import RandomWords
import pygame
import random
from queue import *
rw = RandomWords()
class Words():
def __init__(self, screen):
self.screen = screen
self.x_point = 400
self.y_point = 400
self.word = rw.random_word() #generates a random word
self.queue = Queue() #was hoping to use the queue so that if the user types the char correctly in the right order, then the letter would change color or something (but that's further down the line)
for c in self.word: #iterate through randomized word..
self.queue.put(c) #add each char in randomized word to queue, for typing reasons
def getY(self):
return self.y_point
def draw(self):
#creates a new object
myfont = pygame.font.SysFont('Comic Sans MS' ,30)
#creates a new surface with text drawn on it
textsurface = myfont.render(self.word, False, (0,0,0))
self.screen.blit(textsurface,(self.x_point,self.y_point))
Event KEYDOWN has event.unicode, event.key, event.mod
You can compare
if event.type == pygame.KEYDOWN:
if event.unicode == "a":
or even
if event.type == pygame.KEYDOWN:
if event.unicode.lower() == "a":
to check "a" and "A"
To check char in word
if event.type == pygame.KEYDOWN:
if event.unicode.lower() in your_word.lower():
Example code use event.unicode to render text with pressed keys.
BTW: It is not some Entry widget so it doesn't delete char when you press backspace.
import pygame
# --- constants ---
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
BLUE = ( 0, 0, 255)
GREEN = ( 0, 255, 0)
RED = (255, 0, 0)
SCREEN_WIDTH = 300
SCREEN_HEIGHT = 200
FPS = 5 # `FPS = 25` is enough for human eye to see animation.
# If your program don't use animation
# then `FPS = 5` or even `FPS = 1` can be enough
# --- main ---
# - init -
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT))
screen_rect = screen.get_rect()
# - objects -
font = pygame.font.SysFont(None, 30)
text = ""
text_image = font.render(text, True, GREEN)
text_rect = text_image.get_rect() # get current size
text_rect.center = screen_rect.center # center on screen
# - mainloop -
clock = pygame.time.Clock()
done = False
while not done:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
text += event.unicode
text_image = font.render(text, True, GREEN)
text_rect = text_image.get_rect() # get current size
text_rect.center = screen_rect.center # center on screen
# - draws -
screen.fill(BLACK)
screen.blit(text_image, text_rect)
pygame.display.flip()
clock.tick(FPS)
# - end -
pygame.quit() # <-- quit(), not init()

How to create a pause button in Pygame?

I've been trying to make a game, and everything in there works so far except that the pause button , that when pressed the button P should pause and when pressed S should continue. I kinda understand the problem such that once in enters the while loop in the main code it wont get out. I tried putting the pause function inside the while loop. Please do help or provide tips to fix if possible thank you.
import pygame
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
Blue = (2,55,55)
def recursive_draw(x, y, width, height):
""" Recursive rectangle function. """
pygame.draw.rect(screen, WHITE,
[x, y, width, height],
1)
speed = [10,0]
rect_change_x = 10
rect_change_y = 10
# Is the rectangle wide enough to draw again?
if (width > 25):
# Scale down
x += width * .1
y += height * .1
width *= .8
height *= .8
# Recursively draw again
recursive_draw(x, y, width, height)
def recursive_draw2(x, y, width, height):
""" Recursive rectangle function. """
pygame.draw.rect(screen, Blue,
[x, y, width, height],
1)
speed = [10,0]
rect_change_x = 10
rect_change_y = 10
# Is the rectangle wide enough to draw again?
if (width > 25):
x += width * .1
y += height * .1
width *= .8
height *= .8
# Recursively draw again
recursive_draw2(x, y, width, height)
def paused():
screen.fill(black)
largeText = pygame.font.SysFont("comicsansms",115)
TextSurf, TextRect = text_objects("Paused", largeText)
TextRect.center = ((display_width/2),(display_height/2))
gameDisplay.blit(TextSurf, TextRect)
while pause:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
#gameDisplay.fill(white)
button("Continue",150,450,100,50,green,bright_green,unpause)
button("Quit",550,450,100,50,red,bright_red,quitgame)
pygame.display.update()
clock.tick(15)
pygame.init()
#rectanglelist = [big()]
# Set the height and width of the screen
size = [700, 500]
screen = pygame.display.set_mode(size)
pygame.display.set_caption("My Game")
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
black=(0,0,0)
end_it=False
time = 100
USEREVENT = 0
pygame.time.set_timer(USEREVENT+1, 10)
milliseconds = 0
seconds = 0
start_it = False
while (end_it==False):
screen.fill(black)
myfont=pygame.font.SysFont("Britannic Bold", 40)
nlabel=myfont.render("Welcome to "+ " Jet shooter ", 1, (255, 0, 0))
label=myfont.render("Click on the mouse to start ", 1, (255, 0, 0))
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
end_it=True
screen.blit(nlabel,(200, 100))
screen.blit(label, (170,300))
pygame.display.flip()
while (start_it==False):
screen.fill(black)
myfont2=pygame.font.SysFont("Britannic Bold", 40)
label2=myfont2.render("Ready?", 1, (255, 0, 0))
screen.blit(label2, (300,250))
pygame.display.flip()
pygame.time.wait(3000)
start_it = True
fall = False
while (fall==False):
nlist = [3,2,1]
for i in (nlist):
screen.fill(black)
n = str(i)
myfont3=pygame.font.SysFont("Britannic Bold", 40)
score = myfont3.render(n,1,(255,0,0))
screen.blit((score), (350,250))
pygame.display.flip()
pygame.time.wait(1000)
screen.fill(black)
myfont4=pygame.font.SysFont("Britannic Bold", 40)
label4=myfont3.render("GOOO!!!", 1, (255, 0, 0))
screen.blit(label4, (300,250))
pygame.display.flip()
pygame.time.wait (1000)
fall = True
pause = 0
b = 0
# -------- Main Program Loop -----------
while not done:
for event in pygame.event.get():
if event.type == pygame.KEYUP:
if event.key==K_p:
pause=True
if pause == True:
screen.fill(black)
font=pygame.font.SysFont("Britannic Bold", 40)
nlabelBB=myfont.render("Pause", 1, (255, 0, 0))
screen.blit(nlabelBB,(200, 100))
pygame.display.flip()
# Set the screen background
screen.fill(BLACK)
flip = 1
a = 0
# ALL CODE TO DRAW SHOULD GO BELOW THIS COMMENT
recursive_draw(0, 0, 700, 500)
recursive_draw2(35,25, 625, 450)
**###I TRIED TO PUT THE PAUSE GAME HERE AND IF PRESSED P PAUSE AND S CONTINUE
while a == 0 :
if flip == 1 :
recursive_draw(35,25,625,450)
recursive_draw2(0, 0, 700, 500)
flip = flip + 1
pygame.display.flip()
if event.type == pygame.KEYUP:
if event.key==K_p:
a = 1
screen.fill(black)
font=pygame.font.SysFont("Britannic Bold", 40)
nlabelBB=myfont.render("Pause", 1, (255, 0, 0))
screen.blit(nlabelBB,(200, 100))
pygame.display.flip()
if event.key==K_s:
a = 0
if flip == 2 :
recursive_draw(0, 0, 700, 500)
recursive_draw2(35, 25, 625, 450)
flip = flip - 1
pygame.display.flip()
if event.type == pygame.KEYUP:
if event.key==K_p:
a = 1
screen.fill(black)
font=pygame.font.SysFont("Britannic Bold", 40)
nlabelBB=myfont.render("Pause", 1, (255, 0, 0))
screen.blit(nlabelBB,(200, 100))
pygame.display.flip()
if event.key==K_s:
a = 0**
if event.type == pygame.QUIT:
done = True
# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Limit to 60 frames per second
clock.tick(20)
# Be IDLE friendly. If you forget this line, the program will 'hang'
# on exit.
pygame.quit()
Just use a single game loop for everything and keep track of the current state (e.g. main menu, pause screen, game scene) of your game..
Here's an example where we keep track of the state by a simple variable called state and act in our game loop accordingly:
import pygame, math, itertools
def magnitude(v):
return math.sqrt(sum(v[i]*v[i] for i in range(len(v))))
def sub(u, v):
return [u[i]-v[i] for i in range(len(u))]
def normalize(v):
return [v[i]/magnitude(v) for i in range(len(v))]
pygame.init()
screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
path = itertools.cycle([(26, 43), (105, 110), (45, 225), (145, 295), (266, 211), (178, 134), (250, 56), (147, 12)])
target = next(path)
ball, speed = pygame.rect.Rect(target[0], target[1], 10, 10), 3.6
pause_text = pygame.font.SysFont('Consolas', 32).render('Pause', True, pygame.color.Color('White'))
RUNNING, PAUSE = 0, 1
state = RUNNING
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT: break
if e.type == pygame.KEYDOWN:
if e.key == pygame.K_p: state = PAUSE
if e.key == pygame.K_s: state = RUNNING
else:
screen.fill((0, 0, 0))
if state == RUNNING:
target_vector = sub(target, ball.center)
if magnitude(target_vector) < 2:
target = next(path)
else:
ball.move_ip([c * speed for c in normalize(target_vector)])
pygame.draw.rect(screen, pygame.color.Color('Yellow'), ball)
elif state == PAUSE:
screen.blit(pause_text, (100, 100))
pygame.display.flip()
clock.tick(60)
continue
break
As you can see, the rectangle keeps moving until you press P, which will change the state to PAUSE; and a simple message will now be displayed instead of drawing/moving the rectangle further.
If you press S the state switches back to the normal mode; all done in a single game loop.
Further reading:
Pygame level/menu states
Mulitple Displays in Pygame
Trying to figure out how to track Pygame events and organize the game's functions

Categories