{"id":151,"date":"2012-08-17T09:16:00","date_gmt":"2012-08-17T03:46:00","guid":{"rendered":"http:\/\/sandeepmathew.wordpress.com\/?p=151"},"modified":"2012-08-17T09:16:00","modified_gmt":"2012-08-17T03:46:00","slug":"crash-course-in-game-development-with-pygame","status":"publish","type":"post","link":"https:\/\/sandeepmathew.com\/index.php\/2012\/08\/17\/crash-course-in-game-development-with-pygame\/","title":{"rendered":"Crash course in game development with pygame"},"content":{"rendered":"<p>Today I will ramble about game development with python . Python is very easy to learn and it is a very easy to prototype games\u00a0 with python. Pygame\u00a0 is a SDL binding fo python , visit pygame.org for more details.<\/p>\n<p><strong>2D Game Development Concepts<\/strong><\/p>\n<p>Sprites : Sprites are moveable game entities , I bet all of you have played super mario. The mario character you control is basically a sprite .<\/p>\n<p>Game Loop :\u00a0 Game is loop is very common in most of the games , it something of this form(\u00a0 C is psuedo code )<\/p>\n<p>while ( not_game_over)<\/p>\n<p>{<\/p>\n<p>if ( an_event_occurred )<\/p>\n<p>handle_event()<\/p>\n<p>}<\/p>\n<p>Collision detection : In a game you often need to find out when you characters collide , this is called collision detection. There are many ways to perform collision detection.\u00a0 The easiest way is to define a bounding rectangle for the sprite and determine when\u00a0these two rectangles overlap .<\/p>\n<p>Input handling : While programming your game , you need to determine what needs to be done when user press the keyboard or mouse . With newer operating system this is way too easy you just need to use the services provided by the operating system . Back in the good old days of DOS this was not the case , you need to write a separate keyboard\u00a0 handler , mouse handler etc so that your game responds well.<\/p>\n<p>Sound and\u00a0 Music : You also need to\u00a0 play sound for special game events , eg a sound when you won the game etc<\/p>\n<p>Handling game states : Each game entity and the game itself maintains a state and actions need to be performed based on the current state of the game. One crude way to\u00a0 handle states is to use an enumeration. But\u00a0 when the number of states increase they become very cumbersome to mange.\u00a0 A better way is to use a variation of the state pattern <\/p>\n<p>I am too lazy to write my own game now , i am therefore copy pasting the example games provided by the pygame itself \ud83d\ude42 . They are well commented and easy to understand<\/p>\n<p>Getting started with pygame<\/p>\n<p>your first pgame program<br \/>\n[sourcecode language=&#8221;python&#8221;]<br \/>\nimport pygame<\/p>\n<p>pygame.init();<br \/>\ndimensions = ( 640 , 480 )<br \/>\ncolor_red =   ( 255 , 0 , 0 )<br \/>\nscreen = pygame.display.set_mode(dimensions)<br \/>\npygame.display.set_caption(&quot;Pygame Template&quot;)<br \/>\ngame_running = True<br \/>\nclock = pygame.time.Clock()<br \/>\nwhile game_running == True:<br \/>\n\tfor event in pygame.event.get():<br \/>\n\t\tif  event.type == pygame.QUIT:<br \/>\n\t\t\tgame_running = False<\/p>\n<p>\tscreen.fill(color_red)<br \/>\n\tpygame.display.flip();<br \/>\n\tclock.tick(20)<\/p>\n<p>pygame.quit()<br \/>\n[\/sourcecode]<br \/>\nChimp line by line example<br \/>\n[sourcecode language=&#8221;python&#8221;]<br \/>\n#!\/usr\/bin\/env python<br \/>\n&quot;&quot;&quot;<br \/>\nThis simple example is used for the line-by-line tutorial<br \/>\nthat comes with pygame. It is based on a &#8216;popular&#8217; web banner.<br \/>\nNote there are comments here, but for the full explanation,<br \/>\nfollow along in the tutorial.<br \/>\n&quot;&quot;&quot;<\/p>\n<p>#Import Modules<br \/>\nimport os, pygame<br \/>\nfrom pygame.locals import *<br \/>\nfrom pygame.compat import geterror<\/p>\n<p>if not pygame.font: print (&#8216;Warning, fonts disabled&#8217;)<br \/>\nif not pygame.mixer: print (&#8216;Warning, sound disabled&#8217;)<\/p>\n<p>main_dir = os.path.split(os.path.abspath(__file__))[0]<br \/>\ndata_dir = os.path.join(main_dir, &#8216;data&#8217;)<\/p>\n<p>#functions to create our resources<br \/>\ndef load_image(name, colorkey=None):<br \/>\n    fullname = os.path.join(data_dir, name)<br \/>\n    try:<br \/>\n        image = pygame.image.load(fullname)<br \/>\n    except pygame.error:<br \/>\n        print (&#8216;Cannot load image:&#8217;, fullname)<br \/>\n        raise SystemExit(str(geterror()))<br \/>\n    image = image.convert()<br \/>\n    if colorkey is not None:<br \/>\n        if colorkey is -1:<br \/>\n            colorkey = image.get_at((0,0))<br \/>\n        image.set_colorkey(colorkey, RLEACCEL)<br \/>\n    return image, image.get_rect()<\/p>\n<p>def load_sound(name):<br \/>\n    class NoneSound:<br \/>\n        def play(self): pass<br \/>\n    if not pygame.mixer or not pygame.mixer.get_init():<br \/>\n        return NoneSound()<br \/>\n    fullname = os.path.join(data_dir, name)<br \/>\n    try:<br \/>\n        sound = pygame.mixer.Sound(fullname)<br \/>\n    except pygame.error:<br \/>\n        print (&#8216;Cannot load sound: %s&#8217; % fullname)<br \/>\n        raise SystemExit(str(geterror()))<br \/>\n    return sound<\/p>\n<p>#classes for our game objects<br \/>\nclass Fist(pygame.sprite.Sprite):<br \/>\n    &quot;&quot;&quot;moves a clenched fist on the screen, following the mouse&quot;&quot;&quot;<br \/>\n    def __init__(self):<br \/>\n        pygame.sprite.Sprite.__init__(self) #call Sprite initializer<br \/>\n        self.image, self.rect = load_image(&#8216;fist.bmp&#8217;, -1)<br \/>\n        self.punching = 0<\/p>\n<p>    def update(self):<br \/>\n        &quot;move the fist based on the mouse position&quot;<br \/>\n        pos = pygame.mouse.get_pos()<br \/>\n        self.rect.midtop = pos<br \/>\n        if self.punching:<br \/>\n            self.rect.move_ip(5, 10)<\/p>\n<p>    def punch(self, target):<br \/>\n        &quot;returns true if the fist collides with the target&quot;<br \/>\n        if not self.punching:<br \/>\n            self.punching = 1<br \/>\n            hitbox = self.rect.inflate(-5, -5)<br \/>\n            return hitbox.colliderect(target.rect)<\/p>\n<p>    def unpunch(self):<br \/>\n        &quot;called to pull the fist back&quot;<br \/>\n        self.punching = 0<\/p>\n<p>class Chimp(pygame.sprite.Sprite):<br \/>\n    &quot;&quot;&quot;moves a monkey critter across the screen. it can spin the<br \/>\n       monkey when it is punched.&quot;&quot;&quot;<br \/>\n    def __init__(self):<br \/>\n        pygame.sprite.Sprite.__init__(self) #call Sprite intializer<br \/>\n        self.image, self.rect = load_image(&#8216;chimp.bmp&#8217;, -1)<br \/>\n        screen = pygame.display.get_surface()<br \/>\n        self.area = screen.get_rect()<br \/>\n        self.rect.topleft = 10, 10<br \/>\n        self.move = 9<br \/>\n        self.dizzy = 0<\/p>\n<p>    def update(self):<br \/>\n        &quot;walk or spin, depending on the monkeys state&quot;<br \/>\n        if self.dizzy:<br \/>\n            self._spin()<br \/>\n        else:<br \/>\n            self._walk()<\/p>\n<p>    def _walk(self):<br \/>\n        &quot;move the monkey across the screen, and turn at the ends&quot;<br \/>\n        newpos = self.rect.move((self.move, 0))<br \/>\n        if self.rect.left &lt; self.area.left or \\<br \/>\n            self.rect.right &gt; self.area.right:<br \/>\n            self.move = -self.move<br \/>\n            newpos = self.rect.move((self.move, 0))<br \/>\n            self.image = pygame.transform.flip(self.image, 1, 0)<br \/>\n        self.rect = newpos<\/p>\n<p>    def _spin(self):<br \/>\n        &quot;spin the monkey image&quot;<br \/>\n        center = self.rect.center<br \/>\n        self.dizzy = self.dizzy + 12<br \/>\n        if self.dizzy &gt;= 360:<br \/>\n            self.dizzy = 0<br \/>\n            self.image = self.original<br \/>\n        else:<br \/>\n            rotate = pygame.transform.rotate<br \/>\n            self.image = rotate(self.original, self.dizzy)<br \/>\n        self.rect = self.image.get_rect(center=center)<\/p>\n<p>    def punched(self):<br \/>\n        &quot;this will cause the monkey to start spinning&quot;<br \/>\n        if not self.dizzy:<br \/>\n            self.dizzy = 1<br \/>\n            self.original = self.image<\/p>\n<p>def main():<br \/>\n    &quot;&quot;&quot;this function is called when the program starts.<br \/>\n       it initializes everything it needs, then runs in<br \/>\n       a loop until the function returns.&quot;&quot;&quot;<br \/>\n#Initialize Everything<br \/>\n    pygame.init()<br \/>\n    screen = pygame.display.set_mode((468, 60))<br \/>\n    pygame.display.set_caption(&#8216;Monkey Fever&#8217;)<br \/>\n    pygame.mouse.set_visible(0)<\/p>\n<p>#Create The Backgound<br \/>\n    background = pygame.Surface(screen.get_size())<br \/>\n    background = background.convert()<br \/>\n    background.fill((250, 250, 250))<\/p>\n<p>#Put Text On The Background, Centered<br \/>\n    if pygame.font:<br \/>\n        font = pygame.font.Font(None, 36)<br \/>\n        text = font.render(&quot;Pummel The Chimp, And Win $$$&quot;, 1, (10, 10, 10))<br \/>\n        textpos = text.get_rect(centerx=background.get_width()\/2)<br \/>\n        background.blit(text, textpos)<\/p>\n<p>#Display The Background<br \/>\n    screen.blit(background, (0, 0))<br \/>\n    pygame.display.flip()<\/p>\n<p>#Prepare Game Objects<br \/>\n    clock = pygame.time.Clock()<br \/>\n    whiff_sound = load_sound(&#8216;whiff.wav&#8217;)<br \/>\n    punch_sound = load_sound(&#8216;punch.wav&#8217;)<br \/>\n    chimp = Chimp()<br \/>\n    fist = Fist()<br \/>\n    allsprites = pygame.sprite.RenderPlain((fist, chimp))<\/p>\n<p>#Main Loop<br \/>\n    going = True<br \/>\n    while going:<br \/>\n        clock.tick(60)<\/p>\n<p>        #Handle Input Events<br \/>\n        for event in pygame.event.get():<br \/>\n            if event.type == QUIT:<br \/>\n                going = False<br \/>\n            elif event.type == KEYDOWN and event.key == K_ESCAPE:<br \/>\n                going = False<br \/>\n            elif event.type == MOUSEBUTTONDOWN:<br \/>\n                if fist.punch(chimp):<br \/>\n                    punch_sound.play() #punch<br \/>\n                    chimp.punched()<br \/>\n                else:<br \/>\n                    whiff_sound.play() #miss<br \/>\n            elif event.type == MOUSEBUTTONUP:<br \/>\n                fist.unpunch()<\/p>\n<p>        allsprites.update()<\/p>\n<p>        #Draw Everything<br \/>\n        screen.blit(background, (0, 0))<br \/>\n        allsprites.draw(screen)<br \/>\n        pygame.display.flip()<\/p>\n<p>    pygame.quit()<\/p>\n<p>#Game Over<\/p>\n<p>#this calls the &#8216;main&#8217; function when this script is executed<br \/>\nif __name__ == &#8216;__main__&#8217;:<br \/>\n    main()<\/p>\n<p>[\/sourcecode]<\/p>\n<p>The aliens example <\/p>\n<p>[sourcecode language=&#8221;python&#8221;]<\/p>\n<p>#!\/usr\/bin\/env python<\/p>\n<p>import random, os.path<\/p>\n<p>#import basic pygame modules<br \/>\nimport pygame<br \/>\nfrom pygame.locals import *<\/p>\n<p>#see if we can load more than standard BMP<br \/>\nif not pygame.image.get_extended():<br \/>\n    raise SystemExit(&quot;Sorry, extended image module required&quot;)<\/p>\n<p>#game constants<br \/>\nMAX_SHOTS      = 2      #most player bullets onscreen<br \/>\nALIEN_ODDS     = 22     #chances a new alien appears<br \/>\nBOMB_ODDS      = 60    #chances a new bomb will drop<br \/>\nALIEN_RELOAD   = 12     #frames between new aliens<br \/>\nSCREENRECT     = Rect(0, 0, 640, 480)<br \/>\nSCORE          = 0<\/p>\n<p>main_dir = os.path.split(os.path.abspath(__file__))[0]<\/p>\n<p>def load_image(file):<br \/>\n    &quot;loads an image, prepares it for play&quot;<br \/>\n    file = os.path.join(main_dir, &#8216;data&#8217;, file)<br \/>\n    try:<br \/>\n        surface = pygame.image.load(file)<br \/>\n    except pygame.error:<br \/>\n        raise SystemExit(&#8216;Could not load image &quot;%s&quot; %s&#8217;%(file, pygame.get_error()))<br \/>\n    return surface.convert()<\/p>\n<p>def load_images(*files):<br \/>\n    imgs = []<br \/>\n    for file in files:<br \/>\n        imgs.append(load_image(file))<br \/>\n    return imgs<\/p>\n<p>class dummysound:<br \/>\n    def play(self): pass<\/p>\n<p>def load_sound(file):<br \/>\n    if not pygame.mixer: return dummysound()<br \/>\n    file = os.path.join(main_dir, &#8216;data&#8217;, file)<br \/>\n    try:<br \/>\n        sound = pygame.mixer.Sound(file)<br \/>\n        return sound<br \/>\n    except pygame.error:<br \/>\n        print (&#8216;Warning, unable to load, %s&#8217; % file)<br \/>\n    return dummysound()<\/p>\n<p># each type of game object gets an init and an<br \/>\n# update function. the update function is called<br \/>\n# once per frame, and it is when each object should<br \/>\n# change it&#8217;s current position and state. the Player<br \/>\n# object actually gets a &quot;move&quot; function instead of<br \/>\n# update, since it is passed extra information about<br \/>\n# the keyboard<\/p>\n<p>class Player(pygame.sprite.Sprite):<br \/>\n    speed = 10<br \/>\n    bounce = 24<br \/>\n    gun_offset = -11<br \/>\n    images = []<br \/>\n    def __init__(self):<br \/>\n        pygame.sprite.Sprite.__init__(self, self.containers)<br \/>\n        self.image = self.images[0]<br \/>\n        self.rect = self.image.get_rect(midbottom=SCREENRECT.midbottom)<br \/>\n        self.reloading = 0<br \/>\n        self.origtop = self.rect.top<br \/>\n        self.facing = -1<\/p>\n<p>    def move(self, direction):<br \/>\n        if direction: self.facing = direction<br \/>\n        self.rect.move_ip(direction*self.speed, 0)<br \/>\n        self.rect = self.rect.clamp(SCREENRECT)<br \/>\n        if direction &lt; 0:<br \/>\n            self.image = self.images[0]<br \/>\n        elif direction &gt; 0:<br \/>\n            self.image = self.images[1]<br \/>\n        self.rect.top = self.origtop &#8211; (self.rect.left\/\/self.bounce%2)<\/p>\n<p>    def gunpos(self):<br \/>\n        pos = self.facing*self.gun_offset + self.rect.centerx<br \/>\n        return pos, self.rect.top<\/p>\n<p>class Alien(pygame.sprite.Sprite):<br \/>\n    speed = 13<br \/>\n    animcycle = 12<br \/>\n    images = []<br \/>\n    def __init__(self):<br \/>\n        pygame.sprite.Sprite.__init__(self, self.containers)<br \/>\n        self.image = self.images[0]<br \/>\n        self.rect = self.image.get_rect()<br \/>\n        self.facing = random.choice((-1,1)) * Alien.speed<br \/>\n        self.frame = 0<br \/>\n        if self.facing &lt; 0:<br \/>\n            self.rect.right = SCREENRECT.right<\/p>\n<p>    def update(self):<br \/>\n        self.rect.move_ip(self.facing, 0)<br \/>\n        if not SCREENRECT.contains(self.rect):<br \/>\n            self.facing = -self.facing;<br \/>\n            self.rect.top = self.rect.bottom + 1<br \/>\n            self.rect = self.rect.clamp(SCREENRECT)<br \/>\n        self.frame = self.frame + 1<br \/>\n        self.image = self.images[self.frame\/\/self.animcycle%3]<\/p>\n<p>class Explosion(pygame.sprite.Sprite):<br \/>\n    defaultlife = 12<br \/>\n    animcycle = 3<br \/>\n    images = []<br \/>\n    def __init__(self, actor):<br \/>\n        pygame.sprite.Sprite.__init__(self, self.containers)<br \/>\n        self.image = self.images[0]<br \/>\n        self.rect = self.image.get_rect(center=actor.rect.center)<br \/>\n        self.life = self.defaultlife<\/p>\n<p>    def update(self):<br \/>\n        self.life = self.life &#8211; 1<br \/>\n        self.image = self.images[self.life\/\/self.animcycle%2]<br \/>\n        if self.life &lt;= 0: self.kill()<\/p>\n<p>class Shot(pygame.sprite.Sprite):<br \/>\n    speed = -11<br \/>\n    images = []<br \/>\n    def __init__(self, pos):<br \/>\n        pygame.sprite.Sprite.__init__(self, self.containers)<br \/>\n        self.image = self.images[0]<br \/>\n        self.rect = self.image.get_rect(midbottom=pos)<\/p>\n<p>    def update(self):<br \/>\n        self.rect.move_ip(0, self.speed)<br \/>\n        if self.rect.top &lt;= 0:<br \/>\n            self.kill()<\/p>\n<p>class Bomb(pygame.sprite.Sprite):<br \/>\n    speed = 9<br \/>\n    images = []<br \/>\n    def __init__(self, alien):<br \/>\n        pygame.sprite.Sprite.__init__(self, self.containers)<br \/>\n        self.image = self.images[0]<br \/>\n        self.rect = self.image.get_rect(midbottom=<br \/>\n                    alien.rect.move(0,5).midbottom)<\/p>\n<p>    def update(self):<br \/>\n        self.rect.move_ip(0, self.speed)<br \/>\n        if self.rect.bottom &gt;= 470:<br \/>\n            Explosion(self)<br \/>\n            self.kill()<\/p>\n<p>class Score(pygame.sprite.Sprite):<br \/>\n    def __init__(self):<br \/>\n        pygame.sprite.Sprite.__init__(self)<br \/>\n        self.font = pygame.font.Font(None, 20)<br \/>\n        self.font.set_italic(1)<br \/>\n        self.color = Color(&#8216;white&#8217;)<br \/>\n        self.lastscore = -1<br \/>\n        self.update()<br \/>\n        self.rect = self.image.get_rect().move(10, 450)<\/p>\n<p>    def update(self):<br \/>\n        if SCORE != self.lastscore:<br \/>\n            self.lastscore = SCORE<br \/>\n            msg = &quot;Score: %d&quot; % SCORE<br \/>\n            self.image = self.font.render(msg, 0, self.color)<\/p>\n<p>def main(winstyle = 0):<br \/>\n    # Initialize pygame<br \/>\n    pygame.init()<br \/>\n    if pygame.mixer and not pygame.mixer.get_init():<br \/>\n        print (&#8216;Warning, no sound&#8217;)<br \/>\n        pygame.mixer = None<\/p>\n<p>    # Set the display mode<br \/>\n    winstyle = 0  # |FULLSCREEN<br \/>\n    bestdepth = pygame.display.mode_ok(SCREENRECT.size, winstyle, 32)<br \/>\n    screen = pygame.display.set_mode(SCREENRECT.size, winstyle, bestdepth)<\/p>\n<p>    #Load images, assign to sprite classes<br \/>\n    #(do this before the classes are used, after screen setup)<br \/>\n    img = load_image(&#8216;player1.gif&#8217;)<br \/>\n    Player.images = [img, pygame.transform.flip(img, 1, 0)]<br \/>\n    img = load_image(&#8216;explosion1.gif&#8217;)<br \/>\n    Explosion.images = [img, pygame.transform.flip(img, 1, 1)]<br \/>\n    Alien.images = load_images(&#8216;alien1.gif&#8217;, &#8216;alien2.gif&#8217;, &#8216;alien3.gif&#8217;)<br \/>\n    Bomb.images = [load_image(&#8216;bomb.gif&#8217;)]<br \/>\n    Shot.images = [load_image(&#8216;shot.gif&#8217;)]<\/p>\n<p>    #decorate the game window<br \/>\n    icon = pygame.transform.scale(Alien.images[0], (32, 32))<br \/>\n    pygame.display.set_icon(icon)<br \/>\n    pygame.display.set_caption(&#8216;Pygame Aliens&#8217;)<br \/>\n    pygame.mouse.set_visible(0)<\/p>\n<p>    #create the background, tile the bgd image<br \/>\n    bgdtile = load_image(&#8216;background.gif&#8217;)<br \/>\n    background = pygame.Surface(SCREENRECT.size)<br \/>\n    for x in range(0, SCREENRECT.width, bgdtile.get_width()):<br \/>\n        background.blit(bgdtile, (x, 0))<br \/>\n    screen.blit(background, (0,0))<br \/>\n    pygame.display.flip()<\/p>\n<p>    #load the sound effects<br \/>\n    boom_sound = load_sound(&#8216;boom.wav&#8217;)<br \/>\n    shoot_sound = load_sound(&#8216;car_door.wav&#8217;)<br \/>\n    if pygame.mixer:<br \/>\n        music = os.path.join(main_dir, &#8216;data&#8217;, &#8216;house_lo.wav&#8217;)<br \/>\n        pygame.mixer.music.load(music)<br \/>\n        pygame.mixer.music.play(-1)<\/p>\n<p>    # Initialize Game Groups<br \/>\n    aliens = pygame.sprite.Group()<br \/>\n    shots = pygame.sprite.Group()<br \/>\n    bombs = pygame.sprite.Group()<br \/>\n    all = pygame.sprite.RenderUpdates()<br \/>\n    lastalien = pygame.sprite.GroupSingle()<\/p>\n<p>    #assign default groups to each sprite class<br \/>\n    Player.containers = all<br \/>\n    Alien.containers = aliens, all, lastalien<br \/>\n    Shot.containers = shots, all<br \/>\n    Bomb.containers = bombs, all<br \/>\n    Explosion.containers = all<br \/>\n    Score.containers = all<\/p>\n<p>    #Create Some Starting Values<br \/>\n    global score<br \/>\n    alienreload = ALIEN_RELOAD<br \/>\n    kills = 0<br \/>\n    clock = pygame.time.Clock()<\/p>\n<p>    #initialize our starting sprites<br \/>\n    global SCORE<br \/>\n    player = Player()<br \/>\n    Alien() #note, this &#8216;lives&#8217; because it goes into a sprite group<br \/>\n    if pygame.font:<br \/>\n        all.add(Score())<\/p>\n<p>    while player.alive():<\/p>\n<p>        #get input<br \/>\n        for event in pygame.event.get():<br \/>\n            if event.type == QUIT or \\<br \/>\n                (event.type == KEYDOWN and event.key == K_ESCAPE):<br \/>\n                    return<br \/>\n        keystate = pygame.key.get_pressed()<\/p>\n<p>        # clear\/erase the last drawn sprites<br \/>\n        all.clear(screen, background)<\/p>\n<p>        #update all the sprites<br \/>\n        all.update()<\/p>\n<p>        #handle player input<br \/>\n        direction = keystate[K_RIGHT] &#8211; keystate[K_LEFT]<br \/>\n        player.move(direction)<br \/>\n        firing = keystate[K_SPACE]<br \/>\n        if not player.reloading and firing and len(shots) &lt; MAX_SHOTS:<br \/>\n            Shot(player.gunpos())<br \/>\n            shoot_sound.play()<br \/>\n        player.reloading = firing<\/p>\n<p>        # Create new alien<br \/>\n        if alienreload:<br \/>\n            alienreload = alienreload &#8211; 1<br \/>\n        elif not int(random.random() * ALIEN_ODDS):<br \/>\n            Alien()<br \/>\n            alienreload = ALIEN_RELOAD<\/p>\n<p>        # Drop bombs<br \/>\n        if lastalien and not int(random.random() * BOMB_ODDS):<br \/>\n            Bomb(lastalien.sprite)<\/p>\n<p>        # Detect collisions<br \/>\n        for alien in pygame.sprite.spritecollide(player, aliens, 1):<br \/>\n            boom_sound.play()<br \/>\n            Explosion(alien)<br \/>\n            Explosion(player)<br \/>\n            SCORE = SCORE + 1<br \/>\n            player.kill()<\/p>\n<p>        for alien in pygame.sprite.groupcollide(shots, aliens, 1, 1).keys():<br \/>\n            boom_sound.play()<br \/>\n            Explosion(alien)<br \/>\n            SCORE = SCORE + 1<\/p>\n<p>        for bomb in pygame.sprite.spritecollide(player, bombs, 1):<br \/>\n            boom_sound.play()<br \/>\n            Explosion(player)<br \/>\n            Explosion(bomb)<br \/>\n            player.kill()<\/p>\n<p>        #draw the scene<br \/>\n        dirty = all.draw(screen)<br \/>\n        pygame.display.update(dirty)<\/p>\n<p>        #cap the framerate<br \/>\n        clock.tick(40)<\/p>\n<p>    if pygame.mixer:<br \/>\n        pygame.mixer.music.fadeout(1000)<br \/>\n    pygame.time.wait(1000)<br \/>\n    pygame.quit()<\/p>\n<p>#call the &quot;main&quot; function if running this script<br \/>\nif __name__ == &#8216;__main__&#8217;: main()<\/p>\n<p>[\/sourcecode]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today I will ramble about game development with python . Python is very easy to learn and it is a very easy to prototype games\u00a0 with python. Pygame\u00a0 is a SDL binding fo python , visit pygame.org for more details. 2D Game Development Concepts Sprites : Sprites are moveable game entities , I bet all [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4],"tags":[],"_links":{"self":[{"href":"https:\/\/sandeepmathew.com\/index.php\/wp-json\/wp\/v2\/posts\/151"}],"collection":[{"href":"https:\/\/sandeepmathew.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sandeepmathew.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sandeepmathew.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sandeepmathew.com\/index.php\/wp-json\/wp\/v2\/comments?post=151"}],"version-history":[{"count":0,"href":"https:\/\/sandeepmathew.com\/index.php\/wp-json\/wp\/v2\/posts\/151\/revisions"}],"wp:attachment":[{"href":"https:\/\/sandeepmathew.com\/index.php\/wp-json\/wp\/v2\/media?parent=151"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sandeepmathew.com\/index.php\/wp-json\/wp\/v2\/categories?post=151"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sandeepmathew.com\/index.php\/wp-json\/wp\/v2\/tags?post=151"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}