More Related Content Similar to Introduction to Game Programming Tutorial (20) More from Richard Jones (11) Introduction to Game Programming Tutorial2. The Basics
• Displaying something
• Controlling animation
• User input
• Gameplay mechanics
• Playing sound effects and music
• Further stuff
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
...
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]:
...
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
...
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):
...
45. Other screen / menu
• Use libraries like Cocos2d (Scenes, Layers,
Sprites, Animations)
47. Where To From Here?
• http://pyglet.org
• http://pygame.org
• http://los-cocos.org
• http://inventwithpython.com/
• http://pyweek.org
Editor's Notes r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r15 asteroids-cocos.py