GNU PGE

Example Games

The example game source code can be found under pge-1.0/examples.

Each game corresponds to a sub directory under student-pge-1.0/lab. Currently there is source code for two complete games: breakout and matchsticks. The example frozenbubble is not implemented but added as an idea to guide future development of pge.

Overview of breakout

Here is a very basic version of upside down breakout. You can interfere with the gold ball by pressing the mouse left and right buttons. If the ball hits the triangles it gains a small amount of velocity. All other collisions are very slightly inelastic.

Interesting aspects of the breakout implementation

It uses timers to coordinate the time left and it uses event callbacks to handle mouse presses. Each blue box is deleted with a callback upon collision.

Overview of matchsticks

Here is a very basic game called matchsticks. The idea is to control the gold ball and hit the light wood boxes encapsulating the blue balls. If a blue ball hits the floor it is deleted. You need to make all blue balls disappear before you run out of time.

You can interfere with the gold ball by pressing the mouse left and right buttons. If the ball hits the triangles it gains a small amount of velocity. All other collisions are very slightly inelastic.

Interesting aspects of the matchsticks implementation

It uses timers to coordinate the time left and it uses event callbacks to handle mouse presses. The blue balls initially are free moving and they quickly change internally to the stationary state. Once they are hit or a matchstick is deleted all objects in the stationary state become free moving again.

Overview of frozenbubble

Here is a very basic game of frozebubble.

You control the initial projection vector of the gold ball from the mouse position. If the gold ball hits any other ball in a suspended state it becomes free moving.

Interesting aspects of the frozenbubble implmentation

This game uses the collision callbacks to resume movement for a suspended ball.

Ideas on how to extend PGE

If you are a second year student at the University of South Wales you should skip this section.

Here are a list of possible extensions to pge which might be useful.

Implementing per object gravity and rotation about the centre of gravity would allow frozen bubble to be completed using PGE.

Breakout source code

Here is the declaration section of breakout code.

#!/usr/bin/env python

import pge, sys, time
from pygame.locals import *

print "starting breakout"
pge.interactive ()
pge.record ()

wood_light = pge.rgb (166.0/256.0, 124.0/256.0, 54.0/256.0)
wood_dark = pge.rgb (76.0/256.0, 47.0/256.0, 0.0)
red = pge.rgb (1.0, 0.0, 0.0)
green = pge.rgb (0.0, 1.0, 0.0)
blue = pge.rgb (0.0, 0.0, 1.0)

dark_red = pge.rgb (166.0/255.0, 25.0/255.0, 50.0/255.0)
dark_green = pge.rgb (25.0/255.0, 100.0/255.0, 50.0/255.0)
dark_blue = pge.rgb (25.0/255.0, 50.0/255.0, 150.0/255.0)

steel = pge.rgb (0.5, 0.5, 0.5)
copper = pge.rgb (0.5, 0.3, 0.2)
gold = pge.rgb (0.8, 0.6, 0.15)
ball_size = 0.02
boarder = 0.01
white = pge.rgb (1.0, 1.0, 1.0)
gap = 0.01
blocks = []
winner = False
loser = False
seconds_left = None
previous = None
slowdown = 6

The callback functions.

def finish_game ():
    sys.exit (0)


def myquit (e):
    print "goodbye"
    finish_game ()


def key_pressed (e):
    if e.key == K_ESCAPE:
        myquit (e)


def placeBoarders (thickness, color):
    print "placeBoarders"
    e1 = pge.box (0.0, 0.0, 1.0, thickness, color).fix ()
    e2 = pge.box (0.0, 0.0, thickness, 1.0, color).fix ()
    e3 = pge.box (1.0-thickness, 0.0, thickness, 1.0, color).fix ()
    e4 = pge.box (0.0, 1.0-thickness, 1.0, thickness, color).fix ()
    return e1, e2, e3, e4


def placeBall (kind, x, y, r):
    return pge.circle (x, y, r, kind)


def push_it (o, e):
    p = e.collision_between ()
    if p != None and p != []:
        for i in p:
            if i != o:
                i.put_xvel (i.get_xvel () * 1.15)
                i.put_yvel (i.get_yvel () * 1.15)


def placeTriangle (p0, p1, p2, colour):
    t = pge.poly3 (p0[0], p0[1], p1[0], p1[1], p2[0], p2[1], colour).on_collision (push_it).fix ()


def delete_me (o, e):
    global blocks, winner, loser

    blocks.remove (o)
    o.rm ()
    if blocks == []:
        if not loser:
            winner = True
            pge.text (0.2, 0.3, "Winner", white, 100, 1)
            pge.at_time (4.0, finish_game)


def box_of (pos, width, height, color):
    global blocks

    blocks += [pge.box (pos[0], pos[1], width, height, color).fix ().on_collision (delete_me)]

Timer and event based callbacks.

def mouse_hit (e):
    global gb
    mouse = pge.pyg_to_unit_coord (e.pos)
    if e.button == 1:
        gb.put_xvel (gb.get_xvel ()-0.3)
    elif e.button == 3:
        gb.put_xvel (gb.get_xvel ()+0.3)
    elif gb.moving_towards (mouse[0], mouse[1]):
        ball = gb.get_unit_coord ()
        # print "mouse =", mouse, "ball =", ball
        gb.apply_impulse (pge.sub_coord (mouse, ball), 0.4)
    else:
        gb.put_yvel (gb.get_yvel ()+0.4)


def place_boxes ():
    for y in range (3):
        for x in range (9):
            box_of ([((float)(x))/10.0+0.06, (float)(y)/10.0+0.03], 0.08, 0.08, dark_blue)

def timer ():
    global seconds_left, previous
    if seconds_left >= 0:
        pge.at_time (1.0, timer)
        s = "%d" % seconds_left
        if previous != None:
            previous.rm ()
        previous = pge.text (0.8, 0.9, s, white, 100, 1)
        seconds_left -= 1


def out_of_time ():
    global loser, winner
    if not winner:
        loser = True
        pge.text (0.3, 0.7, "Loser", white, 100, 1)
        pge.at_time (4.0, finish_game)

The main function.

def main ():
    global gb, winner, loser, seconds_left

    t1 = placeTriangle ([0.2, 0.4], [0.4, 0.4], [0.3, 0.5], white)
    t2 = placeTriangle ([0.6, 0.4], [0.8, 0.4], [0.7, 0.5], white)
    b1, b2, b3, b4 = placeBoarders (boarder, wood_dark)

    place_boxes ()
    gb = placeBall (gold, 0.19, 0.8, 0.05).mass (1.25)

    print "before run"
    pge.gravity ()
    pge.dump_world ()
    pge.draw_collision (True, False)
    pge.slow_down (slowdown)  # slows down real time by a factor of
    pge.register_handler (myquit, [QUIT])
    pge.register_handler (key_pressed, [KEYDOWN])
    pge.register_handler (mouse_hit, [MOUSEBUTTONDOWN])
    pge.display_set_mode ([800, 800])
    seconds_left = 10*slowdown
    timer ()
    pge.run (10.0)
    out_of_time ()
    pge.run (4.0)
    pge.finish ()


print "before main()"
main ()