Reputation: 25
I'm trying to make my own version of OLDTV in Python, but I've run into a problem. I am making an effect where the text is bigger for a moment before going to a regular size. The problem that I am running up against is that the text does not display at all. I am running Anaconda 2.7 (installed in a previous project) with the Spyder editor that comes with, if that helps.
Code:
import pygame
from pygame.transform import scale
from random import randint
def make_font(fonts, size):
available = pygame.font.get_fonts()
# get_fonts() returns a list of lowercase spaceless font names
choices = map(lambda x:x.lower().replace(' ', ''), fonts)
for choice in choices:
if choice in available:
return pygame.font.SysFont(choice, size)
return pygame.font.Font(None, size)
_cached_fonts = {}
def get_font(font_preferences, size):
global _cached_fonts
key = str(font_preferences) + '|' + str(size)
font = _cached_fonts.get(key, None)
if font == None:
font = make_font(font_preferences, size)
_cached_fonts[key] = font
return font
_cached_text = {}
def create_text(text, fonts, size, color):
global _cached_text
key = '|'.join(map(str, (fonts, size, color, text)))
image = _cached_text.get(key, None)
if image == None:
font = get_font(fonts, size)
image = font.render(text, True, color)
_cached_text[key] = image
return image
pygame.init()
screen = pygame.display.set_mode((640, 480))
real = 0
guess = 0
score = 0
i = 0
gameRunning = False
runEnd = False
clock = pygame.time.Clock()
done = False
font_preferences = [
"Arial",
"Times New Roman",
"Papyrus",
"Comic Sans MS"]
def endRun(score):
global gameRunning
global runEnd
global i
screen.fill([255, 255, 255])
text = create_text(str(score), font_preferences, 72, (0, 0, 0))
screen.blit(text,
(320 - text.get_width() // 2, 240 - text.get_height() // 2))
gameRunning = False
runEnd = True
i = 0
def genNext():
screen.fill([255, 255, 255])
global real
gen = randint(1, 2)
if gen == 2:
ref = 0
else:
ref = 1
rand1 = randint(1, 6)
rand2 = randint(1, 6)
words = ["Red", "Orange", "Yellow", "Green", "Blue", "Purple"]
if ref == 1:
if rand1 == rand2:
real = 0
else:
real = 1
displayWord = words[rand1-1]
displayCol = rand2
elif ref == 0:
real = 0
displayWord = words[rand1-1]
displayCol = rand1
return ReturnValue(displayWord, displayCol)
def displayWordCol(word, col):
colVal = [(255, 0, 0), (255, 128, 0), (190, 190, 0), (0, 255, 0), (0, 0, 255), (128, 0, 255)]
for i in range(10, 5):
text = create_text(word, font_preferences, 72, colVal[col-1])
scale(text, (text.get_width() * i/5, text.get_height() * i/5))
screen.blit(text, (320 - text.get_width() // 2, 240 - text.get_height() // 2))
pygame.display.update()
clock.tick(60)
def checkNext(real, guess):
global score
if real == guess:
score = score + 1
e = genNext()
displayWordCol(e.y0, e.y1)
else:
endRun(score)
def homeScreen():
screen.fill(0)
text = create_text("OpenTV", font_preferences, 72, (100, 100, 100))
screen.blit(text,
(320 - text.get_width() // 2, 240 - text.get_height() // 2))
class ReturnValue:
def __init__(self, y0, y1):
self.y0 = y0
self.y1 = y1
homeScreen()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if gameRunning == True:
guess = 0
checkNext(real, guess)
elif event.button == 3:
if gameRunning == True:
guess = 1
checkNext(real, guess)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
if gameRunning == False:
gameRunning = True
score = 0
e = genNext()
displayWordCol(e.y0, e.y1)
if event.key == pygame.K_ESCAPE:
if gameRunning == True:
endRun(score)
elif gameRunning == False:
done = True
if runEnd:
i = i + 1
if i == 120:
homeScreen()
runEnd = False
pygame.display.flip()
clock.tick(60)
The part that is causing trouble is the displayWordCol function. Is there something wrong with my code, or should I switch to IDLE and paste in my code?
Upvotes: 2
Views: 175
Reputation: 147
I think the main problem is using scale() to scale rendered text. As far as I know, scale() is for images.
Try this as a mere example (you can adapt it to your needs afterwards).
def displayWordCol(word, col):
colVal = [(255, 0, 0), (255, 128, 0), (190, 190, 0), (0, 255, 0), (0, 0, 255), (128, 0, 255)]
for i in range(10):
text = create_text(word, font_preferences, int(72 *i/5), colVal[col-1])
#scale(text, (text.get_width() * i/5, text.get_height() * i/5))
screen.blit(text, (320 - text.get_width() // 2, 240 - text.get_height() // 2))
pygame.display.update()
clock.tick(60)
Another possible problem is that you might need to erase the screen before blitting the word in every loop cycle (not sure which effect you are looking for).
Finally, using pygame is almost always a good thing to use "dirty" rects, erasing and updating only the parts of the screen that have actually changed.
Regards!
EDIT: Try this as well. I added erasing the screen before blitting. I guess this effect is what you were looking for. I also added "dirty" rects management as an example.
def displayWordCol(word, col):
colVal = [(255, 0, 0), (255, 128, 0), (190, 190, 0), (0, 255, 0), (0, 0, 255), (128, 0, 255)]
regular_size = 72
cicles = 20
size_gap = 5
initial_size = regular_size + cicles * size_gap
text = create_text(word, font_preferences, int(initial_size), colVal[col - 1])
pos = (320, 240)
rect = pygame.Rect(pos[0] - text.get_width()/2, pos[1] - text.get_height()/2, text.get_width(), text.get_height())
screen.fill(pygame.Color("white"))
pygame.display.update()
for i in range(cicles):
text = create_text(word, font_preferences, int(initial_size - i*size_gap), colVal[col-1])
screen.fill(pygame.Color("white"), rect)
screen.blit(text, (pos[0] - text.get_width()/2, pos[1] - text.get_height()/2))
pygame.display.update(rect)
clock.tick(60))
Upvotes: 1