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.

Figure 5.6 Moving dot with its trace

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)

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(WHlTE), 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.

5.3.7 3D Graphics

Python for S60 provides support for 3D graphics by way of the modules gles and glcanvas. The gles module contains Python bindings to the OpenGL ES 2D and 3D graphics API. The glcanvas module provides an object for displaying the 3D graphics, in the same way as the Canvas object is used to display 2D graphics.

Making 3D graphics with OpenGL is somewhat complicated. Fortunately, several good books and free tutorials have been written about the subject. Thus, we do not go into details here. A good starting point is, for instance http://pyopengl.sourceforge.net, which explains a Python version of the OpenGL graphics. The Python for S60 version follows these conventions closely.

Python Interactive Opengl

Figure 5.7 OpenGL cube

hiii|

Figure 5.7 OpenGL cube

We provide a teaser for 3D graphics on this book's website. There you can find an example of a 3D cube, shown in Figure 5.7, which spins on the x, y and z axes simultaneously.

For using the built-in camera of an S60 phone, PyS60 offers a module named camera. We think that this is one of the most fun modules in PyS60, as it can give your programs a new view of the surrounding world.

Because of our enthusiasm for the camera module, this book includes seven examples that are based on taking photos. Being able to use the camera programmatically - even in the most esoteric ways - may change your relationship with camera phones in a profound manner. For instance, see Section 11.2 for a description of a large-scale urban photo hunt that was implemented using the camera module! The camera module includes three types of functions: to query features of the camera; to open and close the viewfinder; and to take photos.

Note that the camera consumes a lot of energy. If you have an application that uses the viewfinder or takes photos frequently, in many cases it is necessary to recharge the battery after four or five hours.

0 0

Post a comment

  • Receive news updates via email from this site