Денис Ковалев «python в игровой индустрии»
DESCRIPTION
Спикер: Денис Ковалев, Software Developer в DataArt. Тема: «Python в игровой индустрии». «Расскажу о библиотеках и фреймворках Python, используемых для создания игр.» О спикере: закончил физический факультет ВГУ, после чего пришел в IT, где работает уже более пяти лет. За это время успел поработать и с Perl и С/С++, и с Python и Java. Специализируется на работе с Linux и базами данных. Видео: https://www.youtube.com/watch?v=RkcX6ZWU56s#t=2207 __ Сайт: http://www.dataart.ru/ Facebook: https://www.facebook.com/DataArt.Enjoy Vkontakte: http://vk.com/dataart_enjoy Twitter: https://twitter.com/DataArt_EnjoyTRANSCRIPT
Python in Game Development
Ковалев ДенисSoftware Developer at DataArt
Используют PythonBattlefield 2 & Battlefield 2142
Eve Online
Mount & Blade
Civilization IV
Severance: Blade of Darkness
Greyhawk: Temple of Elemental Evil
Графические библиотеки
Tkinter, PyGTK, PyQtPyGame - http://pygame.orgPyganim - http://inventwithpython.com/pyganimPyglet - http://pyglet.orgCocos2d - 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 pygame2. 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 pygame2.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 screen12. 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 text5. delta_x, delta_y = (0, 0)6. step = 207. 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 += step14. elif event.type == pygame.KEYDOWN and event.key == pygame.K_UP:15. delta_y -= step16. …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 surfaces1. 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 = True14. elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:15. move = False16. 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 collision1. 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 = pos6. 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 = False14. 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 - create1. class Ball(pygame.sprite.Sprite):2. radius = 253. groups = []4. acceleration = 15. 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.radius12. self.velocity = 013. pygame.draw.circle(self.image, BLUE, self.rect.center, self.radius, 0)14. self.rect.center = pos
Pygame Sprites - move1. 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 loss11. if 0 > self.velocity > -0.1: # prevent infinite bounce12. self.velocity = 013. else:14. self.velocity += Ball.acceleration
Pygame Sprites1. allsprites = pygame.sprite.Group()2. Ball.groups = allsprites3. 4. static = pygame.sprite.Group()5. Brick.groups = allsprites, static6. 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 basics1. import pymunk as pm2. 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 = pos11. self.radius = radius12. def get_shape(self, elasticity=0.9):13. shape = pm.Circle(self, self.radius, (0,0))14. shape.elasticity = elasticity15. return shape
Pygame + Pymunk1. 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 here14.15. ### Update physics16. fps = 60.017. 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 Pyglet1. import pygame2. 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 pyglet2.3. screen = pyglet.window.Window
(640,480) 4.5. pyglet.app.run()
Pygame vs Pyglet1. import pygame2. 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 here12. pygame.display.update()
1. import pyglet2. from pyglet.window import key3. 4. screen = pyglet.window.Window(640,480)5. 6. @screen.event7. def on_key_press(symbol, modifiers):8. if symbol == key.A:9. print 'You pressed A'
10. 11. def update(dt):12. #update objects here13. 14. pyglet.clock.schedule_interval(update, 1/60.0)15. pyglet.app.run()
Редакторы уровней
FIFE - http://www.fifengine.netFIFE + 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/
Спасибо за внимание