KEMBAR78
Денис Ковалев «Python в игровой индустрии» | PDF
Python in Game
Development
Ковалев Денис
Software Developer at DataArt
Используют Python
Battlefield 2 & Battlefield 2142
Eve Online
Mount & Blade
Civilization IV
Severance: Blade of Darkness
Greyhawk: Temple of Elemental Evil
Графические библиотеки
Tkinter, PyGTK, PyQt
PyGame - http://pygame.org
Pyganim - http://inventwithpython.com/pyganim
Pyglet - http://pyglet.org
Cocos2d - http://cocos2d.org
Pyggel (Python Graphical Game Engine + Libraries)
2D
3D
Panda3D - http://panda3d.org
Pygame
+ SDL (Simple Directmedia Layer) library
+ Stable and well-documented (http://www.pygame.org/docs/ref)
+ Examples (http://www.pygame.org/docs/ref/examples.html) and
tutorials (http://www.pygame.org/docs/tut/newbieguide.html)
- Not pythonic
+ Easy & powerful
Pygame Drawing Concept
Pygame в 9 строк
1. import pygame
2.
3. pygame.init()
4. screen = pygame.display.set_mode((640, 480))
5.
6. while 1:
7. for event in pygame.event.get():
8. if event.type == pygame.QUIT:
9. raise SystemExit("QUIT")
Pygame “Hello, World!”
1. import pygame
2.
3. pygame.init()
4. WHITE = pygame.Color(255, 255, 255)
5. width, height = (640, 480)
6. screen = pygame.display.set_mode((width, height))
7.
8. font = pygame.font.Font(None, 50)
9. text = font.render("Hello, World!", True, WHITE)
10.
11. # Draw text on screen
12. screen.blit(text, text.get_rect(centerx=width/2., centery=height/2.))
13. pygame.display.update()
14.
15. while 1:
16. for event in pygame.event.get():
17. if event.type == pygame.QUIT:
18. raise SystemExit("QUIT")
Pygame реакция на действия
1. def get_text(msg="Hello, World!"):
2. font = pygame.font.Font(None, 50)
3. text = font.render(msg, True, WHITE)
4. return text
5. delta_x, delta_y = (0, 0)
6. step = 20
7. while 1:
8. screen.fill(BLACK)
9. for event in pygame.event.get():
10. if event.type == pygame.QUIT:
11. raise SystemExit("QUIT")
12. elif event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN:
13. delta_y += step
14. elif event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
15. delta_y -= step
16. …
17. elif event.type == pygame.KEYDOWN and event.key == pygame.K_r:
18. delta_x, delta_y = (0, 0)
19. text = get_text()
20. screen.blit(text, text.get_rect(centerx=width/2. + delta_x, centery=height/2. + delta_y))
21. pygame.display.update()
Pygame surfaces
1. yellow_surface = pygame.Surface((width, height))
2. yellow_surface.fill(YELLOW)
3. green_surface = pygame.Surface((width/2, height/2))
4. green_surface.fill(GREEN)
5.
6. def draw_circle(pos, radius=width/8):
7. pygame.draw.circle(yellow_surface, GREEN, pos, radius)
8. pygame.draw.circle(green_surface, YELLOW, pos, radius)
9.
10. while 1:
11. for event in pygame.event.get():
12. if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
13. move = True
14. elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:
15. move = False
16. if move:
17. yellow_surface.fill(YELLOW)
18. green_surface.fill(GREEN)
19. pos = pygame.mouse.get_pos()
20. draw_circle(pos)
21. screen.blit(yellow_surface, (0, 0))
22. screen.blit(green_surface, (0, 0))
23. pygame.display.update()
Pygame objects collision
1. static_rect = pygame.Rect((width/3, height/3), (width/3, height/3))
2. moving_rect = pygame.Rect((width*2/3, height*2/3), (width/6, height/6))
3.
4. def draw_rects(pos):
5. moving_rect.centerx, moving_rect.centery = pos
6. pygame.draw.rect(yellow_surface, GREEN, moving_rect)
7. if moving_rect.colliderect(static_rect):
8. pygame.draw.rect(yellow_surface, PURPLE, static_rect)
9. else:
10. pygame.draw.rect(yellow_surface, BLUE, static_rect)
11.
12. pos = (0, 0)
13. move = False
14. while 1:
15. for event in pygame.event.get():
16. ...
17. if move:
18. yellow_surface.fill(YELLOW)
19. pos = pygame.mouse.get_pos()
20. draw_rects(pos)
21. screen.blit(yellow_surface, (0, 0))
22. pygame.display.update()
Pygame Sprites - create
1. class Ball(pygame.sprite.Sprite):
2. radius = 25
3. groups = []
4. acceleration = 1
5. def __init__(self, pos):
6. pygame.sprite.Sprite.__init__(self, self.groups)
7. self.image = pygame.Surface((Ball.radius * 2, Ball.radius * 2))
8. self.image.fill(YELLOW)
9. self.image.convert_alpha()
10. self.rect = self.image.get_rect()
11. self.radius = Ball.radius
12. self.velocity = 0
13. pygame.draw.circle(self.image, BLUE, self.rect.center, self.radius, 0)
14. self.rect.center = pos
Pygame Sprites - move
1. class Ball(pygame.sprite.Sprite):
2. ….
3. def update(self):
4. if self.rect.top < height: # inside the screen?
5. self.rect.move_ip(0, self.velocity)
6. bricks = pygame.sprite.spritecollide(self, static, False)
7. if bricks:
8. brick = bricks[0]
9. self.rect.bottom = brick.rect.top # place the ball on top of the brick
10. self.velocity *= -0.9 # bounce with speed loss
11. if 0 > self.velocity > -0.1: # prevent infinite bounce
12. self.velocity = 0
13. else:
14. self.velocity += Ball.acceleration
Pygame Sprites
1. allsprites = pygame.sprite.Group()
2. Ball.groups = allsprites
3.
4. static = pygame.sprite.Group()
5. Brick.groups = allsprites, static
6.
7. timer = pygame.time.Clock()
8. screen.blit(yellow_surface, (0, 0))
9. while 1:
10. timer.tick(60)
11. for event in pygame.event.get():
12. if event.type == pygame.QUIT:
13. raise SystemExit("QUIT")
14. elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
15. Ball(event.pos)
16. elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 3:
17. Brick(event.pos)
18. elif event.type == pygame.KEYDOWN and event.key == pygame.K_r:
19. allsprites.empty()
20. static.empty()
21. allsprites.clear(screen, yellow_surface)
22. allsprites.update()
23. allsprites.draw(screen)
24. pygame.display.update()
Python Physics Engines
- http://www.pymunk.org
PyODE (Python bindings for The Open Dynamics Engine)
pyBox2D - http://code.google.com/p/pybox2d
Panda3D - http://www.panda3d.org
Pymunk Physics Engine
- Based on Chipmunk2D (http://chipmunk-physics.net)
- Force & impulse
- Collisions
- Constraints
- Pygame & Pyglet modules
Pymunk basics
1. import pymunk as pm
2.
3. space = pm.Space()
4. space.gravity = (0, -900.0)
5.
6. class Ball(pm.Body):
7. def __init__(self, pos, mass=10, radius=25):
8. inertia = pm.moment_for_circle(mass, 0, radius, (0,0))
9. pm.Body.__init__(self, mass, inertia)
10. self.position = pos
11. self.radius = radius
12. def get_shape(self, elasticity=0.9):
13. shape = pm.Circle(self, self.radius, (0,0))
14. shape.elasticity = elasticity
15. return shape
Pygame + Pymunk
1. while 1:
2. for event in pygame.event.get():
3. if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
4. body = Ball(to_pygame(event.pos))
5. shape = body.get_shape()
6. space.add(body, shape)
7. balls.append(shape)
8. elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 3:
9. brick = Brick(to_pygame(event.pos))
10. space.add(brick)
11. bricks.append(brick)
12.
13. ### Draw stuff here
14.
15. ### Update physics
16. fps = 60.0
17. space.step(1./fps)
18.
19. pygame.display.flip()
20. clock.tick(fps)
Pyglet
+ No dependencies
+ Pythonic
+ Images, audio, video in any format
- Not for games
Cocos2d
+ Pyglet-based
+ For games, apps, GUI interaction
- Poor API docs
- Google does not help
+ OpenGL interface
+ Layers and scenes
Pygame vs Pyglet
1. import pygame
2.
3. pygame.init()
4. screen = pygame.display.set_mode
((640,480))
5.
6. while 1:
7. for event in pygame.event.get():
8. if event.type == pygame.QUIT:
9. raise SystemExit("QUIT")
1. import pyglet
2.
3. screen = pyglet.window.Window
(640,480)
4.
5. pyglet.app.run()
Pygame vs Pyglet
1. import pygame
2.
3. pygame.init()
4. screen = pygame.display.set_mode((640,480))
5.
6. while 1:
7. timer.tick(60)
8. for event in pygame.event.get():
9. if event.type == pygame.KEYDOWN and
event.key == pygame.K_a:
10. print 'You pressed A'
11. #update objects here
12. pygame.display.update()
1. import pyglet
2. from pyglet.window import key
3.
4. screen = pyglet.window.Window(640,480)
5.
6. @screen.event
7. def on_key_press(symbol, modifiers):
8. if symbol == key.A:
9. print 'You pressed A'
10.
11. def update(dt):
12. #update objects here
13.
14. pyglet.clock.schedule_interval(update, 1/60.0)
15. pyglet.app.run()
Редакторы уровней
Tiled - http://www.mapeditor.org
+ PyTMX
FIFE - http://www.fifengine.net
FIFE + Python = https://github.com/fifengine/python-tutorials
“Unknown Horizons”“Zero-Projekt”
Examples and games
pyvolley (cocos2d и pymunk) - https://github.
com/aikikode/pyvolley
Minecraft на Python (pyglet, OpenGL) -
https://github.com/boskee/Minecraft
“Кораблики” (PyGame + Tiled) https://github.
com/aikikode/nautili
pyhammerfight (cocos2d и pymunk) - https://github.
com/aikikode/pyhammerfight
Исходники примеров презентации - https://bitbucket.
org/aikikode/pygame_examples
Презентация - http://bit.ly/1lNp0Uk
Дополнительные источники
Игры и библиотеки - https://wiki.python.org/moin/PythonGames
Making games with Pygame - http://youtu.be/RQ-lIU0jWwg
2D game development using Pyglet with Cocos2d - http://video.kiberpipa.
org/py_2d_and_3d_game_development_using_pyglet/
Спасибо за внимание

Денис Ковалев «Python в игровой индустрии»

  • 1.
    Python in Game Development КовалевДенис Software Developer at DataArt
  • 2.
    Используют Python Battlefield 2& Battlefield 2142 Eve Online Mount & Blade Civilization IV Severance: Blade of Darkness Greyhawk: Temple of Elemental Evil
  • 3.
    Графические библиотеки Tkinter, PyGTK,PyQt PyGame - http://pygame.org Pyganim - http://inventwithpython.com/pyganim Pyglet - http://pyglet.org Cocos2d - http://cocos2d.org Pyggel (Python Graphical Game Engine + Libraries) 2D 3D Panda3D - http://panda3d.org
  • 4.
    Pygame + SDL (SimpleDirectmedia Layer) library + Stable and well-documented (http://www.pygame.org/docs/ref) + Examples (http://www.pygame.org/docs/ref/examples.html) and tutorials (http://www.pygame.org/docs/tut/newbieguide.html) - Not pythonic + Easy & powerful
  • 5.
  • 6.
    Pygame в 9строк 1. import pygame 2. 3. pygame.init() 4. screen = pygame.display.set_mode((640, 480)) 5. 6. while 1: 7. for event in pygame.event.get(): 8. if event.type == pygame.QUIT: 9. raise SystemExit("QUIT")
  • 7.
    Pygame “Hello, World!” 1.import pygame 2. 3. pygame.init() 4. WHITE = pygame.Color(255, 255, 255) 5. width, height = (640, 480) 6. screen = pygame.display.set_mode((width, height)) 7. 8. font = pygame.font.Font(None, 50) 9. text = font.render("Hello, World!", True, WHITE) 10. 11. # Draw text on screen 12. screen.blit(text, text.get_rect(centerx=width/2., centery=height/2.)) 13. pygame.display.update() 14. 15. while 1: 16. for event in pygame.event.get(): 17. if event.type == pygame.QUIT: 18. raise SystemExit("QUIT")
  • 8.
    Pygame реакция надействия 1. def get_text(msg="Hello, World!"): 2. font = pygame.font.Font(None, 50) 3. text = font.render(msg, True, WHITE) 4. return text 5. delta_x, delta_y = (0, 0) 6. step = 20 7. while 1: 8. screen.fill(BLACK) 9. for event in pygame.event.get(): 10. if event.type == pygame.QUIT: 11. raise SystemExit("QUIT") 12. elif event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN: 13. delta_y += step 14. elif event.type == pygame.KEYDOWN and event.key == pygame.K_UP: 15. delta_y -= step 16. … 17. elif event.type == pygame.KEYDOWN and event.key == pygame.K_r: 18. delta_x, delta_y = (0, 0) 19. text = get_text() 20. screen.blit(text, text.get_rect(centerx=width/2. + delta_x, centery=height/2. + delta_y)) 21. pygame.display.update()
  • 9.
    Pygame surfaces 1. yellow_surface= pygame.Surface((width, height)) 2. yellow_surface.fill(YELLOW) 3. green_surface = pygame.Surface((width/2, height/2)) 4. green_surface.fill(GREEN) 5. 6. def draw_circle(pos, radius=width/8): 7. pygame.draw.circle(yellow_surface, GREEN, pos, radius) 8. pygame.draw.circle(green_surface, YELLOW, pos, radius) 9. 10. while 1: 11. for event in pygame.event.get(): 12. if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: 13. move = True 14. elif event.type == pygame.MOUSEBUTTONUP and event.button == 1: 15. move = False 16. if move: 17. yellow_surface.fill(YELLOW) 18. green_surface.fill(GREEN) 19. pos = pygame.mouse.get_pos() 20. draw_circle(pos) 21. screen.blit(yellow_surface, (0, 0)) 22. screen.blit(green_surface, (0, 0)) 23. pygame.display.update()
  • 10.
    Pygame objects collision 1.static_rect = pygame.Rect((width/3, height/3), (width/3, height/3)) 2. moving_rect = pygame.Rect((width*2/3, height*2/3), (width/6, height/6)) 3. 4. def draw_rects(pos): 5. moving_rect.centerx, moving_rect.centery = pos 6. pygame.draw.rect(yellow_surface, GREEN, moving_rect) 7. if moving_rect.colliderect(static_rect): 8. pygame.draw.rect(yellow_surface, PURPLE, static_rect) 9. else: 10. pygame.draw.rect(yellow_surface, BLUE, static_rect) 11. 12. pos = (0, 0) 13. move = False 14. while 1: 15. for event in pygame.event.get(): 16. ... 17. if move: 18. yellow_surface.fill(YELLOW) 19. pos = pygame.mouse.get_pos() 20. draw_rects(pos) 21. screen.blit(yellow_surface, (0, 0)) 22. pygame.display.update()
  • 11.
    Pygame Sprites -create 1. class Ball(pygame.sprite.Sprite): 2. radius = 25 3. groups = [] 4. acceleration = 1 5. def __init__(self, pos): 6. pygame.sprite.Sprite.__init__(self, self.groups) 7. self.image = pygame.Surface((Ball.radius * 2, Ball.radius * 2)) 8. self.image.fill(YELLOW) 9. self.image.convert_alpha() 10. self.rect = self.image.get_rect() 11. self.radius = Ball.radius 12. self.velocity = 0 13. pygame.draw.circle(self.image, BLUE, self.rect.center, self.radius, 0) 14. self.rect.center = pos
  • 12.
    Pygame Sprites -move 1. class Ball(pygame.sprite.Sprite): 2. …. 3. def update(self): 4. if self.rect.top < height: # inside the screen? 5. self.rect.move_ip(0, self.velocity) 6. bricks = pygame.sprite.spritecollide(self, static, False) 7. if bricks: 8. brick = bricks[0] 9. self.rect.bottom = brick.rect.top # place the ball on top of the brick 10. self.velocity *= -0.9 # bounce with speed loss 11. if 0 > self.velocity > -0.1: # prevent infinite bounce 12. self.velocity = 0 13. else: 14. self.velocity += Ball.acceleration
  • 13.
    Pygame Sprites 1. allsprites= pygame.sprite.Group() 2. Ball.groups = allsprites 3. 4. static = pygame.sprite.Group() 5. Brick.groups = allsprites, static 6. 7. timer = pygame.time.Clock() 8. screen.blit(yellow_surface, (0, 0)) 9. while 1: 10. timer.tick(60) 11. for event in pygame.event.get(): 12. if event.type == pygame.QUIT: 13. raise SystemExit("QUIT") 14. elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: 15. Ball(event.pos) 16. elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 3: 17. Brick(event.pos) 18. elif event.type == pygame.KEYDOWN and event.key == pygame.K_r: 19. allsprites.empty() 20. static.empty() 21. allsprites.clear(screen, yellow_surface) 22. allsprites.update() 23. allsprites.draw(screen) 24. pygame.display.update()
  • 14.
    Python Physics Engines -http://www.pymunk.org PyODE (Python bindings for The Open Dynamics Engine) pyBox2D - http://code.google.com/p/pybox2d Panda3D - http://www.panda3d.org
  • 15.
    Pymunk Physics Engine -Based on Chipmunk2D (http://chipmunk-physics.net) - Force & impulse - Collisions - Constraints - Pygame & Pyglet modules
  • 16.
    Pymunk basics 1. importpymunk as pm 2. 3. space = pm.Space() 4. space.gravity = (0, -900.0) 5. 6. class Ball(pm.Body): 7. def __init__(self, pos, mass=10, radius=25): 8. inertia = pm.moment_for_circle(mass, 0, radius, (0,0)) 9. pm.Body.__init__(self, mass, inertia) 10. self.position = pos 11. self.radius = radius 12. def get_shape(self, elasticity=0.9): 13. shape = pm.Circle(self, self.radius, (0,0)) 14. shape.elasticity = elasticity 15. return shape
  • 17.
    Pygame + Pymunk 1.while 1: 2. for event in pygame.event.get(): 3. if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: 4. body = Ball(to_pygame(event.pos)) 5. shape = body.get_shape() 6. space.add(body, shape) 7. balls.append(shape) 8. elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 3: 9. brick = Brick(to_pygame(event.pos)) 10. space.add(brick) 11. bricks.append(brick) 12. 13. ### Draw stuff here 14. 15. ### Update physics 16. fps = 60.0 17. space.step(1./fps) 18. 19. pygame.display.flip() 20. clock.tick(fps)
  • 18.
    Pyglet + No dependencies +Pythonic + Images, audio, video in any format - Not for games Cocos2d + Pyglet-based + For games, apps, GUI interaction - Poor API docs - Google does not help + OpenGL interface + Layers and scenes
  • 19.
    Pygame vs Pyglet 1.import pygame 2. 3. pygame.init() 4. screen = pygame.display.set_mode ((640,480)) 5. 6. while 1: 7. for event in pygame.event.get(): 8. if event.type == pygame.QUIT: 9. raise SystemExit("QUIT") 1. import pyglet 2. 3. screen = pyglet.window.Window (640,480) 4. 5. pyglet.app.run()
  • 20.
    Pygame vs Pyglet 1.import pygame 2. 3. pygame.init() 4. screen = pygame.display.set_mode((640,480)) 5. 6. while 1: 7. timer.tick(60) 8. for event in pygame.event.get(): 9. if event.type == pygame.KEYDOWN and event.key == pygame.K_a: 10. print 'You pressed A' 11. #update objects here 12. pygame.display.update() 1. import pyglet 2. from pyglet.window import key 3. 4. screen = pyglet.window.Window(640,480) 5. 6. @screen.event 7. def on_key_press(symbol, modifiers): 8. if symbol == key.A: 9. print 'You pressed A' 10. 11. def update(dt): 12. #update objects here 13. 14. pyglet.clock.schedule_interval(update, 1/60.0) 15. pyglet.app.run()
  • 21.
  • 22.
  • 23.
    FIFE - http://www.fifengine.net FIFE+ Python = https://github.com/fifengine/python-tutorials “Unknown Horizons”“Zero-Projekt”
  • 24.
    Examples and games pyvolley(cocos2d и pymunk) - https://github. com/aikikode/pyvolley Minecraft на Python (pyglet, OpenGL) - https://github.com/boskee/Minecraft “Кораблики” (PyGame + Tiled) https://github. com/aikikode/nautili pyhammerfight (cocos2d и pymunk) - https://github. com/aikikode/pyhammerfight Исходники примеров презентации - https://bitbucket. org/aikikode/pygame_examples Презентация - http://bit.ly/1lNp0Uk
  • 25.
    Дополнительные источники Игры ибиблиотеки - https://wiki.python.org/moin/PythonGames Making games with Pygame - http://youtu.be/RQ-lIU0jWwg 2D game development using Pyglet with Cocos2d - http://video.kiberpipa. org/py_2d_and_3d_game_development_using_pyglet/
  • 26.