I'm trying to build a program that will change each individual pixel within a Pygame surface to a random colour.
For a fixed and constant surface size (eg. 1300 x 700) this works and the whole surface is filled with random colours, however I'm trying to resize the surface with the pygame.RESIZABLE feature of Pygame on the fly (by updating the computed X and Y values that the program works from), every time the surface is resized, however, the Pygame surface only outputs randomly coloured pixels for pixels within the programs initial surface width and height (in this case 1300 x 700) and the rest of the surface is left black (the defult background colour I set), even though when I print the variables that respond to the screen height and width (and are being used to iterate through all the pixel) to the program log, they update as expected.
I don't understand how the surface is not responding to thees updated variables and I don't know how to fix this issue.
Any help is much appreciated and any questions about my code are welcome, thanks!
import pygame
import random
pygame.init() #initiates pygame
Comp_X = 1300
Comp_Y = 700
Window = pygame.display.set_mode((Comp_X, Comp_Y), pygame.RESIZABLE) #defines the window size (the varible doesnt have to be called window)
pygame.display.set_caption("Random Colours") #sets the title of the window
clock = pygame.time.Clock() #sets the refresh rate of the program
def GameLoop():
global Comp_X #computed pixles for the X axis
global Comp_Y #computed pixles for the Y axis
Comp_Tot = Comp_X * Comp_Y #total pixles on the screen
print("initial computed total pixles = " + str(Comp_Tot))
#setting x and y position
x = 0
y = 0
GameExit = False #sets the defult value of this varible to true
while not GameExit: #this is effectivly a "while true" loop, unless the varible "crashed" is set to false
for event in pygame.event.get(): #this for loop will listen for events
print(event.type)
print("X = " + str(Comp_X))
print("Y = " + str(Comp_Y))
if event.type == pygame.QUIT: # this if statement checks to see if the X in the top right of the window was pressed
GameExit = True # this will break the while loop if the condition is met
print("X = " + str(Comp_X))
print("Y = " + str(Comp_Y))
if event.type == 16: #event type 16 is the window resizing event
Comp_X = event.dict['size'][0]
Comp_Y = event.dict['size'][1]
Comp_Tot = Comp_X * Comp_Y
print("current computed total pixles = " + str(Comp_Tot))
#Creating the colours
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
for pixle in range (0, Comp_Tot):
if x == Comp_X:
print("Computed X = " + str(Comp_X))
print("Computed Y = " + str(Comp_Y))
x = 0
y += 1
pygame.draw.rect(Window, (random.randint(0,255), random.randint(0,255), random.randint(0,255)), [x, y, 2, 2])# draws a red square
x += 1
#Drawing the frame
pygame.display.update() #This updates the frame
clock.tick(60) # this defines the FPS
GameLoop()
pygame.quit() # this will close the window if the "while GameLoop" loop stops running
quit()
Using defult height and width of 1300 x 700
Resizing surface to 1457 x 992 - not all of the surface is filled!
There are actually two problems with the code that cause the error. The first is not having the
Window = pygame.display.set_mode((Comp_X, Comp_Y), pygame.RESIZABLE)
line inside of the if event.type == 16: as already mentioned.
The other problem is very minor but causes it to not work properly if resized after filling the screen once already and that is that you are never resetting the values of x or y back to 0 after you fill the screen.
Fixed section of code:
if event.type == pygame.VIDEORESIZE:
Comp_X = event.w
Comp_Y = event.h
Comp_Tot = Comp_X * Comp_Y
print("current computed total pixles = " + str(Comp_Tot))
Window = pygame.display.set_mode((Comp_X, Comp_Y), pygame.RESIZABLE)
#Creating the colours
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
for pixle in range (0, Comp_Tot):
if x == Comp_X:
#print("Computed X = " + str(Comp_X))
#print("Computed Y = " + str(Comp_Y))
x = 0
y += 1
pygame.draw.rect(Window, (random.randint(0,255), random.randint(0,255), random.randint(0,255)), [x, y, 2, 2])# draws a red square
x += 1
x = 0
y = 0
I also changed event.type == 16 to event.type == pygame.VIDEORESIZEas it's more readable.
When the window resize event fires, you need to call pygame.display.set_mode((w, h)) again to allocate a new surface of that size. Otherwise you're still writing to the original 1300x700 Surface instance.
Related
I've put pygame.display.update() multiple different places but for some reason it absolutely doesnt let me do the H keypress so it draws help, everything else works.
This is for a school assignment that ive made much harder than it was. I'm technically done i just wanted to make a main menu, everything went smooth then the help screen never wanted to draw
import pygame
import time
import random
import sys
import os
# ! Use print(event) for coordinate reading
# TODO: Add highscore file read and overwrite ✔️
# TODO: Add Game over message ✔️
# TODO: Show highscore and points of that run ✔️
# TODO: Fix Snake not being on same x,y as apple (Most likely wrong movement increments) ✔️
# TODO: Add GRID ✔️
# ? Find a better spawning logic ✔️
# ? Add menu instead of a simple string - NOE AV DET JÆVLIGSTE JEG HAR STARTET PÅ
# ? Fine tune resolution and size
# ? Add a unique powerup with 3% spawn chance giving 5 points and 1 body length
# ! Pygame Initiatior
pygame.init() # * Initiates pygame
# ! Screen resolution and title
sc_width = 400
sc_height = 400
screen = pygame.display.set_mode((sc_width, sc_height)) # * Sets pygame window
pygame.display.set_caption('Snake') # * Sets window title to Snake
# ! Color Variables
bgcolor = (25, 51, 102) # * Dark blue for background color
yellow = (255, 255, 0) # * Yellow color for snake
red = (255, 0, 0) # * Red color for points & game over
white = (255, 255, 255) # * White color for score
# ! FPS variable
clock = pygame.time.Clock() # * Used to set the FPS of the game using clock.tick(xyz)
# ! Font
font = pygame.font.SysFont(None, 30) # * None = Default pygame font. 40 = size of font
# ! Game Over Draw function
def GameOver(msg, color): # * Function takes in a string and color and draws it on screen
text = font.render(msg, True, color) # * Draws msg with font with True for anti aliasing (Smooth edges) with specified color when func is called
screen.blit(text, [50, 100]) # * Draws text at 100x100
# ! Snake
snake_block = 10
def Snake(snake_block, snakelist):
for x in snakelist:
pygame.draw.rect(screen, yellow, [x[0], x[1], snake_block, snake_block])
# ! Grid
black = (0, 0, 0)
def Grid():
size = 10 # * Sets grid size to 10 (same as snake)
for x2 in range(0, sc_width, size): # * Gaps 10 in width
for y2 in range(0, sc_height, size): # * Gaps height with 10
drawGrid = pygame.Rect(x2, y2, size, size) # * Makes a grid
pygame.draw.rect(screen, black, drawGrid, 1) # * Draws it onto the screen
# ! Draw Score
def drawScore(score):
points = font.render('Score: ' + str(score), True, white)
screen.blit(points, [0, 0]) # * Draws it top left
# ! Make highscore txt
try:
f = open("highscore.txt", 'x') # * Creates file if it doesnt exist
f.write('0') # * No highscore set
f.close() # * Closes file to let other codes down the line rewrite the file
except FileExistsError: # * If exist continue to rest of code using it as the "highscore" file
pass
# ! Draw Highscore
f = open('highscore.txt', 'r') # * Opens as read
highscore = int(f.readline())
f.close()
def drawHighscore(highscore):
hc = font.render('Score: ' + str(highscore), True, white)
screen.blit(hc, [310, 0]) # * Draws it top right
# # ! Draw PRE GAME Screen
# def drawMenu(menu, color):
# pregame = font.render(menu, True, white)
# screen.blit(pregame, [50, 100])
# ! Multiline draw function (Stackoverflow) / PRE GAME
def drawMenu(menu, x, y, fsize):
lines = menu.splitlines()
for i, l in enumerate(lines):
screen.blit(font.render(l, 0, white), (x, y + fsize*i))
# ! Draw Help screen
def drawHelp(x, y, fsize):
help = "Controls: [W][A][S][D]\nInstructions: \nUse WASD to control the snake.\nGrab as many apples as you can;\nand dont crash into yourself :)\n\n [ (B) A C K ]"
hlp = help.splitlines()
for i, l in enumerate(hlp):
screen.blit(font.render(l, 0, white), (x, y + fsize*i))
def mainMenu():
menu = "[ (S) T A R T ]\n [ (H) E L P ]\n [ (Q) U I T ]\n jeg er best"
screen.fill(bgcolor)
drawMenu(menu, 140, 120, 80)
for event in pygame.event.get(): # * Gathers inputs
if event.type == pygame.KEYDOWN: # * Checks key presses
if event.key == pygame.K_q: # * If Q is pressed
pygame.quit()
sys.exit()
elif event.key == pygame.K_s: # * Calls game loop again
game()
elif event.key == pygame.K_h:
screen.fill(bgcolor)
drawHelp(25, 70, 40)
# ! Game Loop
def game():
finished = False
done = False
# ! Spawn location of snake
x = sc_width / 2 # * Spawns snake at screen width / 2
x_move = 0 # * To update x coordinates as the snake moves
y = sc_height / 2 # * Spawns snake at screen height / 2
y_move = 0 # * To update y coordinates as the snake moves
score = 0
f = open('highscore.txt', 'r') # * Opens as read
highscore = int(f.readline())
f.close()
snakelist = []
snake_len = 1
# ! Randomizing apple spawn locations
apple_x = round(random.randrange(0, sc_width - 10) / 10.0) * 10.0
apple_y = round(random.randrange(0, sc_height - 10) / 10.0) * 10.0
while not finished:
while done == True:
screen.fill(bgcolor)
drawScore(snake_len - 1)
drawHighscore(highscore)
mainMenu()
# ! Movement input logic
for event in pygame.event.get(): # * Gathers inputs
if event.type == pygame.QUIT: # * If pygame.quit gets called (clicking X on window) it will set finished to True which will end game loop
finished = True # * Ends game loop
sys.exit()
if event.type == pygame.KEYDOWN: # * Checks if a key is pressed down
if event.key == pygame.K_d: # * If key 'D' is pressed increase x by 10 making it move right
x_move = 10 # * Speed it moves
y_move = 0 # * No vertical movement
elif event.key == pygame.K_a: # * If key 'A' is pressed decrease x by -10 making it move left
x_move = -10 # * Speed it moves
y_move = 0 # * No vertical movement
elif event.key == pygame.K_w: # * If key 'W' is pressed decrease y by -10 making it move up
x_move = 0 # * No horizontal movement
y_move = -10 # * Speed it moves
elif event.key == pygame.K_s: # * If key 'S' is pressed increase y by 10 making it move down
x_move = 0 # * No horizontal movement
y_move = 10 # * Speed it moves
# ! Out of bounds logic
# * If snake is at a value higher than screen res or lower than 0; it means its outside the screen box, then the Game loop var will be True and game ends
if x >= sc_width or x < 0 or y >= sc_height or y < 0:
done = True
# ! Update movement
x += x_move
y += y_move
screen.fill(bgcolor)
# ! Draw grid
Grid() # * Draws grid
# ! Draw snake and apples
pygame.draw.rect(screen, red, [apple_x, apple_y, 10, 10]) # * Draws apples on screen with red color and puts it at apple_x,y with size of 10
pygame.draw.rect(screen, yellow, [x, y, 10, 10]) # * Draws snake on screen with yellow color and puts it at var x,y with a size of 10
snakeH = []
snakeH.append(x) # * Appends snake head x position
snakeH.append(y) # * Appends snake head y position
snakelist.append(snakeH) # * Adds snake head to THE snake list
if len(snakelist) > snake_len: # * If snake list is bigger than snake length
del snakelist[0] # * Kills head
for x1 in snakelist[:-1]:
# ? Tried to understand this by using prints and seeing values:
# ? I'm guessing since it checks each block (prints show list with values with 10 seperating (size of block))
# ? DOES NOT PRINT HEAD
# ? If head hits one of the other boxes, it will overlap in list and head wont be skipped and it dies
# ! print(snakelist[:-1]) (Bugtesting / code understanding)
if x1 == snakeH:
# ! print(snakelist[:-1]) (Bugtesting / code understanding)
done = True
Snake(snake_block, snakelist) # * Updates func with new values
drawScore(snake_len - 1) # * - 1 because dont want to count head as a point
drawHighscore(highscore)
# ! Snake eating apple and growing
if x == apple_x and y == apple_y: # * Checks if snake is at apple pos
apple_x = round(random.randrange(0, sc_width - 10) / 10.0) * 10.0 # * Spawns new apple inside play area
apple_y = round(random.randrange(0, sc_height - 10) / 10.0) * 10.0 # * Spawns new apple inside play area
snake_len += 1 # * Increases snake length by 1
score += 1 # * Increases score by 1
# ! Saving highscore
f = open("highscore.txt", 'r+') # * Opens Highscore
highscore = int(f.readline()) # * Reads Highscore
if highscore > score: # * If Highscore > score(that run)
f.close() # * Close file
else: # * But if score > highscore
f.close # * Close it so it doesnt add to existing number ex: highscore: 5 score that run 6 = highscore: 56
f = open("highscore.txt", 'w') # * Open as write so it writes a new number
f.write(f'{score}') # * Write current score
f.close() # * Close
f = open('highscore.txt', 'r') # * Opens as read
highscore = int(f.readline())
f.close() # * Close file
# ! Setting FPS
clock.tick(30) # * Sets FPS to 30
pygame.display.update()
pygame.quit() # * Uninitializes pygame
quit() # * Quits
while True:
mainMenu()
I have modified your drawHelp function as follows:
def drawHelp(x, y, fsize):
help = "Controls: [W][A][S][D]\nInstructions: \nUse WASD to control the snake.\nGrab as many apples as you can;\nand dont crash into yourself :)\n\n [ (B) A C K ]"
hlp = help.splitlines()
for i, l in enumerate(hlp):
screen.blit(font.render(l, 0, white), (x, y + fsize*i))
pygame.display.update()
# to stay in this function until the B key is pressed.
b_pressed = False
while not b_pressed:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_b:
b_pressed = True
Note I also had to add pygame.display.update() to the end of drawMenu() to make the main menu appear.
That said, there are several problems that make it harder for you to extend an debug your code. Typically pygame.display.update() should only be called once, also events should ideally be handled in one place. Event handlers would ideally modify the game state, e.g. change state from Main Menu to Help. Your event handlers call functions that take over event handling and drawing and updates. In order to achieve your outcome without refactoring your code, I've followed a similar practice.
It would probably help you to read up on state machines, here's an answer that may help you, or a pygame example whose use I imagine isn't strictly permitted for your homework. You've already started down this path with your done and finished variables.
This question already has answers here:
pygame capture keyboard events when window not in focus
(2 answers)
Get Inputs without Focus in Python/Pygame?
(3 answers)
Closed 3 months ago.
I'm trying to implement a feature in Pygame where if the user moves the mouse outside the window the relative position (event.rel) can be returned. I'm trying to do this because I want to make a game where you can keep turning left or right from mouse input.
I know this is possible from the docs:
If the mouse cursor is hidden, and input is grabbed to the current display the mouse will enter a virtual input mode, where the relative movements of the mouse will never be stopped by the borders of the screen. See the functions pygame.mouse.set_visible() and pygame.event.set_grab() to get this configured.
For this reason, I've implemented these lines in my code
pygame.mouse.set_visible(False)
pygame.event.set_grab(True)
However this doesn't help. The actual behaviour is:
when the mouse is moving in the window, event.rel prints to the console (expected)
when the mouse is moving outside the window, event.rel doesn't print to the console (not expected)
Other strange behaviour:
Initially event.rel is set to (300, 300) which is the center of my 600x600 screen. Ideally initial event.rel should be (0,0)
Possible cause:
I'm running the code below in trinket.io or repl.it. Because this is a browser the demo window might cause problems. Maybe this is solved by downloading python locally but i don't want to do this as it takes up too much space (my laptop sucks) and also it would be good to have an online demo to easily show employers that are too lazy to paste code into their IDEs.
Similar issue:
This guy on reddit had a very similar issue but I think his solution is not related to my situation
This block of code was what I asked originally but it doesn't demonstrate the question as well as the last block. Please scroll down to see the last block of code instead :)
import pygame
pygame.init()
# screen
X = 600 # width
Y = 600 # height
halfX = X/2
halfY = Y/2
screen = pygame.display.set_mode((X, Y), pygame.FULLSCREEN)
clock = pygame.time.Clock()
# Colors
WHITE = (255, 255, 255)
RED = (255, 0, 0)
# From the docs:
# "If the mouse cursor is hidden, and input is grabbed to the
# current display the mouse will enter a virtual input mode, where
# the relative movements of the mouse will never be stopped by the
# borders of the screen."
pygame.mouse.set_visible(False)
pygame.event.set_grab(True)
def drawCross(point, size, color):
pygame.draw.line(screen, color, (point[0]-size,point[1]-size), (point[0]+size,point[1]+size), 2)
pygame.draw.line(screen, color, (point[0]+size,point[1]-size), (point[0]-size,point[1]+size), 2)
canvas_rel = (halfX,halfY)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.MOUSEMOTION:
print('event.rel = ' + str(event.rel))
canvas_rel = [10 * event.rel[0] + halfX, 10 * event.rel[1] + halfY]
print(' canvas_rel = ' + str(canvas_rel))
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
print('escape')
running = False
break
screen.fill(WHITE)
# Red sight to represent pygame mouse event.rel
drawCross(canvas_rel, 10, RED)
pygame.display.flip()
clock.tick(20)
pygame.quit()
EDIT:
The above code doesn't fully demonstrate my problem. I've added a better sample below to make the the question easier to understand. This sample will draw a triangle in the centre of the screen. The triangle will rotate with relative horizontal motion of the mouse. Note the attempt to use pygame.mouse.set_pos
import pygame
from math import pi, cos, sin
pygame.init()
# screen
X = 600 # width
Y = 600 # height
halfX = X/2
halfY = Y/2
screen = pygame.display.set_mode((X, Y), pygame.FULLSCREEN)
clock = pygame.time.Clock()
# for getting relative mouse position when outside the screen
pygame.mouse.set_visible(False)
pygame.event.set_grab(True)
# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
# sensitivity
senseTheta = 0.01
# player
stand = [halfX, halfY]
t = 0 # angle in radians from positive X axis to positive x axis anticlockwise about positive Z
# draws a white cross in the screen center for when shooting is implemented :)
def drawPlayer():
p = stand
d = 50
a1 = 0.25*pi-t
a2 = 0.75*pi-t
P = (p[0],p[1])
A1 = (p[0] + d*cos(a1), p[1] + d*sin(a1)) # P + (d*cos(a1), d*sin(a1))
A2 = (p[0] + d*cos(a2), p[1] + d*sin(a2)) # P + (d*cos(a2), d*sin(a2))
pygame.draw.line(screen, BLACK, P, A1, 2)
pygame.draw.line(screen, BLACK, A1, A2, 2)
pygame.draw.line(screen, BLACK, A2, P, 2)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.MOUSEMOTION:
mouseMove = event.rel
print('mouseMove = ' + str(mouseMove))
t -= mouseMove[0] * senseTheta
# "Fix" the mouse pointer at the center
# pygame.mouse.set_pos((screen.get_width()//2, screen.get_height()//2))
# But I think set_pos triggers another MOUSEMOTION event as moving in positive x
# seems to move backward the same amount in x (i.e. the triangle doesn't
# rotate). See the console log.
# If you uncomment this line it works ok (the triangle rotates) but still
# glitches when the mouse leaves the window.
# uncommented or not I still cant get the mouse to work outside the window
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
break
screen.fill(WHITE)
drawPlayer()
pygame.display.flip()
clock.tick(40)
pygame.quit()
i Started creating a game and i stumbled into a little problem:
*When pressing "SPACE Bar" Red Squares keep Spawning randomly on Display
Question
How can i make the Red Squares into obstacles?
im a total begginer and im sorry for asking such a simple question.. :/
The Code might give you an idea:
import pygame, sys
from random import randint
from pygame.locals import*
"List the Stores the Squares"
red_square_list = []
gameDisplay_width = 800
gameDisplay_height = 600
pygame.init()
gameDisplay = pygame.display.set_mode((gameDisplay_width, gameDisplay_height))
pygame.display.set_caption("Square-it")
clock = pygame.time.Clock()
red_color = pygame.Color("red")
"White Square"
white_x = 400
white_y = 300
white_width = 10
white_height = 10
white_color = pygame.Color("white")
white = pygame.Rect(white_x, white_y, white_width, white_height)
"Red Squares"
def create_red_square(x, y):
red_width = 10
red_height = 10
red = pygame.Rect(x, y, red_width, red_height)
return red
while True:
clock.tick(60)
gameDisplay.fill((0, 20, 5))
gameDisplay.fill(white_color, white)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
for each in red_square_list:
gameDisplay.fill(red_color, each)
pygame.display.update()
'''White Square Movement'''
keys = pygame.key.get_pressed()
if keys[K_LEFT]:
white.left = white.left - 4
if keys[K_RIGHT]:
white.right = white.right + 4
if keys[K_UP]:
white.top = white.top - 4
if keys[K_DOWN]:
white.bottom = white.bottom + 4
"when Space key Pressed, Spawns red Squares"
if keys[K_SPACE]:
x = randint(0, gameDisplay_width)
y = randint(0, gameDisplay_height)
red_square_list.append(create_red_square(x, y))
With your current system, as long as Space is being held down, a red square will be added to the list. This means that a square will be placed every FRAME the button is being pressed. Too much! What you want to do is add the following into your event loop. This will activate ON the frame that you press the key, not any more than that.
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
x = randint(0, gameDisplay_width)
y = randint(0, gameDisplay_height)
red_square_list.append(create_red_square(x, y))
I'm a new programmer working on a memory game for my computer science summative.The game goes like this: the computer displays random boxes at random positions and then the user has to guess where the boxes are and click on it.
I'm basically done, except right now I'm trying to create 5 different levels that range in level of difficulty. eg level 1 will display 2 boxes and level 2 will display 5, etc. And then if the user gets through all levels they can play again. I know its a lot but I really want to get an A on this.
But right now I'm stuck because it doesn't really work until I try to close the window, and even then it only goes halfway. Any help would be appreciated.
import pygame , sys
import random
import time
size=[500,500]
pygame.init()
screen=pygame.display.set_mode(size)
# Colours
LIME = (0,255,0)
RED = (255, 0, 0)
BLACK = (0,0,0)
PINK = (255,102,178)
SALMON = (255,192,203)
WHITE = (255,255,255)
LIGHT_PINK = (255, 181, 197)
SKY_BLUE = (176, 226, 255)
screen.fill(BLACK)
# Width and Height of game box
width=50
height=50
# Margin between each cell
margin = 5
rows = 20
columns = 20
# Set title of screen
pygame.display.set_caption("Spatial Recall")
# Used to manage how fast the screen updates
clock=pygame.time.Clock()
coord=[]
# Create a 2 dimensional array. A two dimesional
# array is simply a list of lists.
def resetGrid():
grid = []
for row in range(rows):
# Add an empty array that will hold each cell
# in this row
grid.append([])
for column in range(columns):
grid[row].append(0) # Append a cell
return grid
def displayAllPink(pygame):
for row in range(rows):
for column in range(columns):
color = LIGHT_PINK
pygame.draw.rect(screen,color,[(margin+width)*column + margin,(margin+height)*row+margin,width,height])
pygame.display.flip()
def displayOtherColor(pygame,grid):
coord = []
for i in range(random.randint(2,5)):
x = random.randint(2, rows-1)
y = random.randint(2, columns-1)
color = LIME
pygame.draw.rect(screen,color,[(margin+width)*y + margin,(margin+height)*x+margin,width,height])
coord.append((x,y))
grid[x][y] = 1
pygame.display.flip()
time.sleep(1)
return coord
def runGame(gameCount,coord,pygame,grid):
pygame.event.clear()
pygame.display.set_caption("Spatial Recall: Level "+ str(gameCount))
pygame.time.set_timer(pygame.USEREVENT,1000)
time = 0
#clock.tick(
# -------- Main Program Loop -----------
#Loop until the user clicks the close button.
done = False
while done==False:
event = pygame.event.wait() # User did something
if event.type == pygame.QUIT: # If user clicked close
done=True # Flag that we are done so we exit this loop
pygame.event.clear()
print "Game ",gameCount, "ends"
elif event.type == pygame.USEREVENT:
time = time + 1
pygame.display.set_caption("Spatial Recall: Level "+ str(gameCount) + " Time: "+ str(time))
if time == 100:
done = True
pygame.display.set_caption("Time out, moving to next level")
pygame.event.clear()
return False
elif event.type == pygame.MOUSEBUTTONDOWN:
# User clicks the mouse. Get the position
pos = pygame.mouse.get_pos()
# Change the x/y screen coordinates to grid coordinates
column=pos[0] // (width+margin)
row=pos[1] // (height+margin)
if (row,column) in coord:
print coord
coord.remove((row,column))
print coord
color = LIME
pygame.draw.rect(screen,color,[(margin+width)*column + margin,(margin+height)*row+margin,width,height])
if coord == []:
done=True
pygame.display.set_caption("Time out, moving to next level")
pygame.event.clear()
return True
else:
color = RED
pygame.draw.rect(screen,color,[(margin+width)*column + margin,(margin+height)*row+margin,width,height])
pygame.display.flip()
def startTheGame(gameCount):
grid = resetGrid()
displayAllPink(pygame)
coord = displayOtherColor(pygame,grid)
displayAllPink(pygame)
runGame(gameCount,coord,pygame,grid)
for i in range(2):
startTheGame(i+1)
pygame.quit ()
You may want to use the pygame.font module. http://pygame.org/docs/ref/font.html
First, load a font, either from a file or from one of the system font functions.
Call YourFontObject.render(your_text_string). That'll return a Surface that contains the string rendered in the given font. Note, you can't use newline (\n) characters! You'll have to do the spacing yourself.
Blit this Surface onto the screen after everything else so nothing will obscure it.
Also, you don't need the pygame parameter in your functions.
Hope this helps.
I'm a new programmer working on a memory game for my computer science summative.The game goes like this: the computer displays random boxes at random positions and then the user has to guess where the boxes are and click on it.
I'm basically done, except right now I'm trying to create like 5 different levels that range in level of difficulty. eg level 1 will display like 2 boxes and level 2 will display like 5, etc. And then if the user gets through all levels they can play again. I know its a lot but I really want to get an A on this.
But right now I'm stuck because it doesnt really work until I try to close the window, and even then it only goes halfway. I'm thinking its how I defined the functions but I'm not to certain.
Any help would be appreciated.
import pygame , sys
import random
import time
size=[500,500]
pygame.init()
screen=pygame.display.set_mode(size)
# Colours
LIME = (0,255,0)
RED = (255, 0, 0)
BLACK = (0,0,0)
PINK = (255,102,178)
SALMON = (255,192,203)
WHITE = (255,255,255)
LIGHT_PINK = (255, 181, 197)
SKY_BLUE = (176, 226, 255)
screen.fill(BLACK)
# Width and Height of game box
width=50
height=50
# Margin between each cell
margin = 5
rows = 20
columns = 20
# Set title of screen
pygame.display.set_caption("Spatial Recall")
# Used to manage how fast the screen updates
clock=pygame.time.Clock()
coord=[]
# Create a 2 dimensional array. A two dimesional
# array is simply a list of lists.
def resetGrid():
grid = []
for row in range(rows):
# Add an empty array that will hold each cell
# in this row
grid.append([])
for column in range(columns):
grid[row].append(0) # Append a cell
return grid
def displayAllPink(pygame):
for row in range(rows):
for column in range(columns):
color = LIGHT_PINK
pygame.draw.rect(screen,color,[(margin+width)*column + margin,(margin+height)*row+margin,width,height])
pygame.display.flip()
def displayOtherColor(pygame,grid):
coord = []
for i in range(random.randint(2,5)):
x = random.randint(2, rows-1)
y = random.randint(2, columns-1)
color = LIME
pygame.draw.rect(screen,color,[(margin+width)*y + margin,(margin+height)*x+margin,width,height])
coord.append((x,y))
grid[x][y] = 1
pygame.display.flip()
time.sleep(1)
return coord
def runGame(gameCount,coord,pygame,grid):
pygame.event.clear()
pygame.display.set_caption("Spatial Recall: Level "+ str(gameCount))
pygame.time.set_timer(pygame.USEREVENT,1000)
time = 0
#clock.tick(
# -------- Main Program Loop -----------
#Loop until the user clicks the close button.
done = False
while done==False:
event = pygame.event.wait() # User did something
if event.type == pygame.QUIT: # If user clicked close
done=True # Flag that we are done so we exit this loop
pygame.event.clear()
print "Game ",gameCount, "ends"
elif event.type == pygame.USEREVENT:
time = time + 1
pygame.display.set_caption("Spatial Recall: Level "+ str(gameCount) + " Time: "+ str(time))
if time == 100:
done = True
pygame.display.set_caption("Time out, moving to next level")
pygame.event.clear()
return False
elif event.type == pygame.MOUSEBUTTONDOWN:
# User clicks the mouse. Get the position
pos = pygame.mouse.get_pos()
# Change the x/y screen coordinates to grid coordinates
column=pos[0] // (width+margin)
row=pos[1] // (height+margin)
if (row,column) in coord:
print coord
coord.remove((row,column))
print coord
color = LIME
pygame.draw.rect(screen,color,[(margin+width)*column + margin,(margin+height)*row+margin,width,height])
if coord == []:
done=True
pygame.display.set_caption("Time out, moving to next level")
pygame.event.clear()
return True
else:
color = RED
pygame.draw.rect(screen,color,[(margin+width)*column + margin,(margin+height)*row+margin,width,height])
pygame.display.flip()
def startTheGame(gameCount):
grid = resetGrid()
displayAllPink(pygame)
coord = displayOtherColor(pygame,grid)
displayAllPink(pygame)
runGame(gameCount,coord,pygame,grid)
for i in range(2):
startTheGame(i+1)
pygame.quit ()
the main problem why it is not working at the moment is:
your globals rows and columns are set to 20 but your board has only 9 fields, this is why most randomly selected coords are off the board
then, you do not control that the same coord is chosen 2 times.
in general, I would advise choosing better names, especially for displayOtherColor which assembles your target coordinates for each level.
for your question how to display score, I would propose setting it as caption, as you are already doing with the running time.