SlideShare a Scribd company logo
Introduction To
Game Programming
     EuroPython 2010
       Richard Jones
The Basics
The Basics
• Displaying something
The Basics
• Displaying something
• Controlling animation
The Basics
• Displaying something
• Controlling animation
• User input
The Basics
• Displaying something
• Controlling animation
• User input
• Gameplay mechanics
The Basics
• Displaying something
• Controlling animation
• User input
• Gameplay mechanics
• Playing sound effects and music
The Basics
• Displaying something
• Controlling animation
• User input
• Gameplay mechanics
• Playing sound effects and music
• Game architecture
Displaying Something
Displaying Something

• Opening a window
Displaying Something

• Opening a window
• Reading images
Displaying Something

• Opening a window
• Reading images
• Displaying images
Displaying Something

• Opening a window
• Reading images
• Displaying images
• Organising the display of images (scene
  composition)
Sky
fixed
Distance
 parallax=.5
Midfield
 parallax=.8
Foreground 1
Foreground 2
Game Triggers
Opening a Window
   import cocos
   from cocos.director import director

   director.init()

   scene = cocos.scene.Scene()

   director.run(scene)
Drawing
import cocos
from cocos.director import director

director.init()

scene = cocos.scene.Scene()
sprite = cocos.sprite.Sprite('kitten.jpg')
scene.add(sprite)

director.run(scene)
Anchoring


              (256, 256)
512 px




            512 px
Anchoring




(256, 256)
Anchoring




(0,0)
Anchoring
import cocos
from cocos.director import director

director.init()

scene = cocos.scene.Scene()
sprite = cocos.sprite.Sprite('kitten.jpg', anchor=(0,0))
scene.add(sprite)

director.run(scene)
Using a Layer
import cocos
from cocos.director import director

director.init()

scene = cocos.scene.Scene()
layer = cocos.layer.Layer()
scene.add(layer)
sprite = cocos.sprite.Sprite('kitten.jpg', anchor=(0,0))
layer.add(sprite)

director.run(scene)
Animation
import cocos
from cocos import actions
from cocos.director import director
...
scene = cocos.scene.Scene()
layer = cocos.layer.Layer()
scene.add(layer)
sprite = cocos.sprite.Sprite('kitten.jpg', anchor=(0,0))
layer.add(sprite)

sprite.do(actions.MoveBy((100, 0)))

director.run(scene)
Getting Organised
import cocos
from cocos import actions
from cocos.director import director

class AsteroidsGame(cocos.scene.Scene):
    def __init__(self):
        super(AsteroidsGame, self).__init__()

       self.player = cocos.layer.Layer()
       self.add(self.player)
       self.ship = cocos.sprite.Sprite('data/ship.png', (width/2, height/2))
       velocity = (100, 0)
       self.ship.do(actions.MoveBy(velocity))
       self.player.add(self.ship)

director.init()
width, height = director.get_window_size()
director.run(AsteroidsGame())
Adding Asteroids
import random

import cocos
from cocos import actions
from cocos.director import director

def create_asteroid(layer, size, position, speed):
    '''Create an asteroid of a certain size and speed.
    '''
    s = cocos.sprite.Sprite('data/%s_asteroid.png' % size, position)
    s.size = size
    layer.add(s)
    velocity = (random.randint(-speed, speed), random.randint(-speed, speed))
    dr = random.randint(-speed, speed)
    s.do(actions.Repeat(actions.MoveBy(velocity, 1) | actions.RotateBy(dr, 1)))

...
Adding Asteroids
...
super(AsteroidsGame, self).__init__()

# place the asteroids in a layer by themselves
self.asteroids = cocos.layer.Layer()
self.add(self.asteroids)
for i in range(3):
    # place asteroids at random positions around the screen
    position = (random.randint(0, width), random.randint(0, height))
    create_asteroid(self.asteroids, 'big', position, 100)

# place the player ship in another layer
...
Better action
...
s = cocos.sprite.Sprite('data/%s_asteroid.png' % size, position)
s.size = size
layer.add(s)
s.velocity = (random.randint(-speed, speed), random.randint(-speed, speed))
s.dr = random.randint(-speed, speed)
s.do(actions.Move())
...
Screen Wrapping
...
s.velocity = (random.randint(-speed, speed),
    random.randint(-speed, speed))
s.dr = random.randint(-speed, speed)
s.do(actions.WrappedMove(width, height))
...
    self.ship.velocity = (100, 0)
    # move the ship kinematically and wrapped to the screen size
    self.ship.do(actions.WrappedMove(width, height))
    self.player.add(self.ship)
    ...
Gameplay Mechanics
Gameplay Mechanics
• Player Controls
Gameplay Mechanics
• Player Controls
• Timed rules (when objects appear; moving
  the play field)
Gameplay Mechanics
• Player Controls
• Timed rules (when objects appear; moving
  the play field)
• Interaction of game objects
Gameplay Mechanics
• Player Controls
• Timed rules (when objects appear; moving
  the play field)
• Interaction of game objects
• Detecting important events (game won or
  game over)
User Input
User Input


• Getting events
User Input


• Getting events
• Distinct keyboard events vs. keyboard state
Control
import math
import random

from pyglet.window import key
import cocos
from cocos import actions
from cocos.director import director
Control




                                               y = speed x sin(rotation)
                                         ng)
                                  ho oti
                                rs
                            n, o
                     er atio
                   l
             a cce
     d (or
s pee
        rotation
          x = speed x cos(rotation)
Control
         x = speed x cos(rotation)




                                                y = speed x sin(-rotation)
        rotation
spe
   ed
        (or
              acc
                    ele
                       rat
                          ion
                             , or
                                    sho
                                       oti
                                          ng)
Control
class MoveShip(actions.WrappedMove):
    def step(self, dt):
        super(MoveShip, self).step(dt)

       # set the rotation using the left and right arrow keys
       self.target.dr = (keys[key.RIGHT] - keys[key.LEFT]) * 360

       # figure the x and y heading components from the rotation
       rotation = math.radians(self.target.rotation)
       rotation_x = math.cos(rotation)
       rotation_y = math.sin(-rotation)
       # accelerate along the heading
       acc = keys[key.UP] * 200
       self.target.acceleration = (acc * rotation_x, acc * rotation_y)
Control

...
self.ship = cocos.sprite.Sprite('data/ship.png', (width/2, height/2))
self.ship.velocity = (0, 0)
# animate the ship with our custom action
self. ship.do(MoveShip(width, height))
self.player.add(self. ship)
...
Control

...
# open the window, get dimensions, watch the keyboard and run our scene
director.init()
width, height = director.get_window_size()
keys = key.KeyStateHandler()
director.window.push_handlers(keys)
director.run(AsteriodsGame())
Detecting Collisions
Detecting Collisions

• Pixel-Perfect
Detecting Collisions

• Pixel-Perfect
• Axis-Aligned Bounding Box
Detecting Collisions

• Pixel-Perfect
• Axis-Aligned Bounding Box
• Circle-Circle
Detecting Collisions

• Pixel-Perfect
• Axis-Aligned Bounding Box
• Circle-Circle
• Hash Map
Detecting Collisions
      Pixel-Perfect
Detecting Collisions
   Axis-Aligned Bounding Box
Detecting Collisions
   Axis-Aligned Bounding Box
Detecting Collisions
   Axis-Aligned Bounding Box
Detecting Collisions
      Circle-Circle
Detecting Collisions
      Circle-Circle
Detecting Collisions
      Circle-Circle
Detecting Collisions
      Circle-Circle
Detecting Collisions
                       Hash Map




d = {(42,42): [ship], (43, 42): [ship], (44, 42): ship, ...
      (52, 45): [asteroid], (53, 45): [asteroid], ...}
Collision Detection
Collision Detection
Collision Detection
Collision Detection
Collision Detection

       distance
...
                       Collision
        self.target.acceleration = (acc * rotation_x, acc * rotation_y)



def collide(a, b):
    '''Determine whether two objects with a center point and width
    (diameter) are colliding.'''
    distance = math.sqrt((a.x-b.x)**2 + (a.y-b.y)**2)
    return distance < (a.width/2 + b.width/2)



class MoveAsteroid(actions.WrappedMove):
    def step(self, dt):
        super(MoveAsteroid, self).step(dt)

        # detect collision between this asteroid and the ship
        if collide(self.target, director.scene.ship):
            quit('GAME OVER')



def create_asteroid(layer, size, position, speed):
    ...
Collision

def create_asteroid(layer, size, position, speed):
    '''Create an asteroid of a certain size and speed.
    '''
    s = cocos.sprite.Sprite('data/%s_asteroid.png' % size, position)
    s.size = size
    layer.add(s)
    s.velocity = (random.randint(-speed, speed), random.randint(-speed, speed))
    s.dr = random.randint(-speed, speed)
    s.do(MoveAsteroid(width, height))

...
Shooting
      ...
      self.target.acceleration = (acc * rotation_x, acc * rotation_y)

      if self.target.gun_cooldown:
          # still limiting the gun rate of fire
          self.target.gun_cooldown = max(0, self.target.gun_cooldown - dt)
      elif keys[key.SPACE]:
          # fire a bullet from the ship
          b = cocos.sprite.Sprite('data/bullet.png', (self.target.x,
              self.target.y))
          # send it in the same heading as the ship
          b.velocity = (rotation_x * 400, rotation_y * 400)
          # the bullet has a lifespan of 1 second
          b.life = 1
          director.scene.player.add(b)
          # move the bullet with its custom action
          b.do(MoveBullet(width, height))
          # ship may only shoot twice per second
          self.target.gun_cooldown = .5

...
Shooting
class MoveBullet(actions.WrappedMove):
    def step(self, dt):
        super(MoveBullet, self).step(dt)

       # age the bullet
       self.target.life -= dt
       if self.target.life < 0:
           # remove from play if it's too old
           self.target.kill()
           return

       # see if the bullet hits any asteroids
       for asteroid in director.scene.asteroids.get_children():
           if collide(self.target, asteroid):
               # remove the bullet and asteroid
               self.target.kill()
               asteroid.kill()
               return
... and winning

...
super(MoveShip, self).step(dt)

# if there's no asteroids left then the player has won
if not director.scene.asteroids.children:
    quit('YOU WIN')

# set the rotation using the left and right arrow keys
self.target.dr = (keys[key.RIGHT] - keys[key.LEFT]) * 360
...
Creating chunks
def create_asteroid(layer, size, position, velocity, rotation, speed):
    '''Create an asteroid of a certain size, possibly inheriting its
    parent's velocity and rotation.
    '''
    s = cocos.sprite.Sprite('data/%s_asteroid.png' % size, position)
    s.size = size
    dx, dy = velocity
    s.velocity = (dx + random.randint(-speed, speed),
        dy + random.randint(-speed, speed))
    s.dr = rotation + random.randint(-speed, speed)
    layer.add(s)
    s.do(MoveAsteroid(width, height))
Creating chunks

for asteroid in director.scene.asteroids.get_children():
    if collide(self.target, asteroid):
        # remove the bullet and asteroid, create new smaller
        # asteroid
        self.target.kill()
        create_smaller_asteroids(asteroid)
        asteroid.kill()
        return
Creating chunks
            ...
            position = (random.randint(0, width), random.randint(0, height))
            create_asteroid(self.asteroids, 'big', position, (0, 0), 0, 100)



def create_smaller_asteroids(asteroid):
    asteroids = director.scene.asteroids
    if asteroid.size == 'big':
        # if it's a big asteroid then make two medium asteroids in
        # its place
        for i in range(2):
            create_asteroid(asteroids, 'medium', asteroid.position,
                asteroid.velocity, asteroid.dr, 50)
    elif asteroid.size == 'medium':
        # if it's a medium asteroid then make two small asteroids in
        # its place
        for i in range(2):
            create_asteroid(asteroids, 'small', asteroid.position,
                asteroid.velocity, asteroid.dr, 50)
Sound
Sound


• Reading sound files
Sound


• Reading sound files
• Playing sounds and background music
Sound Effects
import math
import random

import pyglet
from pyglet.window import key
import cocos
from cocos import actions
from cocos.director import director



# load our sound effects
explosion_sound = pyglet.media.load('data/explosion.wav', streaming=False)
bullet_sound = pyglet.media.load('data/bullet.wav', streaming=False)

...
Sound Effects


       ...
       # ship may only shoot twice per second
       self.target.gun_cooldown = .5
       bullet_sound.play()

...
Sound Effects

 ...
 create_smaller_asteroids(asteroid)
 asteroid.kill()
 explosion_sound.play()
 return
Game Architecture
Game Architecture

• Player lives
Game Architecture

• Player lives
• Game won / game over screen
Game Architecture

• Player lives
• Game won / game over screen
• Opening screen
Game Architecture

• Player lives
• Game won / game over screen
• Opening screen
• Options menu
Invulnerability
class Ship(cocos.sprite.Sprite):
    gun_cooldown = 0
    velocity = (0, 0)
    is_invulnerable = False

   def set_invulnerable(self):
       self.do(actions.Blink(10, 1) +
           actions.CallFunc(self.set_vulnerable))
       self.is_invulnerable = True

   def set_vulnerable(self):
       self.is_invulnerable = False
Invulnerability

self.player = cocos.layer.Layer()
self.add(self.player)
self.ship = Ship('data/ship.png', (width/2, height/2))
self.player.add(self.ship)

# animate the ship with our custom action
self.ship.do(MoveShip(width, height))
self.ship.set_invulnerable()
Invulnerability

super(MoveAsteroid, self).step(dt)

if director.scene.ship.is_invulnerable:
    return

# detect collision between this asteroid and the ship
if collide(self.target, director.scene.ship):
    quit('GAME OVER')
Lives

 self.ship.set_invulnerable()
 self.player.add(self.ship)



# another layer for the "HUD" or front informational display
self.hud = cocos.layer.Layer()
self.add(self.hud)
self.lives = cocos.text.Label('Lives: 3', font_size=20, y=height, anchor_y='top')
self.lives.counter = 3
self.hud.add(self.lives)
Lives

# detect collision between this asteroid and the ship
if collide(self.target, director.scene.ship):
    lives = director.scene.lives
    lives.counter -= 1
    director.scene.ship.set_invulnerable()
    if not lives.counter:
        quit('GAME OVER')
    else:
        lives.element.text = 'Lives: %d' % lives.counter
Scenes
class MessageScene(cocos.scene.Scene):
    def __init__(self, text):
        super(MessageScene, self).__init__()
        class UserActivity(cocos.layer.Layer):
            is_event_handler = True
            def on_mouse_press(*args): director.pop()
            def on_text(*args): director.pop()
        layer = UserActivity()
        self.add(layer)
        t = cocos.text.Label(text, font_size=40,
            x=width/2, anchor_x='center',
            y=height/2, anchor_y='center')
        layer.add(t)
Scenes
      # if there's no asteroids left then the player has won
      if not director.scene.asteroids.children:
          director.replace(MessageScene('You Win'))

      # set the rotation using the left and right arrow keys
      self.target.dr = (keys[key.RIGHT] - keys[key.LEFT]) * 360
...
          lives.counter -= 1
          director.scene.ship.set_invulnerable()
          if not lives.counter:
              director.replace(MessageScene('Game Over'))
          else:
              lives.element.text = 'Lives: %d' % lives.counter
Menu
class MenuScene(cocos.scene.Scene):
    def __init__(self):
        super(MenuScene, self).__init__()

        # opening menu
        menu = cocos.menu.Menu("Asteroids!!!!")
        menu.create_menu([
            cocos.menu.MenuItem('Play', lambda: director.push(AsteroidsGame())),
            cocos.menu.MenuItem('Quit', pyglet.app.exit),
        ])
        menu.on_quit = pyglet.app.exit
        self.add(menu)

# open the window, get dimensions, watch the keyboard and run our scene
director.init()
width, height = director.get_window_size()
keys = key.KeyStateHandler()
director.window.push_handlers(keys)
director.run(MenuScene())
Special Effects
Special Effects


• Simple image animations
Special Effects


• Simple image animations
• Use libraries like lepton
Controlling Animation
Controlling Animation

• Image position on screen
Controlling Animation

• Image position on screen
• Updates over time
Controlling Animation

• Image position on screen
• Updates over time
• Accounting for frame rate
Controlling Animation

• Image position on screen
• Updates over time
• Accounting for frame rate
• Frame to use from multiple images
Animation from
multiple images
Animation from
multiple images
Special Effects
Special Effects

...
explosion_sound = pyglet.media.load('data/explosion.wav', streaming=False)
bullet_sound = pyglet.media.load('data/bullet.wav', streaming=False)

# load our explosion animation
explosion = pyglet.image.load('data/explosion.png')
explosion_grid = pyglet.image.ImageGrid(explosion, 2, 8)
explosion = explosion_grid.get_animation(.05, False)

...
Special Effects

# remove the bullet and asteroid, create new smaller
# asteroid
self.target.kill()
s = cocos.sprite.Sprite(explosion, self.target.position)
s.velocity = asteroid.velocity
s.do(actions.WrappedMove(width, height) |
    (actions.Delay(.05 * 16) +
    actions.CallFuncS(lambda s: s.kill())))
self.target.parent.add(s)
create_smaller_asteroids(asteroid)
asteroid.kill()
Other Game Types

• minesweeper
• car driving
• platformer
• tower defence
Minesweeper

• rendering a grid of cells
• detecting mouse clicks on cells
• exposing contents
Car Driving

• different movement model
• detecting correct circuit
• detecting collision with edge of track
  (pixel-based collision detection)
Platformer

• rendering game layers
• handling triggers
• platformer physics
Tower Defence


• tower placement (selection & position)
• movement solution for creeps
Other Things

• kytten
  GUI controls for pyglet / cocos2d
• cocograph
  map editing
Where To From Here?

• http://los-cocos.org
• http://pyglet.org
• http://pygame.org
• http://inventwithpython.com/
• http://pyweek.org
Ad

More Related Content

What's hot (20)

Corona sdk
Corona sdkCorona sdk
Corona sdk
Dom Dominic Toretto
 
Making Games in JavaScript
Making Games in JavaScriptMaking Games in JavaScript
Making Games in JavaScript
Sam Cartwright
 
ES6(ES2015) is beautiful
ES6(ES2015) is beautifulES6(ES2015) is beautiful
ES6(ES2015) is beautiful
monikagupta18jan
 
Proga 0622
Proga 0622Proga 0622
Proga 0622
Atsushi Tadokoro
 
The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84
Mahmoud Samir Fayed
 
Mobile Game and Application with J2ME - Collision Detection
Mobile Gameand Application withJ2ME  - Collision DetectionMobile Gameand Application withJ2ME  - Collision Detection
Mobile Game and Application with J2ME - Collision Detection
Jenchoke Tachagomain
 
Mobile Game and Application with J2ME
Mobile Gameand Application with J2MEMobile Gameand Application with J2ME
Mobile Game and Application with J2ME
Jenchoke Tachagomain
 
Expand/Collapse animation on Android
Expand/Collapse animation on AndroidExpand/Collapse animation on Android
Expand/Collapse animation on Android
Pavlo Dudka
 
The Ring programming language version 1.10 book - Part 71 of 212
The Ring programming language version 1.10 book - Part 71 of 212The Ring programming language version 1.10 book - Part 71 of 212
The Ring programming language version 1.10 book - Part 71 of 212
Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 64 of 212
The Ring programming language version 1.10 book - Part 64 of 212The Ring programming language version 1.10 book - Part 64 of 212
The Ring programming language version 1.10 book - Part 64 of 212
Mahmoud Samir Fayed
 
pptuni1
pptuni1pptuni1
pptuni1
Sachin Yadav
 
Pybelsberg — Constraint-based Programming in Python
Pybelsberg — Constraint-based Programming in PythonPybelsberg — Constraint-based Programming in Python
Pybelsberg — Constraint-based Programming in Python
Christoph Matthies
 
Homemade GoTo mount for Telescopes using Nylon wheels, GT2 belts and 100:1 ge...
Homemade GoTo mount for Telescopes using Nylon wheels, GT2 belts and 100:1 ge...Homemade GoTo mount for Telescopes using Nylon wheels, GT2 belts and 100:1 ge...
Homemade GoTo mount for Telescopes using Nylon wheels, GT2 belts and 100:1 ge...
Janis Alnis
 
Cocos2dx 7.1-7.2
Cocos2dx 7.1-7.2Cocos2dx 7.1-7.2
Cocos2dx 7.1-7.2
Kyungryul KIM
 
SwiftUI Animation - The basic overview
SwiftUI Animation - The basic overviewSwiftUI Animation - The basic overview
SwiftUI Animation - The basic overview
WannitaTolaema
 
The Ring programming language version 1.2 book - Part 38 of 84
The Ring programming language version 1.2 book - Part 38 of 84The Ring programming language version 1.2 book - Part 38 of 84
The Ring programming language version 1.2 book - Part 38 of 84
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.2 book - Part 52 of 181
The Ring programming language version 1.5.2 book - Part 52 of 181The Ring programming language version 1.5.2 book - Part 52 of 181
The Ring programming language version 1.5.2 book - Part 52 of 181
Mahmoud Samir Fayed
 
Functional Systems @ Twitter
Functional Systems @ TwitterFunctional Systems @ Twitter
Functional Systems @ Twitter
C4Media
 
modm
modmmodm
modm
AleksMilovanovic
 
The Ring programming language version 1.5 book - Part 9 of 31
The Ring programming language version 1.5 book - Part 9 of 31The Ring programming language version 1.5 book - Part 9 of 31
The Ring programming language version 1.5 book - Part 9 of 31
Mahmoud Samir Fayed
 
Making Games in JavaScript
Making Games in JavaScriptMaking Games in JavaScript
Making Games in JavaScript
Sam Cartwright
 
The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84
Mahmoud Samir Fayed
 
Mobile Game and Application with J2ME - Collision Detection
Mobile Gameand Application withJ2ME  - Collision DetectionMobile Gameand Application withJ2ME  - Collision Detection
Mobile Game and Application with J2ME - Collision Detection
Jenchoke Tachagomain
 
Mobile Game and Application with J2ME
Mobile Gameand Application with J2MEMobile Gameand Application with J2ME
Mobile Game and Application with J2ME
Jenchoke Tachagomain
 
Expand/Collapse animation on Android
Expand/Collapse animation on AndroidExpand/Collapse animation on Android
Expand/Collapse animation on Android
Pavlo Dudka
 
The Ring programming language version 1.10 book - Part 71 of 212
The Ring programming language version 1.10 book - Part 71 of 212The Ring programming language version 1.10 book - Part 71 of 212
The Ring programming language version 1.10 book - Part 71 of 212
Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 64 of 212
The Ring programming language version 1.10 book - Part 64 of 212The Ring programming language version 1.10 book - Part 64 of 212
The Ring programming language version 1.10 book - Part 64 of 212
Mahmoud Samir Fayed
 
Pybelsberg — Constraint-based Programming in Python
Pybelsberg — Constraint-based Programming in PythonPybelsberg — Constraint-based Programming in Python
Pybelsberg — Constraint-based Programming in Python
Christoph Matthies
 
Homemade GoTo mount for Telescopes using Nylon wheels, GT2 belts and 100:1 ge...
Homemade GoTo mount for Telescopes using Nylon wheels, GT2 belts and 100:1 ge...Homemade GoTo mount for Telescopes using Nylon wheels, GT2 belts and 100:1 ge...
Homemade GoTo mount for Telescopes using Nylon wheels, GT2 belts and 100:1 ge...
Janis Alnis
 
SwiftUI Animation - The basic overview
SwiftUI Animation - The basic overviewSwiftUI Animation - The basic overview
SwiftUI Animation - The basic overview
WannitaTolaema
 
The Ring programming language version 1.2 book - Part 38 of 84
The Ring programming language version 1.2 book - Part 38 of 84The Ring programming language version 1.2 book - Part 38 of 84
The Ring programming language version 1.2 book - Part 38 of 84
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.2 book - Part 52 of 181
The Ring programming language version 1.5.2 book - Part 52 of 181The Ring programming language version 1.5.2 book - Part 52 of 181
The Ring programming language version 1.5.2 book - Part 52 of 181
Mahmoud Samir Fayed
 
Functional Systems @ Twitter
Functional Systems @ TwitterFunctional Systems @ Twitter
Functional Systems @ Twitter
C4Media
 
The Ring programming language version 1.5 book - Part 9 of 31
The Ring programming language version 1.5 book - Part 9 of 31The Ring programming language version 1.5 book - Part 9 of 31
The Ring programming language version 1.5 book - Part 9 of 31
Mahmoud Samir Fayed
 

Similar to Intro to Game Programming (20)

Shootting Game
Shootting GameShootting Game
Shootting Game
Michael Pan
 
Game dev 101 part 3
Game dev 101 part 3Game dev 101 part 3
Game dev 101 part 3
Christoffer Noring
 
Макс Грибов — Использование SpriteKit в неигровых приложениях
Макс Грибов — Использование SpriteKit в неигровых приложенияхМакс Грибов — Использование SpriteKit в неигровых приложениях
Макс Грибов — Использование SpriteKit в неигровых приложениях
CocoaHeads
 
Testing a 2D Platformer with Spock
Testing a 2D Platformer with SpockTesting a 2D Platformer with Spock
Testing a 2D Platformer with Spock
Alexander Tarlinder
 
You will learn RxJS in 2017
You will learn RxJS in 2017You will learn RxJS in 2017
You will learn RxJS in 2017
名辰 洪
 
Game development with Cocos2d
Game development with Cocos2dGame development with Cocos2d
Game development with Cocos2d
Vinsol
 
Writing a Space Shooter with HTML5 Canvas
Writing a Space Shooter with HTML5 CanvasWriting a Space Shooter with HTML5 Canvas
Writing a Space Shooter with HTML5 Canvas
Steve Purkis
 
Game age ppt
Game age pptGame age ppt
Game age ppt
Ahmed Yousef
 
The Ring programming language version 1.6 book - Part 62 of 189
The Ring programming language version 1.6 book - Part 62 of 189The Ring programming language version 1.6 book - Part 62 of 189
The Ring programming language version 1.6 book - Part 62 of 189
Mahmoud Samir Fayed
 
Swift, via "swift-2048"
Swift, via "swift-2048"Swift, via "swift-2048"
Swift, via "swift-2048"
Austin Zheng
 
Html5 game programming overview
Html5 game programming overviewHtml5 game programming overview
Html5 game programming overview
민태 김
 
[Ultracode Munich #4] Demo on Animatron by Anton Kotenko
[Ultracode Munich #4] Demo on Animatron by Anton Kotenko[Ultracode Munich #4] Demo on Animatron by Anton Kotenko
[Ultracode Munich #4] Demo on Animatron by Anton Kotenko
BeMyApp
 
How to Clone Flappy Bird in Swift
How to Clone Flappy Bird in SwiftHow to Clone Flappy Bird in Swift
How to Clone Flappy Bird in Swift
Giordano Scalzo
 
Silverlight as a Gaming Platform
Silverlight as a Gaming PlatformSilverlight as a Gaming Platform
Silverlight as a Gaming Platform
goodfriday
 
JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your code
Laurence Svekis ✔
 
Rxjs kyivjs 2015
Rxjs kyivjs 2015Rxjs kyivjs 2015
Rxjs kyivjs 2015
Alexander Mostovenko
 
Processing and Processing.js
Processing and Processing.jsProcessing and Processing.js
Processing and Processing.js
jeresig
 
Intro to Python (High School) Unit #3
Intro to Python (High School) Unit #3Intro to Python (High School) Unit #3
Intro to Python (High School) Unit #3
Jay Coskey
 
Pointer Events in Canvas
Pointer Events in CanvasPointer Events in Canvas
Pointer Events in Canvas
deanhudson
 
circ.db.dbcircleserver(1).py#!usrlocalbinpython3im.docx
circ.db.dbcircleserver(1).py#!usrlocalbinpython3im.docxcirc.db.dbcircleserver(1).py#!usrlocalbinpython3im.docx
circ.db.dbcircleserver(1).py#!usrlocalbinpython3im.docx
christinemaritza
 
Макс Грибов — Использование SpriteKit в неигровых приложениях
Макс Грибов — Использование SpriteKit в неигровых приложенияхМакс Грибов — Использование SpriteKit в неигровых приложениях
Макс Грибов — Использование SpriteKit в неигровых приложениях
CocoaHeads
 
Testing a 2D Platformer with Spock
Testing a 2D Platformer with SpockTesting a 2D Platformer with Spock
Testing a 2D Platformer with Spock
Alexander Tarlinder
 
You will learn RxJS in 2017
You will learn RxJS in 2017You will learn RxJS in 2017
You will learn RxJS in 2017
名辰 洪
 
Game development with Cocos2d
Game development with Cocos2dGame development with Cocos2d
Game development with Cocos2d
Vinsol
 
Writing a Space Shooter with HTML5 Canvas
Writing a Space Shooter with HTML5 CanvasWriting a Space Shooter with HTML5 Canvas
Writing a Space Shooter with HTML5 Canvas
Steve Purkis
 
The Ring programming language version 1.6 book - Part 62 of 189
The Ring programming language version 1.6 book - Part 62 of 189The Ring programming language version 1.6 book - Part 62 of 189
The Ring programming language version 1.6 book - Part 62 of 189
Mahmoud Samir Fayed
 
Swift, via "swift-2048"
Swift, via "swift-2048"Swift, via "swift-2048"
Swift, via "swift-2048"
Austin Zheng
 
Html5 game programming overview
Html5 game programming overviewHtml5 game programming overview
Html5 game programming overview
민태 김
 
[Ultracode Munich #4] Demo on Animatron by Anton Kotenko
[Ultracode Munich #4] Demo on Animatron by Anton Kotenko[Ultracode Munich #4] Demo on Animatron by Anton Kotenko
[Ultracode Munich #4] Demo on Animatron by Anton Kotenko
BeMyApp
 
How to Clone Flappy Bird in Swift
How to Clone Flappy Bird in SwiftHow to Clone Flappy Bird in Swift
How to Clone Flappy Bird in Swift
Giordano Scalzo
 
Silverlight as a Gaming Platform
Silverlight as a Gaming PlatformSilverlight as a Gaming Platform
Silverlight as a Gaming Platform
goodfriday
 
JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your code
Laurence Svekis ✔
 
Processing and Processing.js
Processing and Processing.jsProcessing and Processing.js
Processing and Processing.js
jeresig
 
Intro to Python (High School) Unit #3
Intro to Python (High School) Unit #3Intro to Python (High School) Unit #3
Intro to Python (High School) Unit #3
Jay Coskey
 
Pointer Events in Canvas
Pointer Events in CanvasPointer Events in Canvas
Pointer Events in Canvas
deanhudson
 
circ.db.dbcircleserver(1).py#!usrlocalbinpython3im.docx
circ.db.dbcircleserver(1).py#!usrlocalbinpython3im.docxcirc.db.dbcircleserver(1).py#!usrlocalbinpython3im.docx
circ.db.dbcircleserver(1).py#!usrlocalbinpython3im.docx
christinemaritza
 
Ad

More from Richard Jones (11)

Angboard
AngboardAngboard
Angboard
Richard Jones
 
Don't do this
Don't do thisDon't do this
Don't do this
Richard Jones
 
Introduction to Game Programming
Introduction to Game ProgrammingIntroduction to Game Programming
Introduction to Game Programming
Richard Jones
 
Message Queueing - by an MQ noob
Message Queueing - by an MQ noobMessage Queueing - by an MQ noob
Message Queueing - by an MQ noob
Richard Jones
 
Message queueing
Message queueingMessage queueing
Message queueing
Richard Jones
 
Web micro-framework BATTLE!
Web micro-framework BATTLE!Web micro-framework BATTLE!
Web micro-framework BATTLE!
Richard Jones
 
State of Python (2010)
State of Python (2010)State of Python (2010)
State of Python (2010)
Richard Jones
 
What's New In Python 2.6
What's New In Python 2.6What's New In Python 2.6
What's New In Python 2.6
Richard Jones
 
What's New In Python 2.5
What's New In Python 2.5What's New In Python 2.5
What's New In Python 2.5
Richard Jones
 
What's New In Python 2.4
What's New In Python 2.4What's New In Python 2.4
What's New In Python 2.4
Richard Jones
 
Tkinter Does Not Suck
Tkinter Does Not SuckTkinter Does Not Suck
Tkinter Does Not Suck
Richard Jones
 
Introduction to Game Programming
Introduction to Game ProgrammingIntroduction to Game Programming
Introduction to Game Programming
Richard Jones
 
Message Queueing - by an MQ noob
Message Queueing - by an MQ noobMessage Queueing - by an MQ noob
Message Queueing - by an MQ noob
Richard Jones
 
Web micro-framework BATTLE!
Web micro-framework BATTLE!Web micro-framework BATTLE!
Web micro-framework BATTLE!
Richard Jones
 
State of Python (2010)
State of Python (2010)State of Python (2010)
State of Python (2010)
Richard Jones
 
What's New In Python 2.6
What's New In Python 2.6What's New In Python 2.6
What's New In Python 2.6
Richard Jones
 
What's New In Python 2.5
What's New In Python 2.5What's New In Python 2.5
What's New In Python 2.5
Richard Jones
 
What's New In Python 2.4
What's New In Python 2.4What's New In Python 2.4
What's New In Python 2.4
Richard Jones
 
Tkinter Does Not Suck
Tkinter Does Not SuckTkinter Does Not Suck
Tkinter Does Not Suck
Richard Jones
 
Ad

Recently uploaded (20)

Biophysics Chapter 3 Methods of Studying Macromolecules.pdf
Biophysics Chapter 3 Methods of Studying Macromolecules.pdfBiophysics Chapter 3 Methods of Studying Macromolecules.pdf
Biophysics Chapter 3 Methods of Studying Macromolecules.pdf
PKLI-Institute of Nursing and Allied Health Sciences Lahore , Pakistan.
 
How to track Cost and Revenue using Analytic Accounts in odoo Accounting, App...
How to track Cost and Revenue using Analytic Accounts in odoo Accounting, App...How to track Cost and Revenue using Analytic Accounts in odoo Accounting, App...
How to track Cost and Revenue using Analytic Accounts in odoo Accounting, App...
Celine George
 
Multi-currency in odoo accounting and Update exchange rates automatically in ...
Multi-currency in odoo accounting and Update exchange rates automatically in ...Multi-currency in odoo accounting and Update exchange rates automatically in ...
Multi-currency in odoo accounting and Update exchange rates automatically in ...
Celine George
 
How to Customize Your Financial Reports & Tax Reports With Odoo 17 Accounting
How to Customize Your Financial Reports & Tax Reports With Odoo 17 AccountingHow to Customize Your Financial Reports & Tax Reports With Odoo 17 Accounting
How to Customize Your Financial Reports & Tax Reports With Odoo 17 Accounting
Celine George
 
LDMMIA Reiki Master Spring 2025 Mini Updates
LDMMIA Reiki Master Spring 2025 Mini UpdatesLDMMIA Reiki Master Spring 2025 Mini Updates
LDMMIA Reiki Master Spring 2025 Mini Updates
LDM Mia eStudios
 
Introduction to Vibe Coding and Vibe Engineering
Introduction to Vibe Coding and Vibe EngineeringIntroduction to Vibe Coding and Vibe Engineering
Introduction to Vibe Coding and Vibe Engineering
Damian T. Gordon
 
Sinhala_Male_Names.pdf Sinhala_Male_Name
Sinhala_Male_Names.pdf Sinhala_Male_NameSinhala_Male_Names.pdf Sinhala_Male_Name
Sinhala_Male_Names.pdf Sinhala_Male_Name
keshanf79
 
Geography Sem II Unit 1C Correlation of Geography with other school subjects
Geography Sem II Unit 1C Correlation of Geography with other school subjectsGeography Sem II Unit 1C Correlation of Geography with other school subjects
Geography Sem II Unit 1C Correlation of Geography with other school subjects
ProfDrShaikhImran
 
Exploring-Substances-Acidic-Basic-and-Neutral.pdf
Exploring-Substances-Acidic-Basic-and-Neutral.pdfExploring-Substances-Acidic-Basic-and-Neutral.pdf
Exploring-Substances-Acidic-Basic-and-Neutral.pdf
Sandeep Swamy
 
SPRING FESTIVITIES - UK AND USA -
SPRING FESTIVITIES - UK AND USA            -SPRING FESTIVITIES - UK AND USA            -
SPRING FESTIVITIES - UK AND USA -
Colégio Santa Teresinha
 
SCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptx
SCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptxSCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptx
SCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptx
Ronisha Das
 
How to Subscribe Newsletter From Odoo 18 Website
How to Subscribe Newsletter From Odoo 18 WebsiteHow to Subscribe Newsletter From Odoo 18 Website
How to Subscribe Newsletter From Odoo 18 Website
Celine George
 
YSPH VMOC Special Report - Measles Outbreak Southwest US 5-3-2025.pptx
YSPH VMOC Special Report - Measles Outbreak  Southwest US 5-3-2025.pptxYSPH VMOC Special Report - Measles Outbreak  Southwest US 5-3-2025.pptx
YSPH VMOC Special Report - Measles Outbreak Southwest US 5-3-2025.pptx
Yale School of Public Health - The Virtual Medical Operations Center (VMOC)
 
One Hot encoding a revolution in Machine learning
One Hot encoding a revolution in Machine learningOne Hot encoding a revolution in Machine learning
One Hot encoding a revolution in Machine learning
momer9505
 
Metamorphosis: Life's Transformative Journey
Metamorphosis: Life's Transformative JourneyMetamorphosis: Life's Transformative Journey
Metamorphosis: Life's Transformative Journey
Arshad Shaikh
 
World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...
World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...
World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...
larencebapu132
 
How to manage Multiple Warehouses for multiple floors in odoo point of sale
How to manage Multiple Warehouses for multiple floors in odoo point of saleHow to manage Multiple Warehouses for multiple floors in odoo point of sale
How to manage Multiple Warehouses for multiple floors in odoo point of sale
Celine George
 
To study Digestive system of insect.pptx
To study Digestive system of insect.pptxTo study Digestive system of insect.pptx
To study Digestive system of insect.pptx
Arshad Shaikh
 
Anti-Depressants pharmacology 1slide.pptx
Anti-Depressants pharmacology 1slide.pptxAnti-Depressants pharmacology 1slide.pptx
Anti-Depressants pharmacology 1slide.pptx
Mayuri Chavan
 
Stein, Hunt, Green letter to Congress April 2025
Stein, Hunt, Green letter to Congress April 2025Stein, Hunt, Green letter to Congress April 2025
Stein, Hunt, Green letter to Congress April 2025
Mebane Rash
 
How to track Cost and Revenue using Analytic Accounts in odoo Accounting, App...
How to track Cost and Revenue using Analytic Accounts in odoo Accounting, App...How to track Cost and Revenue using Analytic Accounts in odoo Accounting, App...
How to track Cost and Revenue using Analytic Accounts in odoo Accounting, App...
Celine George
 
Multi-currency in odoo accounting and Update exchange rates automatically in ...
Multi-currency in odoo accounting and Update exchange rates automatically in ...Multi-currency in odoo accounting and Update exchange rates automatically in ...
Multi-currency in odoo accounting and Update exchange rates automatically in ...
Celine George
 
How to Customize Your Financial Reports & Tax Reports With Odoo 17 Accounting
How to Customize Your Financial Reports & Tax Reports With Odoo 17 AccountingHow to Customize Your Financial Reports & Tax Reports With Odoo 17 Accounting
How to Customize Your Financial Reports & Tax Reports With Odoo 17 Accounting
Celine George
 
LDMMIA Reiki Master Spring 2025 Mini Updates
LDMMIA Reiki Master Spring 2025 Mini UpdatesLDMMIA Reiki Master Spring 2025 Mini Updates
LDMMIA Reiki Master Spring 2025 Mini Updates
LDM Mia eStudios
 
Introduction to Vibe Coding and Vibe Engineering
Introduction to Vibe Coding and Vibe EngineeringIntroduction to Vibe Coding and Vibe Engineering
Introduction to Vibe Coding and Vibe Engineering
Damian T. Gordon
 
Sinhala_Male_Names.pdf Sinhala_Male_Name
Sinhala_Male_Names.pdf Sinhala_Male_NameSinhala_Male_Names.pdf Sinhala_Male_Name
Sinhala_Male_Names.pdf Sinhala_Male_Name
keshanf79
 
Geography Sem II Unit 1C Correlation of Geography with other school subjects
Geography Sem II Unit 1C Correlation of Geography with other school subjectsGeography Sem II Unit 1C Correlation of Geography with other school subjects
Geography Sem II Unit 1C Correlation of Geography with other school subjects
ProfDrShaikhImran
 
Exploring-Substances-Acidic-Basic-and-Neutral.pdf
Exploring-Substances-Acidic-Basic-and-Neutral.pdfExploring-Substances-Acidic-Basic-and-Neutral.pdf
Exploring-Substances-Acidic-Basic-and-Neutral.pdf
Sandeep Swamy
 
SCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptx
SCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptxSCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptx
SCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptx
Ronisha Das
 
How to Subscribe Newsletter From Odoo 18 Website
How to Subscribe Newsletter From Odoo 18 WebsiteHow to Subscribe Newsletter From Odoo 18 Website
How to Subscribe Newsletter From Odoo 18 Website
Celine George
 
One Hot encoding a revolution in Machine learning
One Hot encoding a revolution in Machine learningOne Hot encoding a revolution in Machine learning
One Hot encoding a revolution in Machine learning
momer9505
 
Metamorphosis: Life's Transformative Journey
Metamorphosis: Life's Transformative JourneyMetamorphosis: Life's Transformative Journey
Metamorphosis: Life's Transformative Journey
Arshad Shaikh
 
World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...
World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...
World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...
larencebapu132
 
How to manage Multiple Warehouses for multiple floors in odoo point of sale
How to manage Multiple Warehouses for multiple floors in odoo point of saleHow to manage Multiple Warehouses for multiple floors in odoo point of sale
How to manage Multiple Warehouses for multiple floors in odoo point of sale
Celine George
 
To study Digestive system of insect.pptx
To study Digestive system of insect.pptxTo study Digestive system of insect.pptx
To study Digestive system of insect.pptx
Arshad Shaikh
 
Anti-Depressants pharmacology 1slide.pptx
Anti-Depressants pharmacology 1slide.pptxAnti-Depressants pharmacology 1slide.pptx
Anti-Depressants pharmacology 1slide.pptx
Mayuri Chavan
 
Stein, Hunt, Green letter to Congress April 2025
Stein, Hunt, Green letter to Congress April 2025Stein, Hunt, Green letter to Congress April 2025
Stein, Hunt, Green letter to Congress April 2025
Mebane Rash
 

Intro to Game Programming

  • 1. Introduction To Game Programming EuroPython 2010 Richard Jones
  • 4. The Basics • Displaying something • Controlling animation
  • 5. The Basics • Displaying something • Controlling animation • User input
  • 6. The Basics • Displaying something • Controlling animation • User input • Gameplay mechanics
  • 7. The Basics • Displaying something • Controlling animation • User input • Gameplay mechanics • Playing sound effects and music
  • 8. The Basics • Displaying something • Controlling animation • User input • Gameplay mechanics • Playing sound effects and music • Game architecture
  • 11. Displaying Something • Opening a window • Reading images
  • 12. Displaying Something • Opening a window • Reading images • Displaying images
  • 13. Displaying Something • Opening a window • Reading images • Displaying images • Organising the display of images (scene composition)
  • 20. Opening a Window import cocos from cocos.director import director director.init() scene = cocos.scene.Scene() director.run(scene)
  • 21. Drawing import cocos from cocos.director import director director.init() scene = cocos.scene.Scene() sprite = cocos.sprite.Sprite('kitten.jpg') scene.add(sprite) director.run(scene)
  • 22. Anchoring (256, 256) 512 px 512 px
  • 25. Anchoring import cocos from cocos.director import director director.init() scene = cocos.scene.Scene() sprite = cocos.sprite.Sprite('kitten.jpg', anchor=(0,0)) scene.add(sprite) director.run(scene)
  • 26. Using a Layer import cocos from cocos.director import director director.init() scene = cocos.scene.Scene() layer = cocos.layer.Layer() scene.add(layer) sprite = cocos.sprite.Sprite('kitten.jpg', anchor=(0,0)) layer.add(sprite) director.run(scene)
  • 27. Animation import cocos from cocos import actions from cocos.director import director ... scene = cocos.scene.Scene() layer = cocos.layer.Layer() scene.add(layer) sprite = cocos.sprite.Sprite('kitten.jpg', anchor=(0,0)) layer.add(sprite) sprite.do(actions.MoveBy((100, 0))) director.run(scene)
  • 28. Getting Organised import cocos from cocos import actions from cocos.director import director class AsteroidsGame(cocos.scene.Scene): def __init__(self): super(AsteroidsGame, self).__init__() self.player = cocos.layer.Layer() self.add(self.player) self.ship = cocos.sprite.Sprite('data/ship.png', (width/2, height/2)) velocity = (100, 0) self.ship.do(actions.MoveBy(velocity)) self.player.add(self.ship) director.init() width, height = director.get_window_size() director.run(AsteroidsGame())
  • 29. Adding Asteroids import random import cocos from cocos import actions from cocos.director import director def create_asteroid(layer, size, position, speed): '''Create an asteroid of a certain size and speed. ''' s = cocos.sprite.Sprite('data/%s_asteroid.png' % size, position) s.size = size layer.add(s) velocity = (random.randint(-speed, speed), random.randint(-speed, speed)) dr = random.randint(-speed, speed) s.do(actions.Repeat(actions.MoveBy(velocity, 1) | actions.RotateBy(dr, 1))) ...
  • 30. Adding Asteroids ... super(AsteroidsGame, self).__init__() # place the asteroids in a layer by themselves self.asteroids = cocos.layer.Layer() self.add(self.asteroids) for i in range(3): # place asteroids at random positions around the screen position = (random.randint(0, width), random.randint(0, height)) create_asteroid(self.asteroids, 'big', position, 100) # place the player ship in another layer ...
  • 31. Better action ... s = cocos.sprite.Sprite('data/%s_asteroid.png' % size, position) s.size = size layer.add(s) s.velocity = (random.randint(-speed, speed), random.randint(-speed, speed)) s.dr = random.randint(-speed, speed) s.do(actions.Move()) ...
  • 32. Screen Wrapping ... s.velocity = (random.randint(-speed, speed), random.randint(-speed, speed)) s.dr = random.randint(-speed, speed) s.do(actions.WrappedMove(width, height)) ... self.ship.velocity = (100, 0) # move the ship kinematically and wrapped to the screen size self.ship.do(actions.WrappedMove(width, height)) self.player.add(self.ship) ...
  • 35. Gameplay Mechanics • Player Controls • Timed rules (when objects appear; moving the play field)
  • 36. Gameplay Mechanics • Player Controls • Timed rules (when objects appear; moving the play field) • Interaction of game objects
  • 37. Gameplay Mechanics • Player Controls • Timed rules (when objects appear; moving the play field) • Interaction of game objects • Detecting important events (game won or game over)
  • 40. User Input • Getting events • Distinct keyboard events vs. keyboard state
  • 41. Control import math import random from pyglet.window import key import cocos from cocos import actions from cocos.director import director
  • 42. Control y = speed x sin(rotation) ng) ho oti rs n, o er atio l a cce d (or s pee rotation x = speed x cos(rotation)
  • 43. Control x = speed x cos(rotation) y = speed x sin(-rotation) rotation spe ed (or acc ele rat ion , or sho oti ng)
  • 44. Control class MoveShip(actions.WrappedMove): def step(self, dt): super(MoveShip, self).step(dt) # set the rotation using the left and right arrow keys self.target.dr = (keys[key.RIGHT] - keys[key.LEFT]) * 360 # figure the x and y heading components from the rotation rotation = math.radians(self.target.rotation) rotation_x = math.cos(rotation) rotation_y = math.sin(-rotation) # accelerate along the heading acc = keys[key.UP] * 200 self.target.acceleration = (acc * rotation_x, acc * rotation_y)
  • 45. Control ... self.ship = cocos.sprite.Sprite('data/ship.png', (width/2, height/2)) self.ship.velocity = (0, 0) # animate the ship with our custom action self. ship.do(MoveShip(width, height)) self.player.add(self. ship) ...
  • 46. Control ... # open the window, get dimensions, watch the keyboard and run our scene director.init() width, height = director.get_window_size() keys = key.KeyStateHandler() director.window.push_handlers(keys) director.run(AsteriodsGame())
  • 49. Detecting Collisions • Pixel-Perfect • Axis-Aligned Bounding Box
  • 50. Detecting Collisions • Pixel-Perfect • Axis-Aligned Bounding Box • Circle-Circle
  • 51. Detecting Collisions • Pixel-Perfect • Axis-Aligned Bounding Box • Circle-Circle • Hash Map
  • 52. Detecting Collisions Pixel-Perfect
  • 53. Detecting Collisions Axis-Aligned Bounding Box
  • 54. Detecting Collisions Axis-Aligned Bounding Box
  • 55. Detecting Collisions Axis-Aligned Bounding Box
  • 56. Detecting Collisions Circle-Circle
  • 57. Detecting Collisions Circle-Circle
  • 58. Detecting Collisions Circle-Circle
  • 59. Detecting Collisions Circle-Circle
  • 60. Detecting Collisions Hash Map d = {(42,42): [ship], (43, 42): [ship], (44, 42): ship, ... (52, 45): [asteroid], (53, 45): [asteroid], ...}
  • 66. ... Collision self.target.acceleration = (acc * rotation_x, acc * rotation_y) def collide(a, b): '''Determine whether two objects with a center point and width (diameter) are colliding.''' distance = math.sqrt((a.x-b.x)**2 + (a.y-b.y)**2) return distance < (a.width/2 + b.width/2) class MoveAsteroid(actions.WrappedMove): def step(self, dt): super(MoveAsteroid, self).step(dt) # detect collision between this asteroid and the ship if collide(self.target, director.scene.ship): quit('GAME OVER') def create_asteroid(layer, size, position, speed): ...
  • 67. Collision def create_asteroid(layer, size, position, speed): '''Create an asteroid of a certain size and speed. ''' s = cocos.sprite.Sprite('data/%s_asteroid.png' % size, position) s.size = size layer.add(s) s.velocity = (random.randint(-speed, speed), random.randint(-speed, speed)) s.dr = random.randint(-speed, speed) s.do(MoveAsteroid(width, height)) ...
  • 68. Shooting ... self.target.acceleration = (acc * rotation_x, acc * rotation_y) if self.target.gun_cooldown: # still limiting the gun rate of fire self.target.gun_cooldown = max(0, self.target.gun_cooldown - dt) elif keys[key.SPACE]: # fire a bullet from the ship b = cocos.sprite.Sprite('data/bullet.png', (self.target.x, self.target.y)) # send it in the same heading as the ship b.velocity = (rotation_x * 400, rotation_y * 400) # the bullet has a lifespan of 1 second b.life = 1 director.scene.player.add(b) # move the bullet with its custom action b.do(MoveBullet(width, height)) # ship may only shoot twice per second self.target.gun_cooldown = .5 ...
  • 69. Shooting class MoveBullet(actions.WrappedMove): def step(self, dt): super(MoveBullet, self).step(dt) # age the bullet self.target.life -= dt if self.target.life < 0: # remove from play if it's too old self.target.kill() return # see if the bullet hits any asteroids for asteroid in director.scene.asteroids.get_children(): if collide(self.target, asteroid): # remove the bullet and asteroid self.target.kill() asteroid.kill() return
  • 70. ... and winning ... super(MoveShip, self).step(dt) # if there's no asteroids left then the player has won if not director.scene.asteroids.children: quit('YOU WIN') # set the rotation using the left and right arrow keys self.target.dr = (keys[key.RIGHT] - keys[key.LEFT]) * 360 ...
  • 71. Creating chunks def create_asteroid(layer, size, position, velocity, rotation, speed): '''Create an asteroid of a certain size, possibly inheriting its parent's velocity and rotation. ''' s = cocos.sprite.Sprite('data/%s_asteroid.png' % size, position) s.size = size dx, dy = velocity s.velocity = (dx + random.randint(-speed, speed), dy + random.randint(-speed, speed)) s.dr = rotation + random.randint(-speed, speed) layer.add(s) s.do(MoveAsteroid(width, height))
  • 72. Creating chunks for asteroid in director.scene.asteroids.get_children(): if collide(self.target, asteroid): # remove the bullet and asteroid, create new smaller # asteroid self.target.kill() create_smaller_asteroids(asteroid) asteroid.kill() return
  • 73. Creating chunks ... position = (random.randint(0, width), random.randint(0, height)) create_asteroid(self.asteroids, 'big', position, (0, 0), 0, 100) def create_smaller_asteroids(asteroid): asteroids = director.scene.asteroids if asteroid.size == 'big': # if it's a big asteroid then make two medium asteroids in # its place for i in range(2): create_asteroid(asteroids, 'medium', asteroid.position, asteroid.velocity, asteroid.dr, 50) elif asteroid.size == 'medium': # if it's a medium asteroid then make two small asteroids in # its place for i in range(2): create_asteroid(asteroids, 'small', asteroid.position, asteroid.velocity, asteroid.dr, 50)
  • 74. Sound
  • 76. Sound • Reading sound files • Playing sounds and background music
  • 77. Sound Effects import math import random import pyglet from pyglet.window import key import cocos from cocos import actions from cocos.director import director # load our sound effects explosion_sound = pyglet.media.load('data/explosion.wav', streaming=False) bullet_sound = pyglet.media.load('data/bullet.wav', streaming=False) ...
  • 78. Sound Effects ... # ship may only shoot twice per second self.target.gun_cooldown = .5 bullet_sound.play() ...
  • 79. Sound Effects ... create_smaller_asteroids(asteroid) asteroid.kill() explosion_sound.play() return
  • 82. Game Architecture • Player lives • Game won / game over screen
  • 83. Game Architecture • Player lives • Game won / game over screen • Opening screen
  • 84. Game Architecture • Player lives • Game won / game over screen • Opening screen • Options menu
  • 85. Invulnerability class Ship(cocos.sprite.Sprite): gun_cooldown = 0 velocity = (0, 0) is_invulnerable = False def set_invulnerable(self): self.do(actions.Blink(10, 1) + actions.CallFunc(self.set_vulnerable)) self.is_invulnerable = True def set_vulnerable(self): self.is_invulnerable = False
  • 86. Invulnerability self.player = cocos.layer.Layer() self.add(self.player) self.ship = Ship('data/ship.png', (width/2, height/2)) self.player.add(self.ship) # animate the ship with our custom action self.ship.do(MoveShip(width, height)) self.ship.set_invulnerable()
  • 87. Invulnerability super(MoveAsteroid, self).step(dt) if director.scene.ship.is_invulnerable: return # detect collision between this asteroid and the ship if collide(self.target, director.scene.ship): quit('GAME OVER')
  • 88. Lives self.ship.set_invulnerable() self.player.add(self.ship) # another layer for the "HUD" or front informational display self.hud = cocos.layer.Layer() self.add(self.hud) self.lives = cocos.text.Label('Lives: 3', font_size=20, y=height, anchor_y='top') self.lives.counter = 3 self.hud.add(self.lives)
  • 89. Lives # detect collision between this asteroid and the ship if collide(self.target, director.scene.ship): lives = director.scene.lives lives.counter -= 1 director.scene.ship.set_invulnerable() if not lives.counter: quit('GAME OVER') else: lives.element.text = 'Lives: %d' % lives.counter
  • 90. Scenes class MessageScene(cocos.scene.Scene): def __init__(self, text): super(MessageScene, self).__init__() class UserActivity(cocos.layer.Layer): is_event_handler = True def on_mouse_press(*args): director.pop() def on_text(*args): director.pop() layer = UserActivity() self.add(layer) t = cocos.text.Label(text, font_size=40, x=width/2, anchor_x='center', y=height/2, anchor_y='center') layer.add(t)
  • 91. Scenes # if there's no asteroids left then the player has won if not director.scene.asteroids.children: director.replace(MessageScene('You Win')) # set the rotation using the left and right arrow keys self.target.dr = (keys[key.RIGHT] - keys[key.LEFT]) * 360 ... lives.counter -= 1 director.scene.ship.set_invulnerable() if not lives.counter: director.replace(MessageScene('Game Over')) else: lives.element.text = 'Lives: %d' % lives.counter
  • 92. Menu class MenuScene(cocos.scene.Scene): def __init__(self): super(MenuScene, self).__init__() # opening menu menu = cocos.menu.Menu("Asteroids!!!!") menu.create_menu([ cocos.menu.MenuItem('Play', lambda: director.push(AsteroidsGame())), cocos.menu.MenuItem('Quit', pyglet.app.exit), ]) menu.on_quit = pyglet.app.exit self.add(menu) # open the window, get dimensions, watch the keyboard and run our scene director.init() width, height = director.get_window_size() keys = key.KeyStateHandler() director.window.push_handlers(keys) director.run(MenuScene())
  • 94. Special Effects • Simple image animations
  • 95. Special Effects • Simple image animations • Use libraries like lepton
  • 97. Controlling Animation • Image position on screen
  • 98. Controlling Animation • Image position on screen • Updates over time
  • 99. Controlling Animation • Image position on screen • Updates over time • Accounting for frame rate
  • 100. Controlling Animation • Image position on screen • Updates over time • Accounting for frame rate • Frame to use from multiple images
  • 104. Special Effects ... explosion_sound = pyglet.media.load('data/explosion.wav', streaming=False) bullet_sound = pyglet.media.load('data/bullet.wav', streaming=False) # load our explosion animation explosion = pyglet.image.load('data/explosion.png') explosion_grid = pyglet.image.ImageGrid(explosion, 2, 8) explosion = explosion_grid.get_animation(.05, False) ...
  • 105. Special Effects # remove the bullet and asteroid, create new smaller # asteroid self.target.kill() s = cocos.sprite.Sprite(explosion, self.target.position) s.velocity = asteroid.velocity s.do(actions.WrappedMove(width, height) | (actions.Delay(.05 * 16) + actions.CallFuncS(lambda s: s.kill()))) self.target.parent.add(s) create_smaller_asteroids(asteroid) asteroid.kill()
  • 106. Other Game Types • minesweeper • car driving • platformer • tower defence
  • 107. Minesweeper • rendering a grid of cells • detecting mouse clicks on cells • exposing contents
  • 108. Car Driving • different movement model • detecting correct circuit • detecting collision with edge of track (pixel-based collision detection)
  • 109. Platformer • rendering game layers • handling triggers • platformer physics
  • 110. Tower Defence • tower placement (selection & position) • movement solution for creeps
  • 111. Other Things • kytten GUI controls for pyglet / cocos2d • cocograph map editing
  • 112. Where To From Here? • http://los-cocos.org • http://pyglet.org • http://pygame.org • http://inventwithpython.com/ • http://pyweek.org

Editor's Notes

  • #20: A Sprite is an image that knows how to draw itself on the screen.
  • #21: The default anchor point in cocos2d is the center of the sprite image.
  • #40: Unfortunately cocos2d rotates clockwise around Z, whereas pyglet (and basic trigenometry) rotates anti-clockwise, so we must negate the rotation to determine the correct y value.
  • #93: Make life easier for yourself - make all your animation frames the same size!
  • #94: Make life easier for yourself - make all your animation frames the same size!
  • #96: pyglet will sequence a grid of images from the bottom left corner taking each row, and then each cell in turn