[Tutor] pygame blinking text
Lie Ryan
lie.1296 at gmail.com
Mon Dec 12 22:45:06 CET 2011
On 12/13/2011 01:01 AM, Cranky Frankie wrote:
> I tried putting the ty_message block in a WHILE TRUE loop, and that
> didn't work. Then I tried the same with the
> games.screen.add(ty_message) line and that didn't work either. I think
> what might work is if I can find a way to delete the ty_message and
> readd it, over and over in a loop with a delay, bu:
This is a common problem when people start GUI/graphics programming;
once you enter the GUI mainloop, you're no longer in control of the
program flow. Instead the mainloop will process events and callbacks;
therefore if you want a blinking text, you had to arrange such that your
blinker function will be called every second.
In pygame, you can do the following:
#!/usr/bin/env python
import pygame
# initialize pygame, this must be called before
# doing anything with pygame
pygame.init()
# create a screen
screen = pygame.display.set_mode((400, 400))
# setup the text
font = pygame.font.Font(None, 36)
text = font.render("Hello World", True, (100, 100, 100))
display = True
# the main loop
while pygame.time.get_ticks() < 10000: # run the program for 10 seconds
# empty the screen
screen.fill((255, 255, 255))
display = not display
# draw the text to the screen only if display is True
if display:
screen.blit(text, (100, 100))
# update the actual screen
pygame.display.flip()
# wait for half second
pygame.time.wait(500)
You can do this in pygame since pygame do not provide a mainloop.
I took a quick glance at livewires, their main loop implementation is
very simple; however it discards all events except for mouse, keyboard,
and the quit event. In typical game engine, you usually will register an
event to the event handler to be executed every second that will
draw/undraw the text. However, in livewires event handling system you
can't do that. Therefore, if you want to do it, you'd have to override
the event handling method in the Screen class.
However, for a quick hack, I think you can abuse the after_death=
parameter; you can register a function that will games.screen.add() a
Message, then after_death, it registers an invisible message which
registers a Message after its death which registers the visible message
after death which ... . In short, the following (I haven't tested it,
although I think it should work):
stop = False
def add_visible_ty():
if stop: return
message = games.Message(
value = "Thank You!",
size = 100,
color = color.red,
x = games.screen.width/2,
y = games.screen.height/2,
lifetime = 500,
after_death = add_invisible_ty
)
games.screen.add(message)
def add_invisible_ty():
if stop: return
message = games.Message(
value = "",
size = 100,
color = color.red,
x = games.screen.width/2,
y = games.screen.height/2,
lifetime = 500,
after_death = add_visible_ty
)
games.screen.add(message)
> games.screen.delete(ty_message)
>
> doesn't work - delete is not a valid method.
There are two rendering style for graphics programming; one is called
the "retained mode", in which the libraries retain a complete model of
the objects to be rendered and graphic calls do not directly cause
actual rendering but instead update an internal model, the other is the
"immediate mode" in which graphic calls directly cause rendering of
graphics objects to the display.
pygame falls into the latter; pygame do not keep track of objects that
it has drawn on screen, therefore if you need to "delete" an object from
the screen, you'd need to redraw the whole screen except the object you
had deleted. At the very least, you'd need to redraw the part of the
screen that had changed due to the deletion.
livewires falls into the former; in livewires there is an internal
object that represent each screen object and it keep tracks of which
objects and which part of the screen that are "dirty".
More information about the Tutor
mailing list