SlideShare a Scribd company logo
1 of 112
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

More Related Content

What's hot

Making Games in JavaScript
Making Games in JavaScriptMaking Games in JavaScript
Making Games in JavaScriptSam 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 84Mahmoud 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 DetectionJenchoke Tachagomain
 
Mobile Game and Application with J2ME
Mobile Gameand Application with J2MEMobile Gameand Application with J2ME
Mobile Game and Application with J2MEJenchoke Tachagomain
 
Expand/Collapse animation on Android
Expand/Collapse animation on AndroidExpand/Collapse animation on Android
Expand/Collapse animation on AndroidPavlo 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 212Mahmoud 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 212Mahmoud Samir Fayed
 
Pybelsberg — Constraint-based Programming in Python
Pybelsberg — Constraint-based Programming in PythonPybelsberg — Constraint-based Programming in Python
Pybelsberg — Constraint-based Programming in PythonChristoph 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 overviewWannitaTolaema
 
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 84Mahmoud 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 181Mahmoud Samir Fayed
 
Functional Systems @ Twitter
Functional Systems @ TwitterFunctional Systems @ Twitter
Functional Systems @ TwitterC4Media
 
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 31Mahmoud Samir Fayed
 

What's hot (20)

Corona sdk
Corona sdkCorona sdk
Corona sdk
 
Making Games in JavaScript
Making Games in JavaScriptMaking Games in JavaScript
Making Games in JavaScript
 
ES6(ES2015) is beautiful
ES6(ES2015) is beautifulES6(ES2015) is beautiful
ES6(ES2015) is beautiful
 
Proga 0622
Proga 0622Proga 0622
Proga 0622
 
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
 
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
 
Mobile Game and Application with J2ME
Mobile Gameand Application with J2MEMobile Gameand Application with J2ME
Mobile Game and Application with J2ME
 
Expand/Collapse animation on Android
Expand/Collapse animation on AndroidExpand/Collapse animation on Android
Expand/Collapse animation on Android
 
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
 
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
 
pptuni1
pptuni1pptuni1
pptuni1
 
Pybelsberg — Constraint-based Programming in Python
Pybelsberg — Constraint-based Programming in PythonPybelsberg — Constraint-based Programming in Python
Pybelsberg — Constraint-based Programming in Python
 
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...
 
Cocos2dx 7.1-7.2
Cocos2dx 7.1-7.2Cocos2dx 7.1-7.2
Cocos2dx 7.1-7.2
 
SwiftUI Animation - The basic overview
SwiftUI Animation - The basic overviewSwiftUI Animation - The basic overview
SwiftUI Animation - The basic overview
 
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
 
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
 
Functional Systems @ Twitter
Functional Systems @ TwitterFunctional Systems @ Twitter
Functional Systems @ Twitter
 
modm
modmmodm
modm
 
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
 

Similar to Intro to Game Programming

Макс Грибов — Использование 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 SpockAlexander 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 Cocos2dVinsol
 
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 CanvasSteve 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 189Mahmoud 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 KotenkoBeMyApp
 
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 SwiftGiordano Scalzo
 
Silverlight as a Gaming Platform
Silverlight as a Gaming PlatformSilverlight as a Gaming Platform
Silverlight as a Gaming Platformgoodfriday
 
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 codeLaurence Svekis ✔
 
Processing and Processing.js
Processing and Processing.jsProcessing and Processing.js
Processing and Processing.jsjeresig
 
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 #3Jay Coskey
 
Pointer Events in Canvas
Pointer Events in CanvasPointer Events in Canvas
Pointer Events in Canvasdeanhudson
 
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.docxchristinemaritza
 

Similar to Intro to Game Programming (20)

Shootting Game
Shootting GameShootting Game
Shootting Game
 
Game dev 101 part 3
Game dev 101 part 3Game dev 101 part 3
Game dev 101 part 3
 
Макс Грибов — Использование SpriteKit в неигровых приложениях
Макс Грибов — Использование SpriteKit в неигровых приложенияхМакс Грибов — Использование SpriteKit в неигровых приложениях
Макс Грибов — Использование SpriteKit в неигровых приложениях
 
Testing a 2D Platformer with Spock
Testing a 2D Platformer with SpockTesting a 2D Platformer with Spock
Testing a 2D Platformer with Spock
 
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
 
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
 
Game age ppt
Game age pptGame age ppt
Game age ppt
 
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
 
Swift, via "swift-2048"
Swift, via "swift-2048"Swift, via "swift-2048"
Swift, via "swift-2048"
 
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
 
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
 
Silverlight as a Gaming Platform
Silverlight as a Gaming PlatformSilverlight as a Gaming Platform
Silverlight as a Gaming Platform
 
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
 
Rxjs kyivjs 2015
Rxjs kyivjs 2015Rxjs kyivjs 2015
Rxjs kyivjs 2015
 
Processing and Processing.js
Processing and Processing.jsProcessing and Processing.js
Processing and Processing.js
 
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
 
Pointer Events in Canvas
Pointer Events in CanvasPointer Events in Canvas
Pointer Events in Canvas
 
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
 

More from Richard Jones

Introduction to Game Programming
Introduction to Game ProgrammingIntroduction to Game Programming
Introduction to Game ProgrammingRichard Jones
 
Message Queueing - by an MQ noob
Message Queueing - by an MQ noobMessage Queueing - by an MQ noob
Message Queueing - by an MQ noobRichard 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.6Richard 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.5Richard 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.4Richard Jones
 
Tkinter Does Not Suck
Tkinter Does Not SuckTkinter Does Not Suck
Tkinter Does Not SuckRichard Jones
 

More from Richard Jones (11)

Angboard
AngboardAngboard
Angboard
 
Don't do this
Don't do thisDon't do this
Don't do this
 
Introduction to Game Programming
Introduction to Game ProgrammingIntroduction to Game Programming
Introduction to Game Programming
 
Message Queueing - by an MQ noob
Message Queueing - by an MQ noobMessage Queueing - by an MQ noob
Message Queueing - by an MQ noob
 
Message queueing
Message queueingMessage queueing
Message queueing
 
Web micro-framework BATTLE!
Web micro-framework BATTLE!Web micro-framework BATTLE!
Web micro-framework BATTLE!
 
State of Python (2010)
State of Python (2010)State of Python (2010)
State of Python (2010)
 
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
 
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
 
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
 
Tkinter Does Not Suck
Tkinter Does Not SuckTkinter Does Not Suck
Tkinter Does Not Suck
 

Recently uploaded

Beauty Amidst the Bytes_ Unearthing Unexpected Advantages of the Digital Wast...
Beauty Amidst the Bytes_ Unearthing Unexpected Advantages of the Digital Wast...Beauty Amidst the Bytes_ Unearthing Unexpected Advantages of the Digital Wast...
Beauty Amidst the Bytes_ Unearthing Unexpected Advantages of the Digital Wast...DhatriParmar
 
Q4-PPT-Music9_Lesson-1-Romantic-Opera.pptx
Q4-PPT-Music9_Lesson-1-Romantic-Opera.pptxQ4-PPT-Music9_Lesson-1-Romantic-Opera.pptx
Q4-PPT-Music9_Lesson-1-Romantic-Opera.pptxlancelewisportillo
 
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...Association for Project Management
 
4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptx4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptxmary850239
 
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptxINTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptxHumphrey A Beña
 
MS4 level being good citizen -imperative- (1) (1).pdf
MS4 level   being good citizen -imperative- (1) (1).pdfMS4 level   being good citizen -imperative- (1) (1).pdf
MS4 level being good citizen -imperative- (1) (1).pdfMr Bounab Samir
 
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptxDIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptxMichelleTuguinay1
 
ClimART Action | eTwinning Project
ClimART Action    |    eTwinning ProjectClimART Action    |    eTwinning Project
ClimART Action | eTwinning Projectjordimapav
 
BIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptx
BIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptxBIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptx
BIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptxSayali Powar
 
4.11.24 Poverty and Inequality in America.pptx
4.11.24 Poverty and Inequality in America.pptx4.11.24 Poverty and Inequality in America.pptx
4.11.24 Poverty and Inequality in America.pptxmary850239
 
Narcotic and Non Narcotic Analgesic..pdf
Narcotic and Non Narcotic Analgesic..pdfNarcotic and Non Narcotic Analgesic..pdf
Narcotic and Non Narcotic Analgesic..pdfPrerana Jadhav
 
Scientific Writing :Research Discourse
Scientific  Writing :Research  DiscourseScientific  Writing :Research  Discourse
Scientific Writing :Research DiscourseAnita GoswamiGiri
 
Daily Lesson Plan in Mathematics Quarter 4
Daily Lesson Plan in Mathematics Quarter 4Daily Lesson Plan in Mathematics Quarter 4
Daily Lesson Plan in Mathematics Quarter 4JOYLYNSAMANIEGO
 
Using Grammatical Signals Suitable to Patterns of Idea Development
Using Grammatical Signals Suitable to Patterns of Idea DevelopmentUsing Grammatical Signals Suitable to Patterns of Idea Development
Using Grammatical Signals Suitable to Patterns of Idea Developmentchesterberbo7
 
Man or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptx
Man or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptxMan or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptx
Man or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptxDhatriParmar
 
Oppenheimer Film Discussion for Philosophy and Film
Oppenheimer Film Discussion for Philosophy and FilmOppenheimer Film Discussion for Philosophy and Film
Oppenheimer Film Discussion for Philosophy and FilmStan Meyer
 
Mental Health Awareness - a toolkit for supporting young minds
Mental Health Awareness - a toolkit for supporting young mindsMental Health Awareness - a toolkit for supporting young minds
Mental Health Awareness - a toolkit for supporting young mindsPooky Knightsmith
 
Unraveling Hypertext_ Analyzing Postmodern Elements in Literature.pptx
Unraveling Hypertext_ Analyzing  Postmodern Elements in  Literature.pptxUnraveling Hypertext_ Analyzing  Postmodern Elements in  Literature.pptx
Unraveling Hypertext_ Analyzing Postmodern Elements in Literature.pptxDhatriParmar
 
Q-Factor General Quiz-7th April 2024, Quiz Club NITW
Q-Factor General Quiz-7th April 2024, Quiz Club NITWQ-Factor General Quiz-7th April 2024, Quiz Club NITW
Q-Factor General Quiz-7th April 2024, Quiz Club NITWQuiz Club NITW
 
ICS2208 Lecture6 Notes for SL spaces.pdf
ICS2208 Lecture6 Notes for SL spaces.pdfICS2208 Lecture6 Notes for SL spaces.pdf
ICS2208 Lecture6 Notes for SL spaces.pdfVanessa Camilleri
 

Recently uploaded (20)

Beauty Amidst the Bytes_ Unearthing Unexpected Advantages of the Digital Wast...
Beauty Amidst the Bytes_ Unearthing Unexpected Advantages of the Digital Wast...Beauty Amidst the Bytes_ Unearthing Unexpected Advantages of the Digital Wast...
Beauty Amidst the Bytes_ Unearthing Unexpected Advantages of the Digital Wast...
 
Q4-PPT-Music9_Lesson-1-Romantic-Opera.pptx
Q4-PPT-Music9_Lesson-1-Romantic-Opera.pptxQ4-PPT-Music9_Lesson-1-Romantic-Opera.pptx
Q4-PPT-Music9_Lesson-1-Romantic-Opera.pptx
 
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
 
4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptx4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptx
 
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptxINTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
 
MS4 level being good citizen -imperative- (1) (1).pdf
MS4 level   being good citizen -imperative- (1) (1).pdfMS4 level   being good citizen -imperative- (1) (1).pdf
MS4 level being good citizen -imperative- (1) (1).pdf
 
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptxDIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
 
ClimART Action | eTwinning Project
ClimART Action    |    eTwinning ProjectClimART Action    |    eTwinning Project
ClimART Action | eTwinning Project
 
BIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptx
BIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptxBIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptx
BIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptx
 
4.11.24 Poverty and Inequality in America.pptx
4.11.24 Poverty and Inequality in America.pptx4.11.24 Poverty and Inequality in America.pptx
4.11.24 Poverty and Inequality in America.pptx
 
Narcotic and Non Narcotic Analgesic..pdf
Narcotic and Non Narcotic Analgesic..pdfNarcotic and Non Narcotic Analgesic..pdf
Narcotic and Non Narcotic Analgesic..pdf
 
Scientific Writing :Research Discourse
Scientific  Writing :Research  DiscourseScientific  Writing :Research  Discourse
Scientific Writing :Research Discourse
 
Daily Lesson Plan in Mathematics Quarter 4
Daily Lesson Plan in Mathematics Quarter 4Daily Lesson Plan in Mathematics Quarter 4
Daily Lesson Plan in Mathematics Quarter 4
 
Using Grammatical Signals Suitable to Patterns of Idea Development
Using Grammatical Signals Suitable to Patterns of Idea DevelopmentUsing Grammatical Signals Suitable to Patterns of Idea Development
Using Grammatical Signals Suitable to Patterns of Idea Development
 
Man or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptx
Man or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptxMan or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptx
Man or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptx
 
Oppenheimer Film Discussion for Philosophy and Film
Oppenheimer Film Discussion for Philosophy and FilmOppenheimer Film Discussion for Philosophy and Film
Oppenheimer Film Discussion for Philosophy and Film
 
Mental Health Awareness - a toolkit for supporting young minds
Mental Health Awareness - a toolkit for supporting young mindsMental Health Awareness - a toolkit for supporting young minds
Mental Health Awareness - a toolkit for supporting young minds
 
Unraveling Hypertext_ Analyzing Postmodern Elements in Literature.pptx
Unraveling Hypertext_ Analyzing  Postmodern Elements in  Literature.pptxUnraveling Hypertext_ Analyzing  Postmodern Elements in  Literature.pptx
Unraveling Hypertext_ Analyzing Postmodern Elements in Literature.pptx
 
Q-Factor General Quiz-7th April 2024, Quiz Club NITW
Q-Factor General Quiz-7th April 2024, Quiz Club NITWQ-Factor General Quiz-7th April 2024, Quiz Club NITW
Q-Factor General Quiz-7th April 2024, Quiz Club NITW
 
ICS2208 Lecture6 Notes for SL spaces.pdf
ICS2208 Lecture6 Notes for SL spaces.pdfICS2208 Lecture6 Notes for SL spaces.pdf
ICS2208 Lecture6 Notes for SL spaces.pdf
 

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

  1. A Sprite is an image that knows how to draw itself on the screen.
  2. The default anchor point in cocos2d is the center of the sprite image.
  3. 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.
  4. Make life easier for yourself - make all your animation frames the same size!
  5. Make life easier for yourself - make all your animation frames the same size!
  6. pyglet will sequence a grid of images from the bottom left corner taking each row, and then each cell in turn