rock_spawner()


#
# Main
#######
if __name__ == '__main__':
    # Create frame
    frame = simplegui.create_frame('Spaceship prototype', SCREEN_WIDTH,
                                   SCREEN_HEIGHT, 100)

    # Create FPS
    fps = FPS()

    # Load medias
    loader = Loader(frame, SCREEN_WIDTH, start)

    # Images by Kim Lathrop
    loader.add_image(
        'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blue.png',
        'asteroid')
    loader.add_image(
        'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/debris2_blue.png',
        'debris')
    loader.add_image(
        'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/shot2.png',
        'missile')
    loader.add_image(
        'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/nebula_brown.png',
        'nebula')
    loader.add_image(
class RiceRocks:
    """
    General class dealing the game.
    """
    def __init__(self):
        """
        Set elements of the game.
        """
        self.loaded = False

        self.keydown_left = False
        self.keydown_right = False
        self.lives = 3
        self.my_ship = None
        self.nb_bombs = None
        self.score = 0
        self.started = False
        self.time = 0

        self.explosions = []
        self.live_explosions = []
        self.missiles = []
        self.rocks = []

        self.animate_background_active = True
        self.music_active = True
        self.sounds_active = True
        self.timer = simplegui.create_timer(1000, self.rock_spawner)

        self.img_infos = None
        self.medias = None

    def bomb_explode(self):
        """
        If it remains bomb
        then detonated a bomb that destroys all asteroids.
        """
        if self.nb_bombs:
            self.nb_bombs -= 1
            if self.sounds_active:
                self.medias.get_sound('bomb_explode').rewind()
                self.medias.get_sound('bomb_explode').play()
            for rock in self.rocks:
                self.explosions.append(Sprite(rock.position, rock.velocity,
                                              0, rock.angle_velocity,
                                              'asteroid_explosion'))
            self.rocks = []

    def draw_and_update(self, canvas):
        """
        Draw and update all stuffs in each FPS cycle.

        :param canvas: simplegui.Canvas
        """
        self.time += 1

        # Draw static background
        if not SIMPLEGUICS2PYGAME:
            canvas.draw_image(self.medias.get_image('nebula'),
                              self.img_infos['nebula'].get_center(),
                              self.img_infos['nebula'].get_size(),
                              (SCREEN_WIDTH/2.0, SCREEN_HEIGHT/2.0),
                              (SCREEN_WIDTH, SCREEN_HEIGHT))

        # Draw animated background
        if self.animate_background_active:
            center = self.img_infos['debris'].get_center()
            size = self.img_infos['debris'].get_size()

            wtime = (self.time/4.0) % SCREEN_WIDTH

            canvas.draw_image(self.medias.get_image('debris'),
                              center,
                              size,
                              (wtime - SCREEN_WIDTH/2.0, SCREEN_HEIGHT/2.0),
                              (SCREEN_WIDTH, SCREEN_HEIGHT))
            canvas.draw_image(self.medias.get_image('debris'),
                              center,
                              size,
                              (wtime + SCREEN_WIDTH/2.0, SCREEN_HEIGHT/2.0),
                              (SCREEN_WIDTH, SCREEN_HEIGHT))

        # Draw missiles, ship, asteroids and explosions
        for missile in self.missiles:
            missile.draw(canvas)

        if self.lives > 0:
            self.my_ship.draw(canvas)

        for rock in self.rocks:
            rock.draw(canvas)

        for i in range(len(self.explosions) - 1, -1, -1):
            explosion = self.explosions[i]

            explosion.draw(canvas)
            explosion.update()
            if explosion.lifespan <= 0:  # explosion finished
                del self.explosions[i]

        # Update ship
        self.my_ship.update()

        # Update missiles
        for i in range(len(self.missiles) - 1, -1, -1):
            missile = self.missiles[i]

            missile.update()
            if missile.lifespan <= 0:  # missile disappear
                del self.missiles[i]
            else:                      # active missile
                for j in range(len(self.rocks) - 1, -1, -1):
                    # Check collide with asteroids
                    rock = self.rocks[j]

                    if missile.collide(rock):  # collide
                        del self.missiles[i]
                        del self.rocks[j]

                        if not rock.little:
                            # Divide in two little asteroids
                            angle = vector_to_angle(missile.velocity)
                            mvel = math.sqrt(
                                (rock.velocity[0]*rock.velocity[0]
                                 + rock.velocity[1]*rock.velocity[1])/2.0)

                            vel = list(angle_to_vector(angle - math.pi/4))
                            vel[0] *= mvel
                            vel[1] *= mvel
                            little1 = Asteroid(rock.position, vel,
                                               rock.angle_velocity*2,
                                               rock.num, True)

                            vel = list(angle_to_vector(angle + math.pi/4))
                            vel[0] *= mvel
                            vel[1] *= mvel
                            little2 = Asteroid(rock.position, vel,
                                               -rock.angle_velocity*2,
                                               rock.num, True)

                            while True:
                                little1.position[0] += little1.velocity[0]
                                little1.position[1] += little1.velocity[1]
                                little2.position[0] += little2.velocity[0]
                                little2.position[1] += little2.velocity[1]
                                if not little1.collide(little2):
                                    break
                            self.rocks.extend((little1, little2))

                        self.score += 1
                        if self.score % 10 == 0:  # add a new bomb
                            self.nb_bombs += 1
                            if self.sounds_active:
                                self.medias.get_sound('bomb_extra').rewind()
                                self.medias.get_sound('bomb_extra').play()
                            if self.score % 50 == 0:  # add a new live
                                self.lives += 1

                        self.explosions.append(Sprite(rock.position,
                                                      rock.velocity,
                                                      0, rock.angle_velocity,
                                                      'asteroid_explosion'))

                        break

        # Update asteroids
        for i in range(len(self.rocks) - 1, -1, -1):
            rock = self.rocks[i]

            rock.update()
            if self.my_ship.collide(rock):  # collide with ship
                del self.rocks[i]

                self.explosions.append(Sprite(rock.position, rock.velocity,
                                              0, rock.angle_velocity,
                                              'asteroid_collide_explosion'))
                self.live_explosions.append(Sprite((self.lives*40, 40),
                                                   (0, 0),
                                                   -math.pi/2, 0,
                                                   'live_explosion'))

                self.lives = max(0, self.lives - 1)
                if self.lives <= 0:  # game over
                    self.stop()

                    self.explosions.append(Sprite(self.my_ship.position,
                                                  self.my_ship.velocity,
                                                  0,
                                                  self.my_ship.angle_velocity,
                                                  'ship_explosion'))

                    if self.sounds_active:
                        self.medias.get_sound('death').rewind()
                        self.medias.get_sound('death').play()

                    break
                else:
                    if self.sounds_active:
                        self.medias.get_sound('collide').rewind()
                        self.medias.get_sound('collide').play()
            else:
                for j in range(0, i):
                    other = self.rocks[j]
                    if rock.collide(other):
                        rock.position[0] = (rock.position[0]
                                            - rock.velocity[0]) % SCREEN_WIDTH
                        rock.position[1] = (rock.position[1]
                                            - rock.velocity[1]) % SCREEN_HEIGHT

                        other.position[0] = ((other.position[0]
                                              - other.velocity[0])
                                             % SCREEN_WIDTH)
                        other.position[1] = ((other.position[1]
                                              - other.velocity[1])
                                             % SCREEN_HEIGHT)

                        # Elastic collision (with radius*3 as mass)
                        # https://en.wikipedia.org/wiki/Elastic_collision
                        tmp_sum = (rock.radius + other.radius)*3
                        tmp_diff = (rock.radius - other.radius)*3

                        double = 2*3*other.radius
                        new_x = (float(tmp_diff*rock.velocity[0]
                                       + double*other.velocity[0])/tmp_sum)
                        new_y = (float(tmp_diff*rock.velocity[1]
                                       + double*other.velocity[1])/tmp_sum)

                        double = 2*3*rock.radius
                        other.velocity[0] = float(
                            double*rock.velocity[0]
                            - tmp_diff*other.velocity[0])/tmp_sum
                        other.velocity[1] = float(
                            double*rock.velocity[1]
                            - tmp_diff*other.velocity[1])/tmp_sum

                        rock.velocity[0] = new_x
                        rock.velocity[1] = new_y

        # Display number of lives
        if self.started:
            info = self.img_infos['ship']
            for i in range(self.lives):
                canvas.draw_image(self.medias.get_image('ship'),
                                  info.get_center(), info.get_size(),
                                  (40 + i*40, 40), (40, 40),
                                  -math.pi/2)

        # Draw and update live explosions
        for i in range(len(self.live_explosions) - 1, -1, -1):
            live_explosion = self.live_explosions[i]

            canvas.draw_image(live_explosion.image,
                              live_explosion.image_center,
                              live_explosion.image_size,
                              live_explosion.position, (40, 40),
                              -math.pi/2)
            live_explosion.update()
            if live_explosion.lifespan <= 0:  # explosion finished
                del self.live_explosions[i]

        # Display number of bombs
        if self.started and self.nb_bombs:
            info = self.img_infos['bomb']
            for i in range(self.nb_bombs):
                canvas.draw_image(self.medias.get_image('bomb'),
                                  info.get_center(), info.get_size(),
                                  (40 + i*40, 80), (20, 40),
                                  -math.pi/2)

        # Display score
        size = 36
        font = 'sans-serif'

        text1 = 'Score'
        width1 = frame.get_canvas_textwidth(text1, size, font)
        text2 = str(self.score)
        width2 = frame.get_canvas_textwidth(text2, size, font)

        canvas.draw_text(text1, (SCREEN_WIDTH - 22 - width1, 22 + size*3.0/4),
                         size, 'Gray', font)
        canvas.draw_text(text2, (SCREEN_WIDTH - 22 - width2, 22 + size*7.0/4),
                         size, 'Gray', font)

        canvas.draw_text(text1, (SCREEN_WIDTH - 20 - width1, 20 + size*3.0/4),
                         size, 'White', font)
        canvas.draw_text(text2, (SCREEN_WIDTH - 20 - width2, 20 + size*7.0/4),
                         size, 'White', font)

        # Draw splash screen if game not started
        if not self.started:
            size = self.img_infos['splash'].get_size()
            canvas.draw_image(self.medias.get_image('splash'),
                              self.img_infos['splash'].get_center(), size,
                              (SCREEN_WIDTH/2.0, SCREEN_HEIGHT/2.0), size)

        # Update and draw FPS (if started)
        fps.draw_fct(canvas)

    def load_medias(self):
        """
        Load images and sounds and waiting all is loaded,
        the set the general draw handler.
        """
        self.img_infos = {'asteroid-1': ImageInfo((45, 45), (90, 90), 40),
                          'asteroid-2': ImageInfo((45, 45), (90, 90), 40),
                          'asteroid-3': ImageInfo((45, 45), (90, 90), 38),
                          'asteroid_explosion': ImageInfo((64, 64), (128, 128),
                                                          17, 24, True),
                          'asteroid_collide_explosion': ImageInfo((64, 64),
                                                                  (128, 128),
                                                                  17, 24,
                                                                  True),
                          'bomb': ImageInfo((10, 10), (20, 20)),
                          'debris': ImageInfo((320, 240), (640, 480)),
                          'little-asteroid-1': ImageInfo((45, 45), (90, 90),
                                                         27, None, False,
                                                         (60, 60)),
                          'little-asteroid-2': ImageInfo((45, 45), (90, 90),
                                                         27, None, False,
                                                         (60, 60)),
                          'little-asteroid-3': ImageInfo((45, 45), (90, 90),
                                                         26, None, False,
                                                         (60, 60)),
                          'live_explosion': ImageInfo((64, 64), (128, 128),
                                                      17, 24, True),
                          'missile': ImageInfo((5, 5), (10, 10), 3, 50),
                          'nebula': ImageInfo((400, 300), (800, 600)),
                          'ship': ImageInfo((45, 45), (90, 90), 35),
                          'ship_explosion': ImageInfo((64, 64), (128, 128),
                                                      17, 24, True),
                          'splash': ImageInfo((200, 150), (400, 300))}

        def init():
            """
            Init the game after medias loaded.
            """
            if SIMPLEGUICS2PYGAME:
                frame._set_canvas_background_image(
                    self.medias.get_image('nebula'))

            self.medias._images['live_explosion'] = \
                self.medias._images['ship_explosion']

            for i in range(1, 4):
                self.medias._images['little-asteroid-' + str(i)] = \
                    self.medias._images['asteroid-' + str(i)]

            self.medias._sounds['asteroid_collide_explosion'] = \
                self.medias._sounds['asteroid_explosion']

            self.medias.get_sound('missile').set_volume(.5)

            self.my_ship = Ship((SCREEN_WIDTH/2.0, SCREEN_HEIGHT/2.0), (0, 0),
                                -math.pi/2, 'ship')

            frame.set_draw_handler(self.draw_and_update)

            frame.set_keydown_handler(keydown)
            frame.set_keyup_handler(keyup)

            frame.set_mouseclick_handler(click)

            if self.music_active:
                self.medias.get_sound('intro').play()

            self.loaded = True

        self.medias = Loader(frame, SCREEN_WIDTH, init)

        # Images by Kim Lathrop
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blend.png',
                              'asteroid-1')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blue.png',
                              'asteroid-2')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_brown.png',
                              'asteroid-3')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_alpha.png',
                              'asteroid_explosion')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_alpha2.png',
                              'asteroid_collide_explosion')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/shot3.png',
                              'bomb')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/debris2_blue.png',
                              'debris')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/shot2.png',
                              'missile')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/nebula_brown.png',
                              'nebula')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/double_ship.png',
                              'ship')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_orange.png',
                              'ship_explosion')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/splash.png',
                              'splash')

        # Sounds from http://www.sounddogs.com/ (not free)
        self.medias.add_sound('http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/explosion.ogg',
                              'asteroid_explosion')
        self.medias.add_sound('http://rpg.hamsterrepublic.com/wiki-images/f/f4/StormMagic.ogg',
                              'bomb_explode')
        self.medias.add_sound('http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/extralife.ogg',
                              'bomb_extra')
        self.medias.add_sound('http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/eatedible.ogg',
                              'collide')
        self.medias.add_sound('http://rpg.hamsterrepublic.com/wiki-images/5/58/Death.ogg',
                              'death')
        self.medias.add_sound('http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/intromusic.ogg',
                              'intro')
        self.medias.add_sound('http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/soundtrack.ogg',
                              'soundtrack')
        self.medias.add_sound('http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/missile.ogg',
                              'missile')
        self.medias.add_sound('http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/thrust.ogg',
                              'ship_thrust')

        self.medias.load()

        self.medias.wait_loaded()

    def rock_spawner(self):
        """
        If the maximum is not reached
        then spawns a rock (not too close to the ship).
        """
        if len(self.rocks) < 10:
            too_close = True

            def random_vel():
                """
                :return: int or float
                """
                return (min(2,
                            (random.random()*(self.score/10.0 + 0.1)))
                        * random.choice((-1, 1)))

            for _ in range(10):  # try 10 times
                rock_pos = (random.randrange(0, SCREEN_WIDTH),
                            random.randrange(0, SCREEN_HEIGHT))
                rock_vel = (random_vel(),
                            random_vel())
                rock_ang_vel = random.choice((-1, 1))*(random.random()*0.05
                                                       + 0.01)

                rock = Asteroid(rock_pos, rock_vel,
                                rock_ang_vel,
                                random.randint(1, 3))

                too_close = False
                for rock2 in self.rocks:
                    if rock2.collide(rock):
                        too_close = True

                        break

                too_close = (too_close
                             or (self.my_ship.distance(rock)
                                 < (self.my_ship.radius + rock.radius)*3))
                if not too_close:
                    break

            if not too_close:
                self.rocks.append(rock)

    def start(self):
        """
        Start the game.
        """
        if self.music_active:
            self.medias.get_sound('intro').rewind()
            self.medias.get_sound('soundtrack').play()

        self.keydown_left = False
        self.keydown_right = False
        self.lives = 3
        self.nb_bombs = 0
        self.score = 0

        self.my_ship = Ship((SCREEN_WIDTH/2.0, SCREEN_HEIGHT/2.0), (0, 0),
                            -math.pi/2, 'ship')

        self.explosions = []
        self.missiles = []
        self.rocks = []

        self.timer.start()
        self.rock_spawner()

        self.started = True

    def stop(self):
        """
        Stop the game.
        """
        self.timer.stop()

        self.nb_bombs = None

        self.missiles = []
        self.rocks = []

        self.started = False

        self.my_ship.stop()

        if self.music_active:
            self.medias.get_sound('soundtrack').rewind()
            self.medias.get_sound('intro').play()
    rock_spawner()


#
# Main
#######
if __name__ == '__main__':
    # Create frame
    frame = simplegui.create_frame('Spaceship prototype',
                                   SCREEN_WIDTH, SCREEN_HEIGHT, 100)

    # Create FPS
    fps = FPS()

    # Load medias
    loader = Loader(frame, SCREEN_WIDTH, start)

    # Images by Kim Lathrop
    loader.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blue.png',
                     'asteroid')
    loader.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/debris2_blue.png',
                     'debris')
    loader.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/shot2.png',
                     'missile')
    loader.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/nebula_brown.png',
                     'nebula')
    loader.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/double_ship.png',
                     'ship')

    asteroid_info = ImageInfo((45, 45), (90, 90), 40)
    debris_info = ImageInfo((320, 240), (640, 480))
Exemple #4
0
    # Set the real draw handler
    frame.set_draw_handler(draw)


def quit_prog():
    """
    Stop sounds and frame
    """
    loader.pause_sounds()  # stop all sounds
    frame.stop()
    if SIMPLEGUICS2PYGAME and frame._print_stats_cache:
        loader.print_stats_cache()


loader = Loader(frame,  # the frame
                WIDTH,  # the width frame
                init)   # the function to call after loading

# Specified images to load with its URL and give them a name.
loader.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blend.png',
                 'asteroid')
loader.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/double_ship.png',
                 'double_ship')
loader.add_image('xxx',
                 'incorrect url')

# Specified sounds to load with its URL and give them a name.
loader.add_sound('http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/explosion.ogg',
                 'explosion')
loader.add_sound('http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/soundtrack.ogg',
                 'soundtrack')
    def load_medias(self):
        """
        Load images and sounds and waiting all is loaded,
        the set the general draw handler.
        """
        self.img_infos = {'asteroid-1': ImageInfo((45, 45), (90, 90), 40),
                          'asteroid-2': ImageInfo((45, 45), (90, 90), 40),
                          'asteroid-3': ImageInfo((45, 45), (90, 90), 38),
                          'asteroid_explosion': ImageInfo((64, 64), (128, 128),
                                                          17, 24, True),
                          'asteroid_collide_explosion': ImageInfo((64, 64),
                                                                  (128, 128),
                                                                  17, 24,
                                                                  True),
                          'bomb': ImageInfo((10, 10), (20, 20)),
                          'debris': ImageInfo((320, 240), (640, 480)),
                          'little-asteroid-1': ImageInfo((45, 45), (90, 90),
                                                         27, None, False,
                                                         (60, 60)),
                          'little-asteroid-2': ImageInfo((45, 45), (90, 90),
                                                         27, None, False,
                                                         (60, 60)),
                          'little-asteroid-3': ImageInfo((45, 45), (90, 90),
                                                         26, None, False,
                                                         (60, 60)),
                          'live_explosion': ImageInfo((64, 64), (128, 128),
                                                      17, 24, True),
                          'missile': ImageInfo((5, 5), (10, 10), 3, 50),
                          'nebula': ImageInfo((400, 300), (800, 600)),
                          'ship': ImageInfo((45, 45), (90, 90), 35),
                          'ship_explosion': ImageInfo((64, 64), (128, 128),
                                                      17, 24, True),
                          'splash': ImageInfo((200, 150), (400, 300))}

        def init():
            """
            Init the game after medias loaded.
            """
            if SIMPLEGUICS2PYGAME:
                frame._set_canvas_background_image(
                    self.medias.get_image('nebula'))

            self.medias._images['live_explosion'] = \
                self.medias._images['ship_explosion']

            for i in range(1, 4):
                self.medias._images['little-asteroid-' + str(i)] = \
                    self.medias._images['asteroid-' + str(i)]

            self.medias._sounds['asteroid_collide_explosion'] = \
                self.medias._sounds['asteroid_explosion']

            self.medias.get_sound('missile').set_volume(.5)

            self.my_ship = Ship((SCREEN_WIDTH/2.0, SCREEN_HEIGHT/2.0), (0, 0),
                                -math.pi/2, 'ship')

            frame.set_draw_handler(self.draw_and_update)

            frame.set_keydown_handler(keydown)
            frame.set_keyup_handler(keyup)

            frame.set_mouseclick_handler(click)

            if self.music_active:
                self.medias.get_sound('intro').play()

            self.loaded = True

        self.medias = Loader(frame, SCREEN_WIDTH, init)

        # Images by Kim Lathrop
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blend.png',
                              'asteroid-1')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blue.png',
                              'asteroid-2')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_brown.png',
                              'asteroid-3')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_alpha.png',
                              'asteroid_explosion')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_alpha2.png',
                              'asteroid_collide_explosion')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/shot3.png',
                              'bomb')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/debris2_blue.png',
                              'debris')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/shot2.png',
                              'missile')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/nebula_brown.png',
                              'nebula')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/double_ship.png',
                              'ship')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_orange.png',
                              'ship_explosion')
        self.medias.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/splash.png',
                              'splash')

        # Sounds from http://www.sounddogs.com/ (not free)
        self.medias.add_sound('http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/explosion.ogg',
                              'asteroid_explosion')
        self.medias.add_sound('http://rpg.hamsterrepublic.com/wiki-images/f/f4/StormMagic.ogg',
                              'bomb_explode')
        self.medias.add_sound('http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/extralife.ogg',
                              'bomb_extra')
        self.medias.add_sound('http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/eatedible.ogg',
                              'collide')
        self.medias.add_sound('http://rpg.hamsterrepublic.com/wiki-images/5/58/Death.ogg',
                              'death')
        self.medias.add_sound('http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/intromusic.ogg',
                              'intro')
        self.medias.add_sound('http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/soundtrack.ogg',
                              'soundtrack')
        self.medias.add_sound('http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/missile.ogg',
                              'missile')
        self.medias.add_sound('http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/thrust.ogg',
                              'ship_thrust')

        self.medias.load()

        self.medias.wait_loaded()
    """
    if not SIMPLEGUICS2PYGAME:
        global logo

        logo = loader.get_image('logo')

    frame.set_draw_handler(draw)

    if SIMPLEGUICS2PYGAME:
        from sys import argv

        if len(argv) == 2:
            frame._save_canvas_and_stop(argv[1])


loader = Loader(frame, WIDTH, init)
loader.add_image(
    'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/double_ship.png',
    'double_ship')
if not SIMPLEGUICS2PYGAME:
    loader.add_image(
        'http://simpleguics2pygame.readthedocs.org/en/latest/_images/SimpleGUICS2Pygame_64x64_t.png',
        'logo')
loader.load()

loader.wait_loaded()

if SIMPLEGUICS2PYGAME:
    logo = simplegui._load_local_image(
        '../_img/SimpleGUICS2Pygame_64x64_t.png')
class RiceRocks:
    """
    General class dealing the game.
    """
    def __init__(self):
        """
        Set elements of the game.
        """
        self.loaded = False

        self.keydown_left = False
        self.keydown_right = False
        self.lives = 3
        self.my_ship = None
        self.nb_bombs = None
        self.score = 0
        self.started = False
        self.time = 0

        self.explosions = []
        self.live_explosions = []
        self.missiles = []
        self.rocks = []

        self.animate_background_active = True
        self.music_active = True
        self.sounds_active = True
        self.timer = simplegui.create_timer(1000, self.rock_spawner)

        self.img_infos = None
        self.medias = None

    def bomb_explode(self):
        """
        If it remains bomb
        then detonated a bomb that destroys all asteroids.
        """
        if self.nb_bombs:
            self.nb_bombs -= 1
            if self.sounds_active:
                self.medias.get_sound('bomb_explode').rewind()
                self.medias.get_sound('bomb_explode').play()
            for rock in self.rocks:
                self.explosions.append(
                    Sprite(rock.position, rock.velocity, 0,
                           rock.angle_velocity, 'asteroid_explosion'))
            self.rocks = []

    def draw_and_update(self, canvas):
        """
        Draw and update all stuffs in each FPS cycle.

        :param canvas: simplegui.Canvas
        """
        self.time += 1

        # Draw static background
        if not SIMPLEGUICS2PYGAME:
            canvas.draw_image(self.medias.get_image('nebula'),
                              self.img_infos['nebula'].get_center(),
                              self.img_infos['nebula'].get_size(),
                              (SCREEN_WIDTH / 2.0, SCREEN_HEIGHT / 2.0),
                              (SCREEN_WIDTH, SCREEN_HEIGHT))

        # Draw animated background
        if self.animate_background_active:
            center = self.img_infos['debris'].get_center()
            size = self.img_infos['debris'].get_size()

            wtime = (self.time / 4.0) % SCREEN_WIDTH

            canvas.draw_image(
                self.medias.get_image('debris'), center, size,
                (wtime - SCREEN_WIDTH / 2.0, SCREEN_HEIGHT / 2.0),
                (SCREEN_WIDTH, SCREEN_HEIGHT))
            canvas.draw_image(
                self.medias.get_image('debris'), center, size,
                (wtime + SCREEN_WIDTH / 2.0, SCREEN_HEIGHT / 2.0),
                (SCREEN_WIDTH, SCREEN_HEIGHT))

        # Draw missiles, ship, asteroids and explosions
        for missile in self.missiles:
            missile.draw(canvas)

        if self.lives > 0:
            self.my_ship.draw(canvas)

        for rock in self.rocks:
            rock.draw(canvas)

        for i in range(len(self.explosions) - 1, -1, -1):
            explosion = self.explosions[i]

            explosion.draw(canvas)
            explosion.update()
            if explosion.lifespan <= 0:  # explosion finished
                del self.explosions[i]

        # Update ship
        self.my_ship.update()

        # Update missiles
        for i in range(len(self.missiles) - 1, -1, -1):
            missile = self.missiles[i]

            missile.update()
            if missile.lifespan <= 0:  # missile disappear
                del self.missiles[i]
            else:  # active missile
                for j in range(len(self.rocks) - 1, -1, -1):
                    # Check collide with asteroids
                    rock = self.rocks[j]

                    if missile.collide(rock):  # collide
                        del self.missiles[i]
                        del self.rocks[j]

                        if not rock.little:
                            # Divide in two little asteroids
                            angle = vector_to_angle(missile.velocity)
                            mvel = math.sqrt(
                                (rock.velocity[0] * rock.velocity[0] +
                                 rock.velocity[1] * rock.velocity[1]) / 2.0)

                            vel = list(angle_to_vector(angle - math.pi / 4))
                            vel[0] *= mvel
                            vel[1] *= mvel
                            little1 = Asteroid(rock.position, vel,
                                               rock.angle_velocity * 2,
                                               rock.num, True)

                            vel = list(angle_to_vector(angle + math.pi / 4))
                            vel[0] *= mvel
                            vel[1] *= mvel
                            little2 = Asteroid(rock.position, vel,
                                               -rock.angle_velocity * 2,
                                               rock.num, True)

                            while True:
                                little1.position[0] += little1.velocity[0]
                                little1.position[1] += little1.velocity[1]
                                little2.position[0] += little2.velocity[0]
                                little2.position[1] += little2.velocity[1]
                                if not little1.collide(little2):
                                    break
                            self.rocks.extend((little1, little2))

                        self.score += 1
                        if self.score % 10 == 0:  # add a new bomb
                            self.nb_bombs += 1
                            if self.sounds_active:
                                self.medias.get_sound('bomb_extra').rewind()
                                self.medias.get_sound('bomb_extra').play()
                            if self.score % 50 == 0:  # add a new live
                                self.lives += 1

                        self.explosions.append(
                            Sprite(rock.position, rock.velocity, 0,
                                   rock.angle_velocity, 'asteroid_explosion'))

                        break

        # Update asteroids
        for i in range(len(self.rocks) - 1, -1, -1):
            rock = self.rocks[i]

            rock.update()
            if self.my_ship.collide(rock):  # collide with ship
                del self.rocks[i]

                self.explosions.append(
                    Sprite(rock.position, rock.velocity, 0,
                           rock.angle_velocity, 'asteroid_collide_explosion'))
                self.live_explosions.append(
                    Sprite((self.lives * 40, 40), (0, 0), -math.pi / 2, 0,
                           'live_explosion'))

                self.lives = max(0, self.lives - 1)
                if self.lives <= 0:  # game over
                    self.stop()

                    self.explosions.append(
                        Sprite(self.my_ship.position, self.my_ship.velocity, 0,
                               self.my_ship.angle_velocity, 'ship_explosion'))

                    if self.sounds_active:
                        self.medias.get_sound('death').rewind()
                        self.medias.get_sound('death').play()

                    break
                else:
                    if self.sounds_active:
                        self.medias.get_sound('collide').rewind()
                        self.medias.get_sound('collide').play()
            else:
                for j in range(0, i):
                    other = self.rocks[j]
                    if rock.collide(other):
                        rock.position[0] = (rock.position[0] -
                                            rock.velocity[0]) % SCREEN_WIDTH
                        rock.position[1] = (rock.position[1] -
                                            rock.velocity[1]) % SCREEN_HEIGHT

                        other.position[0] = (
                            (other.position[0] - other.velocity[0]) %
                            SCREEN_WIDTH)
                        other.position[1] = (
                            (other.position[1] - other.velocity[1]) %
                            SCREEN_HEIGHT)

                        # Elastic collision (with radius*3 as mass)
                        # https://en.wikipedia.org/wiki/Elastic_collision
                        tmp_sum = (rock.radius + other.radius) * 3
                        tmp_diff = (rock.radius - other.radius) * 3

                        double = 2 * 3 * other.radius
                        new_x = (float(tmp_diff * rock.velocity[0] +
                                       double * other.velocity[0]) / tmp_sum)
                        new_y = (float(tmp_diff * rock.velocity[1] +
                                       double * other.velocity[1]) / tmp_sum)

                        double = 2 * 3 * rock.radius
                        other.velocity[0] = float(double * rock.velocity[0] -
                                                  tmp_diff *
                                                  other.velocity[0]) / tmp_sum
                        other.velocity[1] = float(double * rock.velocity[1] -
                                                  tmp_diff *
                                                  other.velocity[1]) / tmp_sum

                        rock.velocity[0] = new_x
                        rock.velocity[1] = new_y

        # Display number of lives
        if self.started:
            info = self.img_infos['ship']
            for i in range(self.lives):
                canvas.draw_image(self.medias.get_image('ship'),
                                  info.get_center(), info.get_size(),
                                  (40 + i * 40, 40), (40, 40), -math.pi / 2)

        # Draw and update live explosions
        for i in range(len(self.live_explosions) - 1, -1, -1):
            live_explosion = self.live_explosions[i]

            canvas.draw_image(live_explosion.image,
                              live_explosion.image_center,
                              live_explosion.image_size,
                              live_explosion.position, (40, 40), -math.pi / 2)
            live_explosion.update()
            if live_explosion.lifespan <= 0:  # explosion finished
                del self.live_explosions[i]

        # Display number of bombs
        if self.started and self.nb_bombs:
            info = self.img_infos['bomb']
            for i in range(self.nb_bombs):
                canvas.draw_image(self.medias.get_image('bomb'),
                                  info.get_center(), info.get_size(),
                                  (40 + i * 40, 80), (20, 40), -math.pi / 2)

        # Display score
        size = 36
        font = 'sans-serif'

        text1 = 'Score'
        width1 = frame.get_canvas_textwidth(text1, size, font)
        text2 = str(self.score)
        width2 = frame.get_canvas_textwidth(text2, size, font)

        canvas.draw_text(text1,
                         (SCREEN_WIDTH - 22 - width1, 22 + size * 3.0 / 4),
                         size, 'Gray', font)
        canvas.draw_text(text2,
                         (SCREEN_WIDTH - 22 - width2, 22 + size * 7.0 / 4),
                         size, 'Gray', font)

        canvas.draw_text(text1,
                         (SCREEN_WIDTH - 20 - width1, 20 + size * 3.0 / 4),
                         size, 'White', font)
        canvas.draw_text(text2,
                         (SCREEN_WIDTH - 20 - width2, 20 + size * 7.0 / 4),
                         size, 'White', font)

        # Draw splash screen if game not started
        if not self.started:
            size = self.img_infos['splash'].get_size()
            canvas.draw_image(self.medias.get_image('splash'),
                              self.img_infos['splash'].get_center(), size,
                              (SCREEN_WIDTH / 2.0, SCREEN_HEIGHT / 2.0), size)

        # Update and draw FPS (if started)
        fps.draw_fct(canvas)

    def load_medias(self):
        """
        Load images and sounds and waiting all is loaded,
        the set the general draw handler.
        """
        self.img_infos = {
            'asteroid-1':
            ImageInfo((45, 45), (90, 90), 40),
            'asteroid-2':
            ImageInfo((45, 45), (90, 90), 40),
            'asteroid-3':
            ImageInfo((45, 45), (90, 90), 38),
            'asteroid_explosion':
            ImageInfo((64, 64), (128, 128), 17, 24, True),
            'asteroid_collide_explosion':
            ImageInfo((64, 64), (128, 128), 17, 24, True),
            'bomb':
            ImageInfo((10, 10), (20, 20)),
            'debris':
            ImageInfo((320, 240), (640, 480)),
            'little-asteroid-1':
            ImageInfo((45, 45), (90, 90), 27, None, False, (60, 60)),
            'little-asteroid-2':
            ImageInfo((45, 45), (90, 90), 27, None, False, (60, 60)),
            'little-asteroid-3':
            ImageInfo((45, 45), (90, 90), 26, None, False, (60, 60)),
            'live_explosion':
            ImageInfo((64, 64), (128, 128), 17, 24, True),
            'missile':
            ImageInfo((5, 5), (10, 10), 3, 50),
            'nebula':
            ImageInfo((400, 300), (800, 600)),
            'ship':
            ImageInfo((45, 45), (90, 90), 35),
            'ship_explosion':
            ImageInfo((64, 64), (128, 128), 17, 24, True),
            'splash':
            ImageInfo((200, 150), (400, 300))
        }

        def init():
            """
            Init the game after medias loaded.
            """
            if SIMPLEGUICS2PYGAME:
                frame._set_canvas_background_image(
                    self.medias.get_image('nebula'))

            self.medias._images['live_explosion'] = \
                self.medias._images['ship_explosion']

            for i in range(1, 4):
                self.medias._images['little-asteroid-' + str(i)] = \
                    self.medias._images['asteroid-' + str(i)]

            self.medias._sounds['asteroid_collide_explosion'] = \
                self.medias._sounds['asteroid_explosion']

            self.medias.get_sound('missile').set_volume(.5)

            self.my_ship = Ship((SCREEN_WIDTH / 2.0, SCREEN_HEIGHT / 2.0),
                                (0, 0), -math.pi / 2, 'ship')

            frame.set_draw_handler(self.draw_and_update)

            frame.set_keydown_handler(keydown)
            frame.set_keyup_handler(keyup)

            frame.set_mouseclick_handler(click)

            if self.music_active:
                self.medias.get_sound('intro').play()

            self.loaded = True

        self.medias = Loader(frame, SCREEN_WIDTH, init)

        # Images by Kim Lathrop
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blend.png',
            'asteroid-1')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blue.png',
            'asteroid-2')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_brown.png',
            'asteroid-3')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_alpha.png',
            'asteroid_explosion')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_alpha2.png',
            'asteroid_collide_explosion')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/shot3.png',
            'bomb')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/debris2_blue.png',
            'debris')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/shot2.png',
            'missile')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/nebula_brown.png',
            'nebula')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/double_ship.png',
            'ship')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_orange.png',
            'ship_explosion')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/splash.png',
            'splash')

        # Sounds from http://www.sounddogs.com/ (not free)
        self.medias.add_sound(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/explosion.ogg',
            'asteroid_explosion')
        self.medias.add_sound(
            'http://rpg.hamsterrepublic.com/wiki-images/f/f4/StormMagic.ogg',
            'bomb_explode')
        self.medias.add_sound(
            'http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/extralife.ogg',
            'bomb_extra')
        self.medias.add_sound(
            'http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/eatedible.ogg',
            'collide')
        self.medias.add_sound(
            'http://rpg.hamsterrepublic.com/wiki-images/5/58/Death.ogg',
            'death')
        self.medias.add_sound(
            'http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/intromusic.ogg',
            'intro')
        self.medias.add_sound(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/soundtrack.ogg',
            'soundtrack')
        self.medias.add_sound(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/missile.ogg',
            'missile')
        self.medias.add_sound(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/thrust.ogg',
            'ship_thrust')

        self.medias.load()

        self.medias.wait_loaded()

    def rock_spawner(self):
        """
        If the maximum is not reached
        then spawns a rock (not too close to the ship).
        """
        if len(self.rocks) < 10:
            too_close = True

            def random_vel():
                """
                :return: int or float
                """
                return (min(2, (random.random() * (self.score / 10.0 + 0.1))) *
                        random.choice((-1, 1)))

            for _ in range(10):  # try 10 times
                rock_pos = (random.randrange(0, SCREEN_WIDTH),
                            random.randrange(0, SCREEN_HEIGHT))
                rock_vel = (random_vel(), random_vel())
                rock_ang_vel = random.choice(
                    (-1, 1)) * (random.random() * 0.05 + 0.01)

                rock = Asteroid(rock_pos, rock_vel, rock_ang_vel,
                                random.randint(1, 3))

                too_close = False
                for rock2 in self.rocks:
                    if rock2.collide(rock):
                        too_close = True

                        break

                too_close = (too_close
                             or (self.my_ship.distance(rock) <
                                 (self.my_ship.radius + rock.radius) * 3))
                if not too_close:
                    break

            if not too_close:
                self.rocks.append(rock)

    def start(self):
        """
        Start the game.
        """
        if self.music_active:
            self.medias.get_sound('intro').rewind()
            self.medias.get_sound('soundtrack').play()

        self.keydown_left = False
        self.keydown_right = False
        self.lives = 3
        self.nb_bombs = 0
        self.score = 0

        self.my_ship = Ship((SCREEN_WIDTH / 2.0, SCREEN_HEIGHT / 2.0), (0, 0),
                            -math.pi / 2, 'ship')

        self.explosions = []
        self.missiles = []
        self.rocks = []

        self.timer.start()
        self.rock_spawner()

        self.started = True

    def stop(self):
        """
        Stop the game.
        """
        self.timer.stop()

        self.nb_bombs = None

        self.missiles = []
        self.rocks = []

        self.started = False

        self.my_ship.stop()

        if self.music_active:
            self.medias.get_sound('soundtrack').rewind()
            self.medias.get_sound('intro').play()
    def load_medias(self):
        """
        Load images and sounds and waiting all is loaded,
        the set the general draw handler.
        """
        self.img_infos = {
            'asteroid-1':
            ImageInfo((45, 45), (90, 90), 40),
            'asteroid-2':
            ImageInfo((45, 45), (90, 90), 40),
            'asteroid-3':
            ImageInfo((45, 45), (90, 90), 38),
            'asteroid_explosion':
            ImageInfo((64, 64), (128, 128), 17, 24, True),
            'asteroid_collide_explosion':
            ImageInfo((64, 64), (128, 128), 17, 24, True),
            'bomb':
            ImageInfo((10, 10), (20, 20)),
            'debris':
            ImageInfo((320, 240), (640, 480)),
            'little-asteroid-1':
            ImageInfo((45, 45), (90, 90), 27, None, False, (60, 60)),
            'little-asteroid-2':
            ImageInfo((45, 45), (90, 90), 27, None, False, (60, 60)),
            'little-asteroid-3':
            ImageInfo((45, 45), (90, 90), 26, None, False, (60, 60)),
            'live_explosion':
            ImageInfo((64, 64), (128, 128), 17, 24, True),
            'missile':
            ImageInfo((5, 5), (10, 10), 3, 50),
            'nebula':
            ImageInfo((400, 300), (800, 600)),
            'ship':
            ImageInfo((45, 45), (90, 90), 35),
            'ship_explosion':
            ImageInfo((64, 64), (128, 128), 17, 24, True),
            'splash':
            ImageInfo((200, 150), (400, 300))
        }

        def init():
            """
            Init the game after medias loaded.
            """
            if SIMPLEGUICS2PYGAME:
                frame._set_canvas_background_image(
                    self.medias.get_image('nebula'))

            self.medias._images['live_explosion'] = \
                self.medias._images['ship_explosion']

            for i in range(1, 4):
                self.medias._images['little-asteroid-' + str(i)] = \
                    self.medias._images['asteroid-' + str(i)]

            self.medias._sounds['asteroid_collide_explosion'] = \
                self.medias._sounds['asteroid_explosion']

            self.medias.get_sound('missile').set_volume(.5)

            self.my_ship = Ship((SCREEN_WIDTH / 2.0, SCREEN_HEIGHT / 2.0),
                                (0, 0), -math.pi / 2, 'ship')

            frame.set_draw_handler(self.draw_and_update)

            frame.set_keydown_handler(keydown)
            frame.set_keyup_handler(keyup)

            frame.set_mouseclick_handler(click)

            if self.music_active:
                self.medias.get_sound('intro').play()

            self.loaded = True

        self.medias = Loader(frame, SCREEN_WIDTH, init)

        # Images by Kim Lathrop
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blend.png',
            'asteroid-1')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blue.png',
            'asteroid-2')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_brown.png',
            'asteroid-3')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_alpha.png',
            'asteroid_explosion')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_alpha2.png',
            'asteroid_collide_explosion')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/shot3.png',
            'bomb')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/debris2_blue.png',
            'debris')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/shot2.png',
            'missile')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/nebula_brown.png',
            'nebula')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/double_ship.png',
            'ship')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_orange.png',
            'ship_explosion')
        self.medias.add_image(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/splash.png',
            'splash')

        # Sounds from http://www.sounddogs.com/ (not free)
        self.medias.add_sound(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/explosion.ogg',
            'asteroid_explosion')
        self.medias.add_sound(
            'http://rpg.hamsterrepublic.com/wiki-images/f/f4/StormMagic.ogg',
            'bomb_explode')
        self.medias.add_sound(
            'http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/extralife.ogg',
            'bomb_extra')
        self.medias.add_sound(
            'http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/eatedible.ogg',
            'collide')
        self.medias.add_sound(
            'http://rpg.hamsterrepublic.com/wiki-images/5/58/Death.ogg',
            'death')
        self.medias.add_sound(
            'http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/intromusic.ogg',
            'intro')
        self.medias.add_sound(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/soundtrack.ogg',
            'soundtrack')
        self.medias.add_sound(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/missile.ogg',
            'missile')
        self.medias.add_sound(
            'http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/thrust.ogg',
            'ship_thrust')

        self.medias.load()

        self.medias.wait_loaded()
    Init after image loaded.
    """
    if not SIMPLEGUICS2PYGAME:
        global logo

        logo = loader.get_image('logo')

    frame.set_draw_handler(draw)

    if SIMPLEGUICS2PYGAME:
        from sys import argv

        if len(argv) == 2:
            frame._save_canvas_and_stop(argv[1])

loader = Loader(frame, WIDTH, init)
loader.add_image('http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/double_ship.png',
                 'double_ship')
if not SIMPLEGUICS2PYGAME:
    loader.add_image('http://simpleguics2pygame.readthedocs.org/en/latest/_images/SimpleGUICS2Pygame_64x64_t.png',
                     'logo')
loader.load()

loader.wait_loaded()

if SIMPLEGUICS2PYGAME:
    logo = simplegui._load_local_image(
        '../_img/SimpleGUICS2Pygame_64x64_t.png')

frame.start()
if SIMPLEGUICS2PYGAME and frame._print_stats_cache:
    # Set the real draw handler
    frame.set_draw_handler(draw)


def quit_prog():
    """
    Stop sounds and frame
    """
    loader.pause_sounds()  # stop all sounds
    frame.stop()
    if SIMPLEGUICS2PYGAME and frame._print_stats_cache:
        loader.print_stats_cache()


loader = Loader(
    frame,  # the frame
    WIDTH,  # the width frame
    init)  # the function to call after loading

# Specified images to load with its URL and give them a name.
loader.add_image(
    'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blend.png',
    'asteroid')
loader.add_image(
    'http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/double_ship.png',
    'double_ship')
loader.add_image('xxx', 'incorrect url')

# Specified sounds to load with its URL and give them a name.
loader.add_sound(
    'http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/explosion.ogg',
    'explosion')