Wednesday, 16 January 2013

Interactive Graphics


Interactive Graphics

In Example 33, we learn how to move a single black point, leaving
traces, on a white background (someone might call this a pen), as shown
in Figure 5.6. This example combines earlier lessons learnt, namely
drawing graphics primitives and handling keyboard events.


Example 33: Moving graphics
import appuifw, graphics, e32, key_codes
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
key_down = None
clicked = None
def handle_event(event):
global clicked, key_down
if event['type'] == appuifw.EEventKey:
if key_down:
key_down = (event['keycode'], "down")
else:
key_down = (event['keycode'], "pressed")
elif event['type'] == appuifw.EEventKeyUp and key_down:
code, mode = key_down
if mode == "pressed":
clicked = code
key_down = None
def key_is_down(code):
if key_down and key_down == (code, "down"):
return True
return False
def quit():
global running
running = False
def handle_redraw(rect):
if img:
canvas.blit(img)
img = None
canvas = appuifw.Canvas(event_callback = handle_event,
redraw_callback = handle_redraw)
appuifw.app.screen = "full"
appuifw.app.body = canvas
appuifw.app.exit_key_handler = quit
x = y = 100
w, h = canvas.size
img = graphics.Image.new((w, h))
img.clear(WHITE)
running = True
while running:
if key_is_down(key_codes.EKeyLeftArrow): x -= 5
elif key_is_down(key_codes.EKeyRightArrow): x += 5
elif key_is_down(key_codes.EKeyDownArrow): y += 5
elif key_is_down(key_codes.EKeyUpArrow): y -= 5
#img.clear(WHITE)

img.point((x, y), outline = BLACK, width = 50)
handle_redraw(None)
e32.ao_yield()


The functions handle event() and key is down() are familiar
from Example 30. Again, we create a separate image, img, on which the
dot is first drawn and then the whole image is copied onto the canvas
in handle redraw().
The dot is moved with the arrow keys. Depending on which arrow is
held down, we move the dot’s location the corresponding direction in x
and y coordinates. Here the dot is moved 5 pixels at time, but you can
experiment with different values.
The e32.ao yield() at the end of the loop makes sure that the
system leaves some time to register the keyboard events, as drawing in
the tight loop consumes lots of CPU power and might make the system
unresponsive.
Actually, since we move the dot only when the user presses a key, we
could have used the approach of Example 28 to handle the key events.
In this case, we would not need the busy loop at the end, which would
mean less computing and savings in precious battery time. However, this
example should prepare you for Example 39, where the loop is actually
necessary.
One line, img.clear(WHITE), is preceded by the hash mark (#)
which means that the line is a comment and is ignored by the PyS60
interpreter. If you remove the hash mark, the line is executed and the dot
does not leave any traces. Note, however, that clearing the whole image
because the dot has moved one step forward is unnecessarily expensive.
A better, but less straightforward, approach for clearing traces would be
to draw a small white rectangle on top of the old dot before drawing the
new dot.






No comments:

Post a Comment