ïŒãã¥ãŒããªã¢ã«ã®æ®ãïŒ2ã3ã4ã5ïŒã
å€å žçãªãã¬ã€ã¯ã¢ãŠãã²ãŒã ã®ããŒãžã§ã³ãäœæããŸãã ãã®ãã¥ãŒããªã¢ã«ãç¿åŸãããšãã²ãŒã ãäœæããããã«å¿ èŠãªãã®ãæ確ã«ç解ããPygameã®æ©èœã«ç²Ÿéããã²ãŒã ã®ç¬èªã®äŸãäœæã§ããŸãã
次ã®æ©èœãšæ©èœãå®è£ ããŸãã
- ã·ã³ãã«ãªæšæºã®GameObjectãšTextObject
- ã·ã³ãã«ãªæšæºã®Gameãªããžã§ã¯ã
- ã·ã³ãã«ãªæšæºãã¿ã³
- èšå®ãã¡ã€ã«
- ããŒããŒããšããŠã¹ã®ã€ãã³ãåŠç
- ã¬ã³ã¬ãã©ã±ãããããŒã«
- ã©ã±ããã¢ãŒã·ã§ã³ã³ã³ãããŒã«
- ã²ãŒã ãªããžã§ã¯ããšããŒã«ã®è¡çªãåŠçãã
- èæ¯ç»å
- é³é¿å¹æ
- æ¡åŒµå¯èœãªç¹æ®å¹æã·ã¹ãã
ã²ãŒã ãã°ã©ãã£ã«ã«ã«éåžžã«çŸãããªãããšãæåŸ ããªãã§ãã ãã ã ç§ã¯ããã°ã©ããŒã§ãããã¢ãŒãã£ã¹ãã§ã¯ãªããã³ãŒãã®çŸåŠã«èå³ããããŸãã ç§ãäœæãããã¶ã€ã³ã¯ãäžæå¿«ãªã»ã©é©ãã¹ããã®ã§ãã äžæ¹ããã®ããŒãžã§ã³ã®ãã¬ã€ã¯ã¢ãŠãã®ã°ã©ãã£ãã¯ãæ¹åããå¯èœæ§ã¯ã»ãŒç¡éã«ãããŸãã ç§ã®åŸã§ç¹°ãè¿ããããªãå Žåã¯ãã¹ã¯ãªãŒã³ã·ã§ãããèŠãŠãã ããïŒ
å®æãããœãŒã¹ã³ãŒãã¯ãã¡ãããå ¥æã§ããŸã ã
ã²ãŒã ããã°ã©ãã³ã°ã®ç°¡åãªçŽ¹ä»
ã²ãŒã ã®äž»ãªãã®ã¯ãç»é¢äžã®ãã¯ã»ã«ã®åããšæŸåºããããã€ãºã§ãã ã»ãšãã©ãã¹ãŠã®ãããªã²ãŒã ã«ã¯ãããã®èŠçŽ ããããŸãã ãã®èšäºã§ã¯ãå€ãã®ãããã¯ãŒã¯ããã°ã©ãã³ã°ãå¿ èŠãšããã¯ã©ã€ã¢ã³ããµãŒããŒã²ãŒã ããã«ããã¬ã€ã€ãŒã²ãŒã ã«ã€ããŠã¯æ€èšããŸããã
ã¡ã€ã³ãµã€ã¯ã«
ã²ãŒã ã®ã¡ã€ã³ã«ãŒããå®è¡ãããäžå®ã®ééã§ç»é¢ãæŽæ°ãããŸãã ãããã¯ãã¬ãŒã ã¬ãŒããšåŒã°ããåãã®æ»ãããã決å®ããŸãã éåžžãã²ãŒã ã¯1ç§éã«30ã60åç»é¢ãæŽæ°ããŸãã é »åºŠãå°ãªãå Žåã¯ãç»é¢äžã®ãªããžã§ã¯ããåããŠããããã«èŠããŸãã
ã¡ã€ã³ã«ãŒãå ã«ã¯ãã€ãã³ãã®åŠçãã²ãŒã ã®ç¶æ ã®æŽæ°ãç»é¢äžã®çŸåšã®ç¶æ ã®æç»ãšãã3ã€ã®äž»èŠãªæäœããããŸãã
ã€ãã³ãåŠç
ã²ãŒã å ã®ã€ãã³ãã¯ãã²ãŒã ã³ãŒãã®å¶åŸ¡å€ã§çºçãããã¹ãŠã®ãã®ã§æ§æãããŠããŸãããã²ãŒã ã®å®è¡ã«é¢é£ããŠããŸãã ããšãã°ããã¬ã€ã¯ã¢ãŠãã§ãã¬ã€ã€ãŒãå·Šç¢å°ããŒãæŒããå Žåãã²ãŒã ã¯ã©ã±ãããå·Šã«ç§»åããå¿ èŠããããŸãã æšæºã€ãã³ãã¯ãããŒã®ããŒã¹ãããŒã¯ïŒããã³æŒäžïŒãããŠã¹ã®åããããŠã¹ã¯ãªãã¯ïŒç¹ã«ã¡ãã¥ãŒå ïŒãããã³ã¿ã€ããŒã€ãã³ãïŒããšãã°ãç¹æ®å¹æã®å¹æã¯10ç§éç¶ãïŒã§ãã
ã¹ããŒã¿ã¹æŽæ°
ãã¹ãŠã®ã²ãŒã ã®æ žå¿ã¯ãã®ç¶æ ã§ããã€ãŸããç»é¢äžã§è¿œè·¡ããã³æç»ãããã¹ãŠã®ãã®ã§ãã ãã¬ã€ã¯ã¢ãŠãã®å Žåãç¶æ ã«ã¯ããã¹ãŠã®ã¬ã³ã¬ã®äœçœ®ãããŒã«ã®äœçœ®ãšé床ãã©ã±ããã®äœçœ®ã寿åœãšãã€ã³ããå«ãŸããŸãã
ã²ãŒã ãå¶åŸ¡ã§ããããã«ããè£å©ç¶æ ããããŸãã
- ã¡ãã¥ãŒã¯è¡šç€ºãããŠããŸããïŒ
- ã²ãŒã ãªãŒããŒã§ããïŒ
- ãã¬ãŒã€ãŒã¯åã¡ãŸãããïŒ
æç»
ã²ãŒã ã¯ã幟äœåŠçãªåœ¢ç¶ãç»åãããã¹ãã®ã¬ã³ããªã³ã°ãªã©ãç»é¢ã«ãã®ç¶æ ã衚瀺ããå¿ èŠããããŸãã
ã²ãŒã ç©çåŠ
ã»ãšãã©ã®ã²ãŒã ã§ã¯ãç©ççç°å¢ãã·ãã¥ã¬ãŒããããŸãã ãã¬ã€ã¯ã¢ãŠãã§ã¯ãããŒã«ã¯ãªããžã§ã¯ãã«è·³ãè¿ããåºäœç©çåŠã®éåžžã«è¿äŒŒããã·ã¹ãã ãæã¡ãŸãïŒãããåŒã³åºãããšãã§ããå ŽåïŒã
ããæŽç·Žãããã²ãŒã ã§ã¯ãããæŽç·ŽãããçŸå®çãªç©çã·ã¹ãã ïŒç¹ã«3Dã²ãŒã ïŒã䜿çšã§ããŸãã ãŸããã«ãŒãã²ãŒã ãªã©ã®äžéšã®ã²ãŒã ã§ã¯ãç©çåŠãã»ãšãã©ãªããããã¯å®å šã«æ£åžžã§ããããšã«æ³šæããŠãã ããã
AIïŒäººå·¥ç¥èœïŒ
å€ãã®ã²ãŒã ã§ãã³ã³ãã¥ãŒã¿ãŒã®æµãšæŠãããæµãç§ãã¡ã殺ãããšããŠããŸãã å€ãã®å Žåã圌ãã¯ããããç¥æ§ãæã£ãŠãããã®ããã«ã²ãŒã ã®äžçã§æ¯ãèããŸãã
ããšãã°ãæµã¯ãã¬ã€ã€ãŒãè¿œãããããã®å Žæãç¥ã£ãŠããŸãã ãã¬ã€ã¯ã¢ãŠãã«ã¯AIã¯ãããŸããã ãã¬ã€ã€ãŒã¯å¯ããŠç¡¬ãã¬ã³ã¬ãšæŠããŸãã ãã ããã²ãŒã ã®AIã¯å€ãã®å Žåéåžžã«åçŽã§ãããç䌌åççãªçµæãæäŸããåçŽãªïŒãŸãã¯è€éãªïŒã«ãŒã«ã«åŸããŸãã
é³ã鳎ãã
ãµãŠã³ãã®åçŸã¯ãã²ãŒã ã®ãã1ã€ã®éèŠãªåŽé¢ã§ãã äžè¬çã«ããµãŠã³ãã«ã¯ããã¯ã°ã©ãŠã³ããã¥ãŒãžãã¯ãšãµãŠã³ããšãã§ã¯ãã®2çš®é¡ããããŸãã Breakoutã§ã¯ãããŸããŸãªã€ãã³ãäžã«åçããå¹æé³ã®ã¿ãå®è£ ããŸãã
ããã¯ã°ã©ãŠã³ããã¥ãŒãžãã¯ã¯ãåžžã«ããã¯ã°ã©ãŠã³ãã§åçãããé³æ¥œã§ãã äžéšã®ã²ãŒã ã§ã¯äœ¿çšããããäžéšã®ã²ãŒã ã§ã¯åã¬ãã«ã§å€æŽãããŸãã
ç掻ããã€ã³ããã¬ãã«
ã»ãšãã©ã®ã²ãŒã ã§ã¯ããã¬ã€ã€ãŒã¯äžå®æ°ã®ã©ã€ããæââã¡ãã²ãŒã ãçµäºãããšã²ãŒã ã¯çµäºããŸãã ãŸããã²ãŒã ã«ã¯ããããã¬ãŒããŠããããšãç解ããããèªå·±æ¹åã®åæ©ä»ããããããèšé²ãå人ã«èŠãããããããã®ã¡ã¬ãããããŸãã å€ãã®ã²ãŒã ã«ã¯ãå®å šã«ç°ãªãã¬ãã«ãŸãã¯é£æ床ãåŸã ã«é«ããªãã¬ãã«ããããŸãã
Pygameã®çŽ¹ä»
ã²ãŒã ã®å®è£ ãéå§ããåã«ãPygameã«ã€ããŠå°ãåŠã³ãŸããããPygameã¯ã»ãšãã©ã®äœæ¥ãåŒãåããŸãã
pygameãšã¯äœã§ããïŒ
Pygameã¯ãã²ãŒã ããã°ã©ãã³ã°çšã®Pythonããã°ã©ãã³ã°ãã¬ãŒã ã¯ãŒã¯ã§ãã SDLã®äžã«æ§ç¯ãããŠãããå¿ èŠãªãã®ã¯ãã¹ãŠæã£ãŠããŸãã
- æºæ
- è¯ãã³ãã¥ããã£
- ãªãŒãã³ãœãŒã¹
- ã¯ãã¹ãã©ãããã©ãŒã
- å質ææž
- ã²ãŒã ã®å€ãã®äŸ
- ç 究ã®ã·ã³ãã«ã
Pygameãã€ã³ã¹ããŒã«ãã
pip install pygame
ãšå ¥åããŠããã¬ãŒã ã¯ãŒã¯ãã€ã³ã¹ããŒã«ããŸãã ä»ã«äœããå¿ èŠãªå Žåã¯ããããžã§ã¯ãwikiã®ãã¯ããã«ãã»ã¯ã·ã§ã³ã®æ瀺ã«åŸã£ãŠãã ããã ç§ã®ããã«macOS Sierraã®å Žåãåé¡ãçºçããå¯èœæ§ããããŸãã ç§ã¯Pygameãè€éãªãã§ã€ã³ã¹ããŒã«ã§ããã³ãŒãã¯æ£åžžã«åäœããŸãããã²ãŒã ãŠã£ã³ããŠã¯è¡šç€ºãããŸããã
ããã¯ãã²ãŒã ãéå§ãããšãã«æ·±å»ãªé害ã«ãªããŸãã æçµçã«ãVirtualBox VMå ã®Windowsã§å®è¡ããå¿ èŠããããŸããã ãã®èšäºãèªããŸã§ã«åé¡ã解決ããããšãé¡ã£ãŠããŸãã
ã²ãŒã ã¢ãŒããã¯ãã£
ã²ãŒã ã¯å€ãã®æ å ±ã管çããå€ãã®ãªããžã§ã¯ãã§ã»ãŒåãæäœãå®è¡ããå¿ èŠããããŸãã ãã¬ã€ã¯ã¢ãŠãã¯å°ããªã²ãŒã ã§ããã1ã€ã®ãã¡ã€ã«ã§ãã¹ãŠã管çããããšããã®ã¯é¢åã§ãã ãã®ããããã倧ããªã²ãŒã ã«é©ãããã¡ã€ã«æ§é ãšã¢ãŒããã¯ãã£ãäœæããããšã«ããŸããã
ãã©ã«ããŒãšãã¡ã€ã«ã®æ§é
âââPipfile âââPipfile.lock âââREADME.md âââball.py âââbreakout.py âââbrick.py âââbutton.py âââcolors.py âââconfig.py âââgame.py âââgame_object.py âââç»å ââââbackground.jpg âââpaddle.py âââsound_effects ââââbrick_hit.wav ââââeffect_done.wav ââââlevel_complete.wav ââââpaddle_hit.wav âââtext_object.py
PipfileãšPipfile.lockã¯ãPythonã§äŸåé¢ä¿ã管çããææ°ã®æ¹æ³ã§ãã imagesãã©ã«ããŒã«ã¯ã²ãŒã ã§äœ¿çšãããç»åãå«ãŸãïŒãã®ããŒãžã§ã³ã§ã¯èæ¯ç»åã®ã¿ããããŸãïŒãsound_effectsãã£ã¬ã¯ããªãã©ã«ããŒã«ã¯å¹æé³ãšããŠïŒãæ³åã®ãšããïŒäœ¿çšãããçããµãŠã³ãã¯ãªãããå«ãŸããŸãã
ball.pyãpaddle.pyãããã³brick.pyãã¡ã€ã«ã«ã¯ããããã®åBreakoutãªããžã§ã¯ãã«é¢é£ããã³ãŒããå«ãŸããŠããŸãã ãããã«ã€ããŠã¯ããã¥ãŒããªã¢ã«ã®ä»¥äžã®éšåã§è©³ãã説æããŸãã text_object.pyãã¡ã€ã«ã«ã¯ããã¹ããç»é¢ã«è¡šç€ºããã³ãŒããå«ãŸããbackground.pyãã¡ã€ã«ã«ã¯Breakoutã²ãŒã ããžãã¯ãå«ãŸããŠããŸãã
ãã ããæ±çšã®ä»»æã®ãã¹ã±ã«ãã³ããäœæããã¢ãžã¥ãŒã«ãããã€ããããŸãã ãããã§å®çŸ©ãããã¯ã©ã¹ã¯ãä»ã®PygameããŒã¹ã®ã²ãŒã ã§äœ¿çšã§ããŸãã
ã¯ã©ã¹GameObject
GameObjectã¯ãèªåèªèº«ãã¬ã³ããªã³ã°ããå¢çãä¿åãã移åããæ¹æ³ãç¥ã£ãŠããããžã¥ã¢ã«ãªããžã§ã¯ãã§ãã Pygameã«ãåæ§ã®åœ¹å²ãæããSpriteã¯ã©ã¹ããããŸããããã®ãã¥ãŒããªã¢ã«ã§ã¯ããã¹ãŠãäœã¬ãã«ã§æ©èœããæ¢æã®éæ³ã«ããŸãäŸåããªãæ¹æ³ã瀺ããŸãã GameObjectã¯ã©ã¹ã¯æ¬¡ã®ããã«ãªããŸãã
from pygame.rect import Rect class GameObject: def __init__(self, x, y, w, h, speed=(0,0)): self.bounds = Rect(x, y, w, h) self.speed = speed @property def left(self): return self.bounds.left @property def right(self): return self.bounds.right @property def top(self): return self.bounds.top @property def bottom(self): return self.bounds.bottom @property def width(self): return self.bounds.width @property def height(self): return self.bounds.height @property def center(self): return self.bounds.center @property def centerx(self): return self.bounds.centerx @property def centery(self): return self.bounds.centery def draw(self, surface): pass def move(self, dx, dy): self.bounds = self.bounds.move(dx, dy) def update(self): if self.speed == [0, 0]: return self.move(*self.speed)
GameObjectã¯ãä»ã®ãªããžã§ã¯ãã®åºæ¬ã¯ã©ã¹ã«ãªãããšãç®çãšããŠããŸãã self.boundsåè§åœ¢ã®å€ãã®ããããã£ãçŽæ¥æããã«ãã
update()
ã¡ãœããã§çŸåšã®é床ã«å¿ããŠãªããžã§ã¯ãã移åããŸãã
draw()
ã¡ãœããã§ã¯äœãè¡ããŸãããããµãã¯ã©ã¹ã§ãªãŒããŒã©ã€ãããå¿ èŠããããŸãã
ã²ãŒã ã¯ã©ã¹
Gameã¯ã©ã¹ã¯ã²ãŒã ã®äžæ žã§ãã ã¡ã€ã³ã«ãŒãã§å®è¡ãããŸãã å€ãã®äŸ¿å©ãªæ©èœããããŸãã ã¡ãœããããšã«ã¡ãœãããåæããŸãããã
__init__()
ã¡ãœããã¯ãPygameèªäœããã©ã³ãã·ã¹ãã ãããã³ãµãŠã³ããããµãŒãåæåããŸãã ãã¹ãŠã®Pygameã²ãŒã ããã¹ãŠã®ã³ã³ããŒãã³ãã䜿çšããããã§ã¯ãªãããã3ã€ã®ç°ãªãåŒã³åºããå¿ èŠã§ãããããã£ãŠã䜿çšãããµãã·ã¹ãã ãå¶åŸ¡ããé©åãªãã©ã¡ãŒã¿ãŒã§å¿ èŠãªãµãã·ã¹ãã ã®ã¿ãåæåã§ããŸãã ãã®ã¡ãœããã¯ãèæ¯ç»åãã¡ã€ã³ãµãŒãã§ã¹ïŒãã¹ãŠãæç»ãããïŒãããã³æ£ãããã¬ãŒã ã¬ãŒãã®ã²ãŒã ã¿ã€ããŒãäœæããŸãã
self.objectsèŠçŽ ã«ã¯ãã¬ã³ããªã³ã°ããã³æŽæ°ãå¿ èŠãªãã¹ãŠã®ã²ãŒã ãªããžã§ã¯ããæ ŒçŽãããŸãã ããŸããŸãªãã³ãã©ãŒããç¹å®ã®ã€ãã³ãã§å®è¡ããå¿ èŠããããã³ãã©ãŒé¢æ°ã®ãªã¹ãã管çããŸãã
import pygame import sys from collections import defaultdict class Game: def __init__(self, caption, width, height, back_image_filename, frame_rate): self.background_image = \ pygame.image.load(back_image_filename) self.frame_rate = frame_rate self.game_over = False self.objects = [] pygame.mixer.pre_init(44100, 16, 2, 4096) pygame.init() pygame.font.init() self.surface = pygame.display.set_mode((width, height)) pygame.display.set_caption(caption) self.clock = pygame.time.Clock() self.keydown_handlers = defaultdict(list) self.keyup_handlers = defaultdict(list) self.mouse_handlers = []
update()
ããã³
draw()
ã¡ãœããã¯éåžžã«ç°¡åã§ãã ãã¹ãŠã®ç®¡ç察象ã²ãŒã ãªããžã§ã¯ãããã€ãã¹ãã察å¿ããã¡ãœãããåŒã³åºããŸãã 2ã€ã®ãªããžã§ã¯ããç»é¢äžã§äºãã«éãªãåã£ãŠããå Žåããªããžã§ã¯ãã®ãªã¹ãã®é åºã«ãã£ãŠã©ã¡ããæåã«ã¬ã³ããªã³ã°ãããæ®ãã®éšåãéšåçã«ãŸãã¯å®å šã«éãªããŸãã
def update(self): for o in self.objects: o.update() def draw(self): for o in self.objects: o.draw(self.surface)
handle_events()
ã¡ãœããã¯ãããŒããŒãã€ãã³ããããŠã¹ã€ãã³ããªã©ãPygameã«ãã£ãŠçæãããã€ãã³ãããªãã¹ã³ããŸãã ã€ãã³ãããšã«ã察å¿ããã¿ã€ãã®ã€ãã³ããåŠçãããã¹ãŠã®ãã³ãã©ãŒé¢æ°ãåŒã³åºããŸãã
def handle_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: for handler in self.keydown_handlers[event.key]: handler(event.key) elif event.type == pygame.KEYUP: for handler in self.keydown_handlers[event.key]: handler(event.key) elif event.type in (pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP, pygame.MOUSEMOTION): for handler in self.mouse_handlers: handler(event.type, event.pos)
æåŸã«ã
run()
ã¡ãœãããã¡ã€ã³ã«ãŒããå®è¡ããŸãã
game_over
èŠçŽ ãTrueã«ãªããŸã§å®è¡ãããŸãã åå埩ã§ãèæ¯ç»åãã¬ã³ããªã³ã°ãã
handle_events()
ã
update()
ããã³
draw()
ã¡ãœãããé çªã«åŒã³åºããŸãã
次ã«ãç»é¢ãæŽæ°ããŸããã€ãŸããçŸåšã®å埩ã§ã¬ã³ããªã³ã°ããããã¹ãŠã®ã³ã³ãã³ããç©çãã£ã¹ãã¬ã€ã«æžã蟌ã¿ãŸãã æåŸã«
clock.tick()
ããšã§ããã次ã®ç¹°ãè¿ãããã€åŒã³åºãããããå¶åŸ¡ããããã«
clock.tick()
ã¡ãœãããåŒã³åºããŸãã
def run(self): while not self.game_over: self.surface.blit(self.background_image, (0, 0)) self.handle_events() self.update() self.draw() pygame.display.update() self.clock.tick(self.frame_rate)
ãããã«
ãã®ããŒãã§ã¯ãã²ãŒã ããã°ã©ãã³ã°ã®åºç€ãšãã²ãŒã ã®äœæã«é¢ä¿ãããã¹ãŠã®ã³ã³ããŒãã³ããåŠã³ãŸããã ãŸããPygameèªäœã調ã¹ãŠãã€ã³ã¹ããŒã«æ¹æ³ãåŠã³ãŸããã æåŸã«ãã²ãŒã ã®ã¢ãŒããã¯ãã£ã«é£ã³èŸŒã¿ããã©ã«ãæ§é ã
GameObject
ã¯ã©ã¹ãããã³Gameã¯ã©ã¹ã調æ»ããŸããã
2çªç®ã®éšåã§ã¯ãç»é¢ã«ããã¹ããã¬ã³ããªã³ã°ããããã«äœ¿çšããã
TextObject
ã¯ã©ã¹ã調ã¹ãŸãã èæ¯ç»åãå«ãã¡ã€ã³ãŠã£ã³ããŠãäœæãããªããžã§ã¯ãïŒããŒã«ãšã©ã±ããïŒã®æç»æ¹æ³ãåŠç¿ããŸãã