Threading issue with Pygame - python

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

Related

How to break out of an infinite loop while the program is running in python

I was making something in python that I am not smart enough to make, and I accidentally created an infinite loop, and I can't end it because I am using pygame, so it made a new window and I can't close it. I tried Ctrl+c and closing the lid of my laptop, is there any way other than restarting, because that will be annoying to do every time.
(No title)
import pygame
# initialize variables
width = 1366
height = 704
display_surface = pygame.display.set_mode((width, height))
screen = pygame.display.set_mode((width, height))
# this is the block type list
items = [
# building blocks
["grass", "dirt", "stone", "ore", "chest", "item collector", "block placer", "item dropper"],
# technical blocks
["wires", "sensor", "AND gate", "OR gate", "NOT gate", "NOR gate", "XOR gate", "XNOR gate", "NAND gate", "gearbox", "gear - 24 tooth", "gear - 8 tooth", "item pipe", "filter pipe", "delete pipe", "motor", "joint", "bearing", "blueprints", "spring"],
]
# initiallize pygame sttuff
pygame.init()
# begining of program
import pygame
def init_screen_and_clock():
global screen, display, clock
pygame.init()
pygame.display.set_caption('Game')
clock = pygame.time.Clock()
def create_fonts(font_sizes_list):
"Creates different fonts with one list"
fonts = []
for size in font_sizes_list:
fonts.append(
pygame.font.SysFont("Arial", size))
return fonts
def render(fnt, what, color, where):
"Renders the fonts as passed from display_fps"
text_to_show = fnt.render(what, 0, pygame.Color(color))
screen.blit(text_to_show, where)
def display_fps():
"Data that will be rendered and blitted in _display"
render(
fonts[0],
what=str(int(clock.get_fps())),
color="white",
where=(0, 0))
init_screen_and_clock()
# This create different font size in one line
fonts = create_fonts([32, 16, 14, 8])
loop = 1
while True:
screen.fill((0, 0, 0))
display_fps()
for event in pygame.event.get():
if event.type == pygame.QUIT:
loop = 0
clock.tick(60)
pygame.display.flip()
pygame.quit()
print("Game over")
The issue is that you're setting loop to exit/not, but the code is not testing loop, it's just testing True... which unsurprisingly always evaluates to True.
loop = 1
while True: # <<-- HERE
screen.fill((0, 0, 0))
display_fps()
for event in pygame.event.get():
if event.type == pygame.QUIT:
loop = 0
clock.tick(60)
pygame.display.flip()
If you simply change this to test loop it will work ok:
loop = 1
while ( loop == 1 ): # <<-- HERE
screen.fill((0, 0, 0))
display_fps()
for event in pygame.event.get():
if event.type == pygame.QUIT:
loop = 0
clock.tick(60)
pygame.display.flip()
I laboured the syntax here to show exactly what's going on. You could also get away with while loop:. But less code isn't always better.

ZX81 BASIC to Pygame Conversion of "Dropout" Game

I based the code below on this article: http://kevman3d.blogspot.com/2015/07/basic-games-in-python-1982-would-be.html
and on the ZX BASIC in this image:
10 LET P=0
20 LET T=P
30 FOR Z=1 T0 10
35 CLS
37 PRINT AT 12,0;T
40 LET R=INT (RND*17)
50 FOR Y=0 TO 10
60 PRINT AT Y,R;"O"
70 LET N=P(INKEY$="4")-(INKEY$="1")
80 IF N<0 OR N>15 THEN LET N=P
100 PRINT AT 11,P;" ";AT 11,N;"┗┛";AT Y,R;" "
110 LET P=N
120 NEXT Y
130 LET T=T+(P=R OR P+1=R)
150 NEXT Z
160 PRINT AT 12,0;"YOU SCORED ";T;"/10"
170 PAUSE 4E4
180 RUN
I also shared it on Code Review Stack Exchange, and got a very helpful response refactoring it into high quality Python code complete with type hints.
However, for my purposes I'm wanting to keep the level of knowledge required to make this work a little less advanced, including avoiding the use of OOP. I basically want to maintain the "spirit of ZX BASIC" but make the code "not awful." The use of functions is fine, as we were allowed GOSUB back in the day.
I'm pretty dubious about the approach of using nested FOR loops inside the main game loop to make the game work, but at the same time I'm curious to see how well the BASIC paradigm maps onto the more event driven approach of Pygame, so I'd welcome any comments on the pros and cons of this approach.
More specifically,
Is there somewhere I can put the exit code if event.type == pygame.QUIT where it will work during game rounds, without having to repeat the code elsewhere?
How would this game be implemented if I were to avoid the use of FOR loops / nested FOR loops?
Are there any points of best practice for pygame/Python which I have violated?
What improvements can you suggest, bearing in mind my purpose is to write good Pygame code while maintaining the "spirit" of the ZX81 games?
Any input much appreciated. I'm also curious to see a full listing implementing some of the ideas arising from my initial attempt if anyone is willing to provide one.
import pygame
import random
import sys
# Define colors and other global constants
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
TEXT_SIZE = 16
SCREEN_SIZE = (16 * TEXT_SIZE, 13 * TEXT_SIZE)
NUM_ROUNDS = 5
def print_at_pos(row_num, col_num, item):
"""Blits text to row, col position."""
screen.blit(item, (col_num * TEXT_SIZE, row_num * TEXT_SIZE))
# Set up stuff
pygame.init()
screen = pygame.display.set_mode(SCREEN_SIZE)
pygame.display.set_caption("Dropout")
game_font = pygame.font.SysFont('consolas', TEXT_SIZE)
# Create clock to manage how fast the screen updates
clock = pygame.time.Clock()
# initialize some game variables
player_pos, new_player_pos, coin_row, score = 0, 0, 0, 0
# -------- Main Program Loop -----------
while True:
score = 0
# Each value of i represents 1 round
for i in range(NUM_ROUNDS):
coin_col = random.randint(0, 15)
# Each value of j represents one step in the coin's fall
for j in range(11):
pygame.event.get()
pressed = pygame.key.get_pressed()
if pressed[pygame.K_RIGHT]:
new_player_pos = player_pos + 1
elif pressed[pygame.K_LEFT]:
new_player_pos = player_pos - 1
if new_player_pos < 0 or new_player_pos > 15:
new_player_pos = player_pos
# --- Game logic
player_pos = new_player_pos
coin_row = j
if player_pos + 1 == coin_col and j == 10:
score += 1
# --- Drawing code
# First clear screen
screen.fill(WHITE)
player_icon = game_font.render("|__|", True, BLACK, WHITE)
print_at_pos(10, new_player_pos, player_icon)
coin_text = game_font.render("O", True, BLACK, WHITE)
print_at_pos(coin_row, coin_col, coin_text)
score_text = game_font.render(f"SCORE: {score}", True, BLACK, WHITE)
print_at_pos(12, 0, score_text)
# --- Update the screen.
pygame.display.flip()
# --- Limit to 6 frames/sec maximum. Adjust to taste.
clock.tick(8)
msg_text = game_font.render("PRESS ANY KEY TO PLAY AGAIN", True, BLACK, WHITE)
print_at_pos(5, 0, msg_text)
pygame.display.flip()
waiting = True
while waiting:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit(0)
if event.type == pygame.KEYDOWN:
waiting = False
Here's my reorganisation of your code:
import pygame
import random
# Define global constants
TEXT_SIZE = 16
SCREEN_SIZE = (16 * TEXT_SIZE, 13 * TEXT_SIZE)
NUM_ROUNDS = 5
def print_at_pos(row_num, col_num, item):
"""Blits text to row, col position."""
screen.blit(item, (col_num * TEXT_SIZE, row_num * TEXT_SIZE))
# Set up stuff
pygame.init()
screen = pygame.display.set_mode(SCREEN_SIZE)
pygame.display.set_caption("Dropout")
game_font = pygame.font.SysFont("consolas", TEXT_SIZE)
# Create clock to manage how fast the screen updates
clock = pygame.time.Clock()
# draw the images
player_icon = game_font.render("|__|", True, "black", "white")
# if we don't specify a background color, it'll be transparent
coin_text = game_font.render("O", True, "black")
msg_text = game_font.render("PRESS ANY KEY TO PLAY AGAIN", True, "black", "white")
# initialize some game variables
waiting = False # start in game
player_pos = 0
score = 0
game_round = 0
coin_row = 0
coin_col = random.randint(0, 15)
running = True # For program exit
# -------- Main Program Loop -----------
while running:
# event handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if waiting:
waiting = False
score = 0 # reset score
elif event.key == pygame.K_LEFT:
player_pos -= 1
elif event.key == pygame.K_RIGHT:
player_pos += 1
# --- Game logic
if waiting:
# don't update the game state or redraw screen
print_at_pos(5, 0, msg_text)
else:
coin_row += 1 # TODO: decouple from frame rate
if -1 > player_pos:
player_pos = -1 # so we can catch a coin at zero
elif 15 < player_pos:
player_pos = 15
# coin is in scoring position
if coin_row == 10:
if player_pos + 1 == coin_col:
score += 1
elif coin_row > 10: # round is over
coin_col = random.randint(0, 15)
coin_row = 0
game_round+= 1
if game_round >= NUM_ROUNDS:
waiting = True
game_round = 0 # reset round counter
# --- Drawing code
screen.fill("white") # clear screen
print_at_pos(10, player_pos, player_icon)
print_at_pos(coin_row, coin_col, coin_text)
score_text = game_font.render(f"SCORE: {score}", True, "black", "white")
print_at_pos(12, 0, score_text)
# --- Update the screen.
pygame.display.flip()
# --- Limit to 6 frames/sec maximum. Adjust to taste.
clock.tick(6)
pygame.quit()
I've used a boolean waiting to allow for common event and game state handling that only moves during gameplay. For more complex interactions, you'll want a state machine.
The coin movement is currently coupled to the frame rate, which is easy, but ideally you'd specify a rate/time interval, e.g. 200ms between row drops and then you could have a refresh rate similar to the monitor refresh rate.

How do you make the string appear after hitting the return key

I am creating a flashcard game for my kid. Its about Dinos. I am having trouble making "Congrats, You got it right" appear on the screen. I have moved my code all over the place but no luck. Can someone please help me out.
To be clear, What I want to happen is when the user presses the number 1,2,3 on the keypad, and if the key is the correct answer that correlates to the question, the message "Congrats, You got it right!" should appear on the screen.
I know the keydown event right now is the return key, but I did that for testing purposes only. This is also the same for testtext variable. I was using that variable to see if I could print "Hello WOrld" to the screen.
I do have a feeling it has something to do with the loop that is running. My guess would be is that it does show up for a fraction of a second but disappears before anyone can see it.
import pygame, random
pygame.font.init()
pygame.init()
font = pygame.font.Font(None, 48)
#Created the window display
size = width, height = 800,800
screen = pygame.display.set_mode(size)
#Loads the images of the starting game Trex
#t_rex = pygame.image.load('trex1.png')
##Places the image on the screen
#screen.blit(t_rex,(150,50))
count = 0
score = 0
active = False
testtext = font.render("Hello WOrld", True, (250, 250, 250))
#The below code keeps the display window open until user decides to quie app
crashed = False
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
if event.type==pygame.KEYDOWN:
if event.key==pygame.K_RETURN:
screen.blit(testtext, (200,699))
while count < 2:
screen.fill(0)
dinoQuestions = ["Does a t-rex eat meat?\n","Does a trycerotopes have 3 horns?\n"]
dinoAnswer = ["Yes\n", "No\n","Maybe\n"]
wordnum = random.randint(0, len(dinoQuestions)-1)
mainpic = pygame.image.load("trex1.png")
screen.blit(mainpic, (150, 20))
options = [random.randint(0, len(dinoAnswer)-1),random.randint(0, len(dinoAnswer)-1)]
options[random.randint(0,1)] = wordnum
question_display = font.render(dinoQuestions[wordnum].rstrip('\n'),True, (255, 255, 255))
text1 = font.render('1 - ' + dinoAnswer[options[0]].rstrip('\n'),True, (255, 255, 255))
text2 = font.render('2 - ' + dinoAnswer[options[1]].rstrip('\n'),True, (255, 255, 255))
#the below code is for testing purposes only
screen.blit(question_display,(200, 590))
screen.blit(text1, (200, 640))
screen.blit(text2, (200, 690))
count = count + 1
pygame.display.flip()
The blit to your screen surface you perform when handling a Return key down event is overwritten when you later call screen.fill(0).
I've rearranged your code a little and added displaying a result on appropriate key press.
import pygame
import random
pygame.init()
pygame.font.init()
font = pygame.font.Font(None, 48)
size = width, height = 800,800
screen = pygame.display.set_mode(size) #Created the window display
count = 0
score = 0
active = False
white = pygame.color.Color("white")
black = pygame.color.Color("black")
green = pygame.color.Color("green")
# load/create static resources once
mainpic = pygame.image.load("trex1.png")
testtext = font.render("Hello World", True, (250, 250, 250))
correct_text = font.render("Correct! Well Done!", True, green)
clock = pygame.time.Clock() # for limiting FPS
dinoQuestions = ["Does a t-rex eat meat?","Does a triceratops have 3 horns?"]
dinoAnswer = ["Yes", "No","Maybe"]
# initialise state
show_hello = False
show_correct = False
update_questions = True # need to update questions on the first iteration
finished = False
while not finished:
for event in pygame.event.get():
if event.type == pygame.QUIT:
finished = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
show_hello = not show_hello # toggle flag for later display
elif event.key == pygame.K_SPACE:
update_questions = True
elif event.key in [pygame.K_1, pygame.K_2]:
# an answer has been selected
# pygame.K_1 is 0, pygame.K_2 is 1
if dinoAnswer[event.key - pygame.K_1] == "Yes":
show_correct = True
count += 1
else:
show_correct = False
screen.fill(black)
screen.blit(mainpic, (150, 20))
if show_hello:
screen.blit(testtext, (200,199))
if show_correct:
screen.blit(correct_text, (200, 300))
if update_questions:
random.shuffle(dinoQuestions)
random.shuffle(dinoAnswer)
question_display = font.render(dinoQuestions[0],True, white)
text1 = font.render('1 - ' + dinoAnswer[0],True, white)
text2 = font.render('2 - ' + dinoAnswer[1],True, white)
update_questions = False
show_correct = False
# Display the Question
screen.blit(question_display,(200, 590))
screen.blit(text1, (200, 640))
screen.blit(text2, (200, 690))
# count = count + 1
pygame.display.flip()
clock.tick(60)
Hopefully this is enough of a framework for you to extend.
Let me know if you have any questions about any portions of the code.
I am a bit confused about what your exact problem is, so I'm going to try to answer. You say that you want the words "Congrats, , you got it right!", so I can help you with what went wrong. You blit the testtext before you color the screen, so each time the loop loops, it displays the testtext but then almost instantly covers it up with screen.fill(0). To make it better, you should put the blitting of the text after the screen is colored. The best way to do this is to put it right at the start of the loop, or making another event detector after the current position of the screen.fill in the code.
Also, I would get rid of the stacked while loop, and instead replace it with if statement because it is already in the while loop.
Is this what you were looking for?

Pygame: Drawing Lines

In my previous question For Loop Functions in Python,
I had trouble with putting functions that contained a command to draw a line for a hangman game. It didn't exactly draw the line, and I first suspected it was a problem with the for loop or the functions. Now I realize there is somewhat a glitch with Pygame.
I have tried solving the problem by using this code in the country, CANADA:
b2 = font.render(str(letters[1]), True, (red))
screen.blit(b2, (bPosition))
if hangman1x == -500 and hangman1y == -500:
hangman1x = (775, 250)
hangman1y = (775, 50)
pygame.draw.line(screen, black, (hangman1x), (hangman1y), (5))
pygame.display.flip()
time.sleep(0.5)
bPosition = -500, -500
b1.x, b1.y = -500, -500
if hangman1x == (775, 250) and hangman1y == (775, 50):
print 'hi'
width = 6
pygame.draw.line(screen, black, (hangman1x), (hangman1y), (5))
print 'yay'
pygame.display.flip()
Now here's the weird thing.
When you press the B blitted onto the screen, it turns red, like its meant to, draws the line perfectly fine, but disappears, when the B disappears, and I understand why. After that, I added that extra if code. (Notice that both pygame.draw.line(s) are the same), It prints hi and yay in the shell, but it does not keep the line. Anyway to solve this?
After you are calling pygame.draw.line() you are probably redrawing your screen completely white, this will draw over the line and hide it. Instead of drawing lines like you are, I would build a hangman class draw from that
class Hangman():
def __init__(self):
self.lines = 0 #Number of lines to be drawn
def draw(self,screen):
#TODO draw to screen based on self.lines
#More code setting up pygame
drawlist = []
myMan = Hangman()
drawlist.append(myMan)
#mainloop
while 1:
screen.fill('#000000')
for item in drawlist:
item.draw(screen)
This way you are redrawing you hangman every frame, and thus he is always being showed
EDIT Added a running example
#!/usr/bin/python
import pygame
pygame.init()
class Hangman():
def __init__(self):
self.lines = 0 #Number of lines to be drawn
def hang(self):
self.lines += 1
def draw(self,screen):
for x in range(self.lines):
coord1 = (x*10,20)
coord2 = (x*10,50)
pygame.draw.line(screen,(0,0,0),coord1,coord2)
size = screenWidth,screenHeight = 200,70
screen = pygame.display.set_mode(size)
pygame.display.flip()
myman = Hangman()
drawlist = []
drawlist.append(myman)
#mainloop
running = True
while running:
#EVENT HANDLING#
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == 32: #Spacebar
myman.hang()
#DRAWING#
screen.fill((255,255,255))
for item in drawlist:
item.draw(screen)
pygame.display.flip()

Pygame text input not on screen

I need to kb input onto a pygame screen
at the moment it appears on the idle shell
any advice would be appreciated.
This code is extracted from a larger program
mostly screen based but i need to input some
data (numeric) from the kb at times
import sys
import pygame
from pygame.locals import *
pygame.init()
N= ''
screen = pygame.display.set_mode((600,600))
font= pygame.font.Font(None,40)
screen.fill((255,255,255))
pygame.display.flip
pygame.display.update()
def score(C,y):
SetWnd = font.render( C,True,(0,0,255))
screen.blit(SetWnd, (15, 100+y))
pygame.display.update()
def start():
while True:
name=''
for evt in pygame.event.get():
if evt.type == KEYDOWN:
if evt.unicode.isalnum(): # unicode
name+=evt.unicode
print name,
elif evt.key == K_BACKSPACE:
name = name[:-1]
print name,
elif evt.key == K_RETURN:
return N
elif evt.type == QUIT:
pygame.quit()
sys.exit()
def Pchange(c,y):
block = font.render(N, True, (0,0,0))
rect = block.get_rect()
rect.move_ip(75,100 + y)
screen.blit(block,rect)
pygame.display.flip()
score('wind', 0)
score('elev',20)
N = start()
Pchange(N,0)
Pchange(N,20)
Firstly you draw the score twice, which i assume works well.
The problem lies in you start function.
You are not calling any draw or update function in your while loop.
In your event foreach, you add a digit to name, and exit the while loop when enter is pressed. Then you draw twice with Pchange, but you are the function does not use the right parameters. You have:
def Pchange(c,y):
block = font.render(N, True, (0,0,0))
you are using the global N which is ''. So to fix that, you need to change N to c.
The next problem is that the game quits right after pressing enter. Since you pasted only a part of the program, this might not be the case. If it is, make another while loop, and just wait for the ESC key to call pygame.quit() and sys.exit()

Categories

Resources