SlideShare a Scribd company logo
Game Programming
      LCA 2010
     Richard Jones
The Basics
• Displaying something
• Controlling animation
• User input
• Gameplay mechanics
• Playing sound effects and music
• Further stuff
Displaying Something

• Opening a window
• Reading images
• Displaying images
Controlling Animation

• Image position on screen
• Updates over time
• Accounting for frame rate
User Input


• Getting events
• Distinct keyboard events vs. keyboard state
Gameplay Mechanics


• Interaction of game objects
• Detecting important events (game won or
  game over)
Detecting Collisions

• Pixel-Perfect
• Axis-Aligned Bounding Box
• Circle-Circle
• Hash Map
Sound


• Reading sound files
• Playing sounds and background music
Opening a Window

 import pyglet

 w = pyglet.window.Window()

 pyglet.app.run()
Clearing the Window
  import pyglet

  w = pyglet.window.Window()

  @w.event
  def on_draw():
     w.clear()

  pyglet.app.run()
Drawing
import pyglet

w = pyglet.window.Window()

ship_image = pyglet.image.load('data/ship.png')

@w.event
def on_draw():
   w.clear()
   ship_image.blit(100, 100)

pyglet.app.run()
Better Drawing
import pyglet

w = pyglet.window.Window()

ship_image = pyglet.image.load('data/ship.png')
ship = pyglet.sprite.Sprite(ship_image)
ship.position = (100, 100)

@w.event
def on_draw():
   w.clear()
   ship_image.blit(100, 100)
   ship.draw()

pyglet.app.run()
Animation
...
   w.clear()
   ship.draw()

def update(dt):
    ship.x += 1

pyglet.clock.schedule_interval(update, 1./30)

pyglet.app.run()
Better Animation
 ...
    w.clear()
    ship.draw()

 def update(dt):
     ship.x += 1
     ship.x += 100 * dt

 pyglet.clock.schedule_interval(update, 1./30)

 pyglet.app.run()
Adding Asteroids
 import random
 import pyglet

 w = pyglet.window.Window()

 def center_anchor(img):
     img.anchor_x = img.width / 2
     img.anchor_y = img.height / 2

 ...
Adding Asteroids
...
ship_image = pyglet.image.load('data/ship.png')
center_anchor(ship_image)
ship = pyglet.sprite.Sprite(ship_image)
ship.position = (100, 100)

big_asteroid_image = pyglet.image.load('data/big_asteroid.png')
center_anchor(big_asteroid_image)
asteroids = []
for i in range(3):
    x = random.randint(0, w.width)
    y = random.randint(0, w.height)
    s = pyglet.sprite.Sprite(big_asteroid_image, x, y)
    s.dx = random.randint(-100, 100)
    s.dy = random.randint(-100, 100)
    asteroids.append(s)

@w.event
...
Adding Asteroids

   ...
   @w.event
   def on_draw():
       w.clear()
       for asteroid in asteroids:
           asteroid.draw()
       ship.draw()
   ...
Adding Asteroids

  ...
  def update(dt):
      ship.x += 100 * dt
      for asteroid in asteroids:
          asteroid.x += asteroid.dx*dt
          asteroid.y += asteroid.dy*dt
  ...
A Little Refactoring

   ...
   ship = pyglet.sprite.Sprite(ship_image)
   ship.position = (100, 100)
   ship.dx = 100
   ship.dy = 0

   ...
Screen Wrapping
  ...
  def update(dt):
      ship.x += 100 * dt
      for asteroid in asteroids:
          asteroid.x += asteroid.dx*dt
          asteroid.y += asteroid.dy*dt
      for a in asteroids + [ship]:
          a.x += a.dx*dt
          a.y += a.dy*dt
          if a.x - a.width/2 > w.width:
              a.x -= w.width + a.width
          elif a.x + a.width/2 < 0:
              a.x += w.width + a.width
          if a.y - a.height/2 > w.height:
              a.y -= w.height + a.height
          elif a.y + a.height/2 < 0:
              a.y += w.height + a.height
  ...
Control

import math
import random
import pyglet

w = pyglet.window.Window()

...
Control
...
keys = pyglet.window.key.KeyStateHandler()
w.push_handlers(keys)

def update(dt):
    if keys[pyglet.window.key.LEFT]:
        ship.rotation -= 360*dt
    if keys[pyglet.window.key.RIGHT]:
        ship.rotation += 360*dt
    rotation = math.radians(ship.rotation)
    rotation_x = math.cos(-rotation)
    rotation_y = math.sin(-rotation)
    if keys[pyglet.window.key.UP]:
        ship.dx += 200 * rotation_x * dt
        ship.dy += 200 * rotation_y * dt

   for a in asteroids + [ship]:
   ...
Rotation

...
ship = pyglet.sprite.Sprite(ship_image)
ship.position = (100, 100)
ship.dx = 100
ship.dy = 0
ship.position = (w.width/2, w.height/2)
ship.dx = ship.dy = ship.dr = 0

...
Rotation

      ...
      s = pyglet.sprite.Sprite(big_asteroid_image, x, y)
      s.dx = random.randint(-100, 100)
      s.dy = random.randint(-100, 100)
      s.dr = random.randint(-100, 100)
      asteroids.append(s)

...
Rotation
...
def update(dt):
    if keys[pyglet.window.key.LEFT]:
        ship.rotation -= 360*dt
    if keys[pyglet.window.key.RIGHT]:
        ship.rotation += 360*dt
    ship.dr = (keys[pyglet.window.key.RIGHT] - keys[pyglet.window.key.LEFT]) * 360
    rotation = math.pi * ship.rotation / 180.0
    ...
    for a in asteroids + [ship]:
        a.x += a.dx*dt
        a.y += a.dy*dt
        a.rotation += a.dr * dt
        if a.x - a.width/2 > w.width:
            a.x -= w.width + a.width
Collision Detection
Collision Detection
Collision Detection
Collision Detection
Collision Detection

       distance
Collision Detection

  import   sys
  import   math
  import   random
  import   pyglet

  w = pyglet.window.Window()
  ...
Collision Detection

 ...
 w.push_handlers(keys)

 def distance(a, b):
     return math.sqrt((a.x-b.x)**2 + (a.y-b.y)**2)

 def update(dt):
     ...
Collision Detection

       ...
       elif a.y + a.height/2 < 0:
           a.y += w.height + a.height

   for a in asteroids:
       if distance(a, ship) < (a.width/2 + ship.width/2):
           sys.exit('GAME OVER')

pyglet.clock.schedule_interval(update, 1./30)
...
Shooting

ship.position = (w.width/2, w.height/2)
ship.dx = ship.dy = ship.dr = 0
ship.gun_cooldown = 0

bullet_image = pyglet.image.load('data/bullet.png')
center_anchor(bullet_image)
bullets = []

...
...
             Shooting
    ship.dy += 200 * rotation_y * dt

if ship.gun_cooldown:
    ship.gun_cooldown = max(0, ship.gun_cooldown - dt)
elif keys[pyglet.window.key.SPACE] and len(bullets) < 2:
    b = pyglet.sprite.Sprite(bullet_image, ship.x, ship.y)
    b.dx = rotation_x * 500
    b.dy = rotation_y * 500
    b.dr = 0
    b.life = 1
    bullets.append(b)
    ship.gun_cooldown = .5

for b in list(bullets):
    b.life -= dt
    if b.life < 0:
        bullets.remove(b)

for a in asteroids + [ship]:
for a in asteroids + [ship] + bullets:
     a.x += a.dx*dt
     ...
Shooting

...
@w.event
def on_draw():
    w.clear()
    for asteroid in asteroids:
         asteroid.draw()
    for s in asteroids + bullets:
        s.draw()
    ship.draw()
...
Shooting ... and Hitting

   ...
   def distance(a, b):
       return math.sqrt((a.x-b.x)**2 + (a.y-b.y)**2)
   def collide(a, b):
       return distance(a, b) < (a.width/2 + b.width/2)
   ...
Shooting ... and Hitting
        ...
        elif a.y + a.height/2 < 0:
            a.y += w.height + a.height

    for a in asteroids:
        if distance(a, ship) < (a.width/2 + ship.width/2):
            sys.exit('GAME OVER')
    for a in list(asteroids):
        if collide(a, ship):
            sys.exit('GAME OVER')
        for b in list(bullets):
            if collide(a, b):
                bullets.remove(b)
                asteroids.remove(a)

    if not asteroids:
        sys.exit('YOU WIN')

 pyglet.clock.schedule_interval(update, 1./30)
 ...
Chunks

...
center_anchor(bullet_image)
bullets = []

small_asteroid_image = pyglet.image.load('data/small_asteroid.png')
center_anchor(small_asteroid_image)
medium_asteroid_image = pyglet.image.load('data/medium_asteroid.png')
center_anchor(medium_asteroid_image)
big_asteroid_image = pyglet.image.load('data/big_asteroid.png')
center_anchor(big_asteroid_image)
...
...
                          Chunks
   for b in list(bullets):
       if collide(a, b):
           bullets.remove(b)
           asteroids.remove(a)
           if a.image is big_asteroid_image.texture:
               for i in range(2):
                   s = pyglet.sprite.Sprite(medium_asteroid_image, a.x, a.y)
                   s.dx = a.dx + random.randint(-50, 50)
                   s.dy = a.dy + random.randint(-50, 50)
                   s.dr = a.dr + random.randint(-50, 50)
                   asteroids.append(s)
           elif a.image is medium_asteroid_image.texture:
               for i in range(2):
                   s = pyglet.sprite.Sprite(small_asteroid_image, a.x, a.y)
                   s.dx = a.dx + random.randint(-50, 50)
                   s.dy = a.dy + random.randint(-50, 50)
                   s.dr = a.dr + random.randint(-50, 50)
                   asteroids.append(s)

if not asteroids:
    sys.exit('YOU WIN')
...
Sound Effects

...
      asteroids.append(s)

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

@w.event
def on_draw():
...
Sound Effects

     ...
     bullets.append(b)
     ship.gun_cooldown = .5
     bullet_sound.play()

  for b in list(bullets):
  ...
Sound Effects

...
bullets.remove(b)
asteroids.remove(a)
explosion_sound.play()
if a.image is big_asteroid_image.texture:
Further Stuff

• Opening screen
• Options menu
• Game won / game over screen
• Special effects
Other screen / menu


• Use libraries like Cocos2d (Scenes, Layers,
  Sprites, Animations)
Special Effects


• Simple image animations
• Use libraries like lepton
Where To From Here?

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

Recommended

Intro to Game Programming
Intro to Game Programming
Richard Jones
 
The Ring programming language version 1.8 book - Part 59 of 202
The Ring programming language version 1.8 book - Part 59 of 202
Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 70 of 212
The Ring programming language version 1.10 book - Part 70 of 212
Mahmoud Samir Fayed
 
Real life XNA
Real life XNA
Johan Lindfors
 
Raspberry Pi à la GroovyFX
Raspberry Pi à la GroovyFX
Stephen Chin
 
Corona sdk
Corona sdk
Dom Dominic Toretto
 
Node meetup feb_20_12
Node meetup feb_20_12
jafar104
 
The 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.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 Game and Application with J2ME - Collision Detection
Jenchoke Tachagomain
 
Mobile Game and Application with J2ME
Mobile Game and Application with J2ME
Jenchoke Tachagomain
 
The Ring programming language version 1.5.1 book - Part 51 of 180
The Ring programming language version 1.5.1 book - Part 51 of 180
Mahmoud Samir Fayed
 
pptuni1
pptuni1
Sachin Yadav
 
libGDX: Tiled Maps
libGDX: Tiled Maps
Jussi Pohjolainen
 
The 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
 
Box2D and libGDX
Box2D and libGDX
Jussi Pohjolainen
 
Александр Зимин – Анимация как средство самовыражения
Александр Зимин – Анимация как средство самовыражения
CocoaHeads
 
Implementing a Simple Game using libGDX
Implementing a Simple Game using libGDX
Jussi Pohjolainen
 
ES6(ES2015) is beautiful
ES6(ES2015) is beautiful
monikagupta18jan
 
λ | Lenses
λ | Lenses
Open-IT
 
Proga 0622
Proga 0622
Atsushi Tadokoro
 
The 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
 
libGDX: User Input and Frame by Frame Animation
libGDX: User Input and Frame by Frame Animation
Jussi Pohjolainen
 
Expand/Collapse animation on Android
Expand/Collapse animation on Android
Pavlo Dudka
 
Beyond Scala Lens
Beyond Scala Lens
Julien Truffaut
 
The Ring programming language version 1.8 book - Part 56 of 202
The Ring programming language version 1.8 book - Part 56 of 202
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 181
Mahmoud Samir Fayed
 
Snake report ROHIT MALAV
Snake report ROHIT MALAV
Rohit malav
 
Minecraft in 500 lines of Python with Pyglet
Minecraft in 500 lines of Python with Pyglet
Richard Donkin
 
Денис Ковалев «Python в игровой индустрии»
Денис Ковалев «Python в игровой индустрии»
DataArt
 

More Related Content

What's hot (20)

The 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 Game and Application with J2ME - Collision Detection
Jenchoke Tachagomain
 
Mobile Game and Application with J2ME
Mobile Game and Application with J2ME
Jenchoke Tachagomain
 
The Ring programming language version 1.5.1 book - Part 51 of 180
The Ring programming language version 1.5.1 book - Part 51 of 180
Mahmoud Samir Fayed
 
pptuni1
pptuni1
Sachin Yadav
 
libGDX: Tiled Maps
libGDX: Tiled Maps
Jussi Pohjolainen
 
The 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
 
Box2D and libGDX
Box2D and libGDX
Jussi Pohjolainen
 
Александр Зимин – Анимация как средство самовыражения
Александр Зимин – Анимация как средство самовыражения
CocoaHeads
 
Implementing a Simple Game using libGDX
Implementing a Simple Game using libGDX
Jussi Pohjolainen
 
ES6(ES2015) is beautiful
ES6(ES2015) is beautiful
monikagupta18jan
 
λ | Lenses
λ | Lenses
Open-IT
 
Proga 0622
Proga 0622
Atsushi Tadokoro
 
The 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
 
libGDX: User Input and Frame by Frame Animation
libGDX: User Input and Frame by Frame Animation
Jussi Pohjolainen
 
Expand/Collapse animation on Android
Expand/Collapse animation on Android
Pavlo Dudka
 
Beyond Scala Lens
Beyond Scala Lens
Julien Truffaut
 
The Ring programming language version 1.8 book - Part 56 of 202
The Ring programming language version 1.8 book - Part 56 of 202
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 181
Mahmoud Samir Fayed
 
Snake report ROHIT MALAV
Snake report ROHIT MALAV
Rohit malav
 
The 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 Game and Application with J2ME - Collision Detection
Jenchoke Tachagomain
 
Mobile Game and Application with J2ME
Mobile Game and Application with J2ME
Jenchoke Tachagomain
 
The Ring programming language version 1.5.1 book - Part 51 of 180
The Ring programming language version 1.5.1 book - Part 51 of 180
Mahmoud Samir Fayed
 
The 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
 
Александр Зимин – Анимация как средство самовыражения
Александр Зимин – Анимация как средство самовыражения
CocoaHeads
 
Implementing a Simple Game using libGDX
Implementing a Simple Game using libGDX
Jussi Pohjolainen
 
λ | Lenses
λ | Lenses
Open-IT
 
The 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
 
libGDX: User Input and Frame by Frame Animation
libGDX: User Input and Frame by Frame Animation
Jussi Pohjolainen
 
Expand/Collapse animation on Android
Expand/Collapse animation on Android
Pavlo Dudka
 
The Ring programming language version 1.8 book - Part 56 of 202
The Ring programming language version 1.8 book - Part 56 of 202
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 181
Mahmoud Samir Fayed
 
Snake report ROHIT MALAV
Snake report ROHIT MALAV
Rohit malav
 

Similar to Introduction to Game Programming Tutorial (20)

Minecraft in 500 lines of Python with Pyglet
Minecraft in 500 lines of Python with Pyglet
Richard Donkin
 
Денис Ковалев «Python в игровой индустрии»
Денис Ковалев «Python в игровой индустрии»
DataArt
 
Minecraft in 500 lines with Pyglet - PyCon UK
Minecraft in 500 lines with Pyglet - PyCon UK
Richard Donkin
 
Need help with questions 2-4. Write assembly code to find absolute v.pdf
Need help with questions 2-4. Write assembly code to find absolute v.pdf
feelinggifts
 
Html5 game programming overview
Html5 game programming overview
민태 김
 
The Ring programming language version 1.5.3 book - Part 60 of 184
The Ring programming language version 1.5.3 book - Part 60 of 184
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.3 book - Part 50 of 184
The Ring programming language version 1.5.3 book - Part 50 of 184
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.4 book - Part 51 of 185
The Ring programming language version 1.5.4 book - Part 51 of 185
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.2 book - Part 50 of 181
The Ring programming language version 1.5.2 book - Part 50 of 181
Mahmoud Samir Fayed
 
The Ring programming language version 1.8 book - Part 57 of 202
The Ring programming language version 1.8 book - Part 57 of 202
Mahmoud Samir Fayed
 
The Ring programming language version 1.6 book - Part 53 of 189
The Ring programming language version 1.6 book - Part 53 of 189
Mahmoud Samir Fayed
 
The Ring programming language version 1.3 book - Part 40 of 88
The Ring programming language version 1.3 book - Part 40 of 88
Mahmoud Samir Fayed
 
2dPlatformGame2dPlatformGamedataanimsfemale.xml .docx
2dPlatformGame2dPlatformGamedataanimsfemale.xml .docx
tamicawaysmith
 
Pygame presentation
Pygame presentation
Felix Z. Hoffmann
 
Game dev 101 part 3
Game dev 101 part 3
Christoffer Noring
 
The Ring programming language version 1.5.1 book - Part 49 of 180
The Ring programming language version 1.5.1 book - Part 49 of 180
Mahmoud Samir Fayed
 
Game architecture is different
Game architecture is different
Richard Lord
 
The Ring programming language version 1.9 book - Part 60 of 210
The Ring programming language version 1.9 book - Part 60 of 210
Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 61 of 212
The Ring programming language version 1.10 book - Part 61 of 212
Mahmoud Samir Fayed
 
Gd 26
Gd 26
DawitThepchatree
 
Minecraft in 500 lines of Python with Pyglet
Minecraft in 500 lines of Python with Pyglet
Richard Donkin
 
Денис Ковалев «Python в игровой индустрии»
Денис Ковалев «Python в игровой индустрии»
DataArt
 
Minecraft in 500 lines with Pyglet - PyCon UK
Minecraft in 500 lines with Pyglet - PyCon UK
Richard Donkin
 
Need help with questions 2-4. Write assembly code to find absolute v.pdf
Need help with questions 2-4. Write assembly code to find absolute v.pdf
feelinggifts
 
Html5 game programming overview
Html5 game programming overview
민태 김
 
The Ring programming language version 1.5.3 book - Part 60 of 184
The Ring programming language version 1.5.3 book - Part 60 of 184
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.3 book - Part 50 of 184
The Ring programming language version 1.5.3 book - Part 50 of 184
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.4 book - Part 51 of 185
The Ring programming language version 1.5.4 book - Part 51 of 185
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.2 book - Part 50 of 181
The Ring programming language version 1.5.2 book - Part 50 of 181
Mahmoud Samir Fayed
 
The Ring programming language version 1.8 book - Part 57 of 202
The Ring programming language version 1.8 book - Part 57 of 202
Mahmoud Samir Fayed
 
The Ring programming language version 1.6 book - Part 53 of 189
The Ring programming language version 1.6 book - Part 53 of 189
Mahmoud Samir Fayed
 
The Ring programming language version 1.3 book - Part 40 of 88
The Ring programming language version 1.3 book - Part 40 of 88
Mahmoud Samir Fayed
 
2dPlatformGame2dPlatformGamedataanimsfemale.xml .docx
2dPlatformGame2dPlatformGamedataanimsfemale.xml .docx
tamicawaysmith
 
The Ring programming language version 1.5.1 book - Part 49 of 180
The Ring programming language version 1.5.1 book - Part 49 of 180
Mahmoud Samir Fayed
 
Game architecture is different
Game architecture is different
Richard Lord
 
The Ring programming language version 1.9 book - Part 60 of 210
The Ring programming language version 1.9 book - Part 60 of 210
Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 61 of 212
The Ring programming language version 1.10 book - Part 61 of 212
Mahmoud Samir Fayed
 
Ad

More from Richard Jones (11)

Angboard
Angboard
Richard Jones
 
Don't do this
Don't do this
Richard Jones
 
Introduction to Game Programming
Introduction to Game Programming
Richard Jones
 
Message Queueing - by an MQ noob
Message Queueing - by an MQ noob
Richard Jones
 
Message queueing
Message queueing
Richard Jones
 
Web micro-framework BATTLE!
Web micro-framework BATTLE!
Richard Jones
 
State of Python (2010)
State of Python (2010)
Richard Jones
 
What'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.5
Richard Jones
 
What's New In Python 2.4
What's New In Python 2.4
Richard Jones
 
Tkinter Does Not Suck
Tkinter Does Not Suck
Richard Jones
 
Introduction to Game Programming
Introduction to Game Programming
Richard Jones
 
Message Queueing - by an MQ noob
Message Queueing - by an MQ noob
Richard Jones
 
Web micro-framework BATTLE!
Web micro-framework BATTLE!
Richard Jones
 
State of Python (2010)
State of Python (2010)
Richard Jones
 
What'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.5
Richard Jones
 
What's New In Python 2.4
What's New In Python 2.4
Richard Jones
 
Tkinter Does Not Suck
Tkinter Does Not Suck
Richard Jones
 
Ad

Recently uploaded (20)

10 Key Challenges for AI within the EU Data Protection Framework.pdf
10 Key Challenges for AI within the EU Data Protection Framework.pdf
Priyanka Aash
 
Techniques for Automatic Device Identification and Network Assignment.pdf
Techniques for Automatic Device Identification and Network Assignment.pdf
Priyanka Aash
 
Security Tips for Enterprise Azure Solutions
Security Tips for Enterprise Azure Solutions
Michele Leroux Bustamante
 
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC
 
OWASP Barcelona 2025 Threat Model Library
OWASP Barcelona 2025 Threat Model Library
PetraVukmirovic
 
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
Fwdays
 
AI vs Human Writing: Can You Tell the Difference?
AI vs Human Writing: Can You Tell the Difference?
Shashi Sathyanarayana, Ph.D
 
"Database isolation: how we deal with hundreds of direct connections to the d...
"Database isolation: how we deal with hundreds of direct connections to the d...
Fwdays
 
WebdriverIO & JavaScript: The Perfect Duo for Web Automation
WebdriverIO & JavaScript: The Perfect Duo for Web Automation
digitaljignect
 
cnc-processing-centers-centateq-p-110-en.pdf
cnc-processing-centers-centateq-p-110-en.pdf
AmirStern2
 
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Priyanka Aash
 
Securing AI - There Is No Try, Only Do!.pdf
Securing AI - There Is No Try, Only Do!.pdf
Priyanka Aash
 
The Future of Product Management in AI ERA.pdf
The Future of Product Management in AI ERA.pdf
Alyona Owens
 
ReSTIR [DI]: Spatiotemporal reservoir resampling for real-time ray tracing ...
ReSTIR [DI]: Spatiotemporal reservoir resampling for real-time ray tracing ...
revolcs10
 
Python Conference Singapore - 19 Jun 2025
Python Conference Singapore - 19 Jun 2025
ninefyi
 
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
Priyanka Aash
 
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Saikat Basu
 
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik
 
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
Edge AI and Vision Alliance
 
9-1-1 Addressing: End-to-End Automation Using FME
9-1-1 Addressing: End-to-End Automation Using FME
Safe Software
 
10 Key Challenges for AI within the EU Data Protection Framework.pdf
10 Key Challenges for AI within the EU Data Protection Framework.pdf
Priyanka Aash
 
Techniques for Automatic Device Identification and Network Assignment.pdf
Techniques for Automatic Device Identification and Network Assignment.pdf
Priyanka Aash
 
Security Tips for Enterprise Azure Solutions
Security Tips for Enterprise Azure Solutions
Michele Leroux Bustamante
 
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC
 
OWASP Barcelona 2025 Threat Model Library
OWASP Barcelona 2025 Threat Model Library
PetraVukmirovic
 
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
Fwdays
 
AI vs Human Writing: Can You Tell the Difference?
AI vs Human Writing: Can You Tell the Difference?
Shashi Sathyanarayana, Ph.D
 
"Database isolation: how we deal with hundreds of direct connections to the d...
"Database isolation: how we deal with hundreds of direct connections to the d...
Fwdays
 
WebdriverIO & JavaScript: The Perfect Duo for Web Automation
WebdriverIO & JavaScript: The Perfect Duo for Web Automation
digitaljignect
 
cnc-processing-centers-centateq-p-110-en.pdf
cnc-processing-centers-centateq-p-110-en.pdf
AmirStern2
 
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Priyanka Aash
 
Securing AI - There Is No Try, Only Do!.pdf
Securing AI - There Is No Try, Only Do!.pdf
Priyanka Aash
 
The Future of Product Management in AI ERA.pdf
The Future of Product Management in AI ERA.pdf
Alyona Owens
 
ReSTIR [DI]: Spatiotemporal reservoir resampling for real-time ray tracing ...
ReSTIR [DI]: Spatiotemporal reservoir resampling for real-time ray tracing ...
revolcs10
 
Python Conference Singapore - 19 Jun 2025
Python Conference Singapore - 19 Jun 2025
ninefyi
 
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
Priyanka Aash
 
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Saikat Basu
 
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik
 
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
Edge AI and Vision Alliance
 
9-1-1 Addressing: End-to-End Automation Using FME
9-1-1 Addressing: End-to-End Automation Using FME
Safe Software
 

Introduction to Game Programming Tutorial

  • 1. Game Programming LCA 2010 Richard Jones
  • 2. The Basics • Displaying something • Controlling animation • User input • Gameplay mechanics • Playing sound effects and music • Further stuff
  • 3. Displaying Something • Opening a window • Reading images • Displaying images
  • 4. Controlling Animation • Image position on screen • Updates over time • Accounting for frame rate
  • 5. User Input • Getting events • Distinct keyboard events vs. keyboard state
  • 6. Gameplay Mechanics • Interaction of game objects • Detecting important events (game won or game over)
  • 7. Detecting Collisions • Pixel-Perfect • Axis-Aligned Bounding Box • Circle-Circle • Hash Map
  • 8. Sound • Reading sound files • Playing sounds and background music
  • 9. Opening a Window import pyglet w = pyglet.window.Window() pyglet.app.run()
  • 10. Clearing the Window import pyglet w = pyglet.window.Window() @w.event def on_draw(): w.clear() pyglet.app.run()
  • 11. Drawing import pyglet w = pyglet.window.Window() ship_image = pyglet.image.load('data/ship.png') @w.event def on_draw(): w.clear() ship_image.blit(100, 100) pyglet.app.run()
  • 12. Better Drawing import pyglet w = pyglet.window.Window() ship_image = pyglet.image.load('data/ship.png') ship = pyglet.sprite.Sprite(ship_image) ship.position = (100, 100) @w.event def on_draw(): w.clear() ship_image.blit(100, 100) ship.draw() pyglet.app.run()
  • 13. Animation ... w.clear() ship.draw() def update(dt): ship.x += 1 pyglet.clock.schedule_interval(update, 1./30) pyglet.app.run()
  • 14. Better Animation ... w.clear() ship.draw() def update(dt): ship.x += 1 ship.x += 100 * dt pyglet.clock.schedule_interval(update, 1./30) pyglet.app.run()
  • 15. Adding Asteroids import random import pyglet w = pyglet.window.Window() def center_anchor(img): img.anchor_x = img.width / 2 img.anchor_y = img.height / 2 ...
  • 16. Adding Asteroids ... ship_image = pyglet.image.load('data/ship.png') center_anchor(ship_image) ship = pyglet.sprite.Sprite(ship_image) ship.position = (100, 100) big_asteroid_image = pyglet.image.load('data/big_asteroid.png') center_anchor(big_asteroid_image) asteroids = [] for i in range(3): x = random.randint(0, w.width) y = random.randint(0, w.height) s = pyglet.sprite.Sprite(big_asteroid_image, x, y) s.dx = random.randint(-100, 100) s.dy = random.randint(-100, 100) asteroids.append(s) @w.event ...
  • 17. Adding Asteroids ... @w.event def on_draw(): w.clear() for asteroid in asteroids: asteroid.draw() ship.draw() ...
  • 18. Adding Asteroids ... def update(dt): ship.x += 100 * dt for asteroid in asteroids: asteroid.x += asteroid.dx*dt asteroid.y += asteroid.dy*dt ...
  • 19. A Little Refactoring ... ship = pyglet.sprite.Sprite(ship_image) ship.position = (100, 100) ship.dx = 100 ship.dy = 0 ...
  • 20. Screen Wrapping ... def update(dt): ship.x += 100 * dt for asteroid in asteroids: asteroid.x += asteroid.dx*dt asteroid.y += asteroid.dy*dt for a in asteroids + [ship]: a.x += a.dx*dt a.y += a.dy*dt if a.x - a.width/2 > w.width: a.x -= w.width + a.width elif a.x + a.width/2 < 0: a.x += w.width + a.width if a.y - a.height/2 > w.height: a.y -= w.height + a.height elif a.y + a.height/2 < 0: a.y += w.height + a.height ...
  • 21. Control import math import random import pyglet w = pyglet.window.Window() ...
  • 22. Control ... keys = pyglet.window.key.KeyStateHandler() w.push_handlers(keys) def update(dt): if keys[pyglet.window.key.LEFT]: ship.rotation -= 360*dt if keys[pyglet.window.key.RIGHT]: ship.rotation += 360*dt rotation = math.radians(ship.rotation) rotation_x = math.cos(-rotation) rotation_y = math.sin(-rotation) if keys[pyglet.window.key.UP]: ship.dx += 200 * rotation_x * dt ship.dy += 200 * rotation_y * dt for a in asteroids + [ship]: ...
  • 23. Rotation ... ship = pyglet.sprite.Sprite(ship_image) ship.position = (100, 100) ship.dx = 100 ship.dy = 0 ship.position = (w.width/2, w.height/2) ship.dx = ship.dy = ship.dr = 0 ...
  • 24. Rotation ... s = pyglet.sprite.Sprite(big_asteroid_image, x, y) s.dx = random.randint(-100, 100) s.dy = random.randint(-100, 100) s.dr = random.randint(-100, 100) asteroids.append(s) ...
  • 25. Rotation ... def update(dt): if keys[pyglet.window.key.LEFT]: ship.rotation -= 360*dt if keys[pyglet.window.key.RIGHT]: ship.rotation += 360*dt ship.dr = (keys[pyglet.window.key.RIGHT] - keys[pyglet.window.key.LEFT]) * 360 rotation = math.pi * ship.rotation / 180.0 ... for a in asteroids + [ship]: a.x += a.dx*dt a.y += a.dy*dt a.rotation += a.dr * dt if a.x - a.width/2 > w.width: a.x -= w.width + a.width
  • 31. Collision Detection import sys import math import random import pyglet w = pyglet.window.Window() ...
  • 32. Collision Detection ... w.push_handlers(keys) def distance(a, b): return math.sqrt((a.x-b.x)**2 + (a.y-b.y)**2) def update(dt): ...
  • 33. Collision Detection ... elif a.y + a.height/2 < 0: a.y += w.height + a.height for a in asteroids: if distance(a, ship) < (a.width/2 + ship.width/2): sys.exit('GAME OVER') pyglet.clock.schedule_interval(update, 1./30) ...
  • 34. Shooting ship.position = (w.width/2, w.height/2) ship.dx = ship.dy = ship.dr = 0 ship.gun_cooldown = 0 bullet_image = pyglet.image.load('data/bullet.png') center_anchor(bullet_image) bullets = [] ...
  • 35. ... Shooting ship.dy += 200 * rotation_y * dt if ship.gun_cooldown: ship.gun_cooldown = max(0, ship.gun_cooldown - dt) elif keys[pyglet.window.key.SPACE] and len(bullets) < 2: b = pyglet.sprite.Sprite(bullet_image, ship.x, ship.y) b.dx = rotation_x * 500 b.dy = rotation_y * 500 b.dr = 0 b.life = 1 bullets.append(b) ship.gun_cooldown = .5 for b in list(bullets): b.life -= dt if b.life < 0: bullets.remove(b) for a in asteroids + [ship]: for a in asteroids + [ship] + bullets: a.x += a.dx*dt ...
  • 36. Shooting ... @w.event def on_draw(): w.clear() for asteroid in asteroids: asteroid.draw() for s in asteroids + bullets: s.draw() ship.draw() ...
  • 37. Shooting ... and Hitting ... def distance(a, b): return math.sqrt((a.x-b.x)**2 + (a.y-b.y)**2) def collide(a, b): return distance(a, b) < (a.width/2 + b.width/2) ...
  • 38. Shooting ... and Hitting ... elif a.y + a.height/2 < 0: a.y += w.height + a.height for a in asteroids: if distance(a, ship) < (a.width/2 + ship.width/2): sys.exit('GAME OVER') for a in list(asteroids): if collide(a, ship): sys.exit('GAME OVER') for b in list(bullets): if collide(a, b): bullets.remove(b) asteroids.remove(a) if not asteroids: sys.exit('YOU WIN') pyglet.clock.schedule_interval(update, 1./30) ...
  • 39. Chunks ... center_anchor(bullet_image) bullets = [] small_asteroid_image = pyglet.image.load('data/small_asteroid.png') center_anchor(small_asteroid_image) medium_asteroid_image = pyglet.image.load('data/medium_asteroid.png') center_anchor(medium_asteroid_image) big_asteroid_image = pyglet.image.load('data/big_asteroid.png') center_anchor(big_asteroid_image) ...
  • 40. ... Chunks for b in list(bullets): if collide(a, b): bullets.remove(b) asteroids.remove(a) if a.image is big_asteroid_image.texture: for i in range(2): s = pyglet.sprite.Sprite(medium_asteroid_image, a.x, a.y) s.dx = a.dx + random.randint(-50, 50) s.dy = a.dy + random.randint(-50, 50) s.dr = a.dr + random.randint(-50, 50) asteroids.append(s) elif a.image is medium_asteroid_image.texture: for i in range(2): s = pyglet.sprite.Sprite(small_asteroid_image, a.x, a.y) s.dx = a.dx + random.randint(-50, 50) s.dy = a.dy + random.randint(-50, 50) s.dr = a.dr + random.randint(-50, 50) asteroids.append(s) if not asteroids: sys.exit('YOU WIN') ...
  • 41. Sound Effects ... asteroids.append(s) explosion_sound = pyglet.media.load('data/explosion.wav', streaming=False) bullet_sound = pyglet.media.load('data/bullet.wav', streaming=False) @w.event def on_draw(): ...
  • 42. Sound Effects ... bullets.append(b) ship.gun_cooldown = .5 bullet_sound.play() for b in list(bullets): ...
  • 44. Further Stuff • Opening screen • Options menu • Game won / game over screen • Special effects
  • 45. Other screen / menu • Use libraries like Cocos2d (Scenes, Layers, Sprites, Animations)
  • 46. Special Effects • Simple image animations • Use libraries like lepton
  • 47. Where To From Here? • http://pyglet.org • http://pygame.org • http://los-cocos.org • http://inventwithpython.com/ • http://pyweek.org

Editor's Notes