Exemplo n.º 1
0
class SpriteBase(pygame.sprite.Sprite):
    def __init__(self, *args, **kwargs):
        super(SpriteBase, self).__init__(*args, **kwargs)
        self.image = ImageObject('ship.png')
        self.rect = self.image.rect

    def draw_on_surface(self, surface, game_board):
        self.image.draw_on_surface(surface)
        self.rect = self.image.rect
Exemplo n.º 2
0
class StartupBoard(BoardBase):
    switch_board = False
    labels = []

    def __init__(self, *args, **kwargs):
        self.background = ImageObject('background.png')

    def process_draw_on_surface(self, surface):
        self.background.draw_on_surface(surface)

        if self.labels == []:
            label = LabelObject('PYWANDER', 37)
            label.rect.left = 90
            label.rect.top = 90
            self.labels.append(label)

            label = LabelObject('IS A GAME...', 15)
            label.rect.left = 329
            label.rect.top = 109
            self.labels.append(label)

            label = LabelObject('WHERE YOU MUST SAVE THE WORLD IN', 15)
            label.rect.left = 60
            label.rect.top = 170
            self.labels.append(label)

            label = LabelObject('LESS THAN...', 25)
            label.rect.left = 410
            label.rect.top = 170
            self.labels.append(label)

            label = LabelObject('9 TIMES', 121)
            label.rect.left = 31
            label.rect.top = 184
            self.labels.append(label)

        for label in self.labels:
            label.draw_on_surface(surface)

        buffer = pygame.image.tostring(surface, 'RGB')
        self.buffer = buffer
        self.buffer_size = surface.get_size()

    def process_inputs(self, events):
        for event in events:
            if event.type == KEYDOWN:
                self.switch_board = True

    def is_time_to_switch_board(self):
        return self.switch_board

    def get_next_board(self):
        return SwitchBoard(self.buffer, self.buffer_size, HowToBoard())
Exemplo n.º 3
0
class SwitchBoard(BoardBase):
    switch_board = False
    next_board = None
    image = None
    is_completed = False
    transparency = 0.0
    transparency_speed = 6.54
    go_to_dark = True

    def __init__(self, buffer, buffer_size, board_after):
        self.image = pygame.image.frombuffer(buffer, buffer_size, 'RGB')
        self.next_board = board_after
        self.background = ImageObject('background.png')

    def process_draw_on_surface(self, surface):
        if self.go_to_dark:
            surface.blit(self.image, (0, 0))

            if self.transparency < 255 - self.transparency_speed:
                self.transparency += self.transparency_speed
            else:
                self.go_to_dark = False
            transparency_rgb_with_alpha = (160,
                                           160,
                                           160,
                                           self.transparency)
            transparency = pygame.surface.Surface((640, 480)).convert_alpha()
            transparency.fill(transparency_rgb_with_alpha)
            surface.blit(transparency, (0, 0))
        else:
            self.background.draw_on_surface(surface)

            if self.transparency > 0 + self.transparency_speed:
                self.transparency -= self.transparency_speed
            else:
                self.switch_board = True
            transparency_rgb_with_alpha = (160,
                                           160,
                                           160,
                                           self.transparency)
            transparency = pygame.surface.Surface((640, 480)).convert_alpha()
            transparency.fill(transparency_rgb_with_alpha)
            surface.blit(transparency, (0, 0))

    def process_inputs(self, events):
        pass

    def is_time_to_switch_board(self):
        return self.switch_board

    def get_next_board(self):
        return self.next_board
Exemplo n.º 4
0
    def __init__(self, level=1):
        self.level = level

        self.background = ImageObject('background.png')

        self.ship = ShipSprite()
        self.bullets_group = pygame.sprite.Group()
        self.enemy_group = pygame.sprite.Group()
        self.inactive_group = pygame.sprite.Group()

        self.level_file = open(
            os.path.join('data', 'levels', 'level_%d.txt' % self.level))
        self.level_file.readline(
        )  # First line indicates just limit of file width
Exemplo n.º 5
0
    def draw_on_surface(self, surface, game_board):
        if not self.start_explosion:
            time_before = self.time
            self.time = pygame.time.get_ticks()
            elapsed = self.time - time_before
            self.x_position -= int(elapsed * self.speed)
            self.image.rect.left = int(self.x_position)

            if random.randint(1, 6) == 6:
                time_now = pygame.time.get_ticks()
                if self.last_fire_time + self.fire_time_delay < time_now:
                    bullet = BulletSprite(False)
                    bullet.image.rect.left = self.image.rect.left + self.image.rect.width / 2 - 4
                    bullet.image.rect.top = self.image.rect.top + self.image.rect.height / 2 - 9
                    bullet.rect = bullet.image.rect
                    game_board.enemy_group.add(bullet)
                    self.last_fire_time = time_now

            super(EnemySprite, self).draw_on_surface(surface, game_board)
        else:
            if self.explosion_frame != 15:
                tmp_rect = self.image.rect
                self.image = ImageObject('explosion-%d.png' %
                                         self.explosion_frame)
                self.image.rect = tmp_rect
                self.explosion_frame += 1
                super(EnemySprite, self).draw_on_surface(surface, game_board)
Exemplo n.º 6
0
 def __init__(self, is_ship_bullet=True, *args, **kwargs):
     super(BulletSprite, self).__init__(*args, **kwargs)
     self.image = ImageObject('ship_bullet.png')
     self.is_ship_bullet = is_ship_bullet
     if not self.is_ship_bullet:
         self.image.surface_to_draw = pygame.transform.flip(
             self.image.surface_to_draw, True, False)
     self.time = pygame.time.get_ticks()
Exemplo n.º 7
0
class WonBoard(BoardBase):
    switch_board = False
    labels = []
    level = None

    def __init__(self, level):
        self.level = level
        self.background = ImageObject('background.png')

    def process_draw_on_surface(self, surface):
        self.background.draw_on_surface(surface)

        if self.labels == []:
            label = LabelObject('CONGRATS', 81)
            label.rect.left = 61
            label.rect.top = 114
            self.labels.append(label)

            level_finished = self.level - 1
            label = LabelObject('YOU HAVE JUST FINISHED LEVEL %d,' % level_finished, 27)
            label.rect.left = 61
            label.rect.top = 204
            self.labels.append(label)

            label = LabelObject('PREPARE FOR NEXT LEVEL!', 27)
            label.rect.left = 61
            label.rect.top = 244
            self.labels.append(label)

        for label in self.labels:
            label.draw_on_surface(surface)

    def process_inputs(self, events):
        for event in events:
            if event.type == KEYDOWN:
                self.switch_board = True

    def is_time_to_switch_board(self):
        return self.switch_board

    def get_next_board(self):
        return GameBoard(self.level)
Exemplo n.º 8
0
    def __init__(self, level=1):
        self.level = level

        self.background = ImageObject('background.png')

        self.ship = ShipSprite()
        self.bullets_group = pygame.sprite.Group()
        self.enemy_group = pygame.sprite.Group()
        self.inactive_group = pygame.sprite.Group()

        self.level_file = open(os.path.join('data', 'levels', 'level_%d.txt' % self.level))
        self.level_file.readline()  # First line indicates just limit of file width
Exemplo n.º 9
0
class LoseBoard(BoardBase):
    switch_board = False
    labels = []

    def __init__(self, *args, **kwargs):
        self.background = ImageObject('background.png')

    def process_draw_on_surface(self, surface):
        self.background.draw_on_surface(surface)

        if self.labels == []:
            label = LabelObject('SORRY', 121)
            label.rect.left = 71
            label.rect.top = 104
            self.labels.append(label)

            label = LabelObject('BUT YOU LOSE. JUST DON''T CRY,', 27)
            label.rect.left = 71
            label.rect.top = 224
            self.labels.append(label)

            label = LabelObject('YOU CAN PLAY AGAIN! :)', 27)
            label.rect.left = 71
            label.rect.top = 264
            self.labels.append(label)

        for label in self.labels:
            label.draw_on_surface(surface)

    def process_inputs(self, events):
        for event in events:
            if event.type == KEYDOWN:
                self.switch_board = True

    def is_time_to_switch_board(self):
        return self.switch_board

    def get_next_board(self):
        return None
Exemplo n.º 10
0
class LoseBoard(BoardBase):
    switch_board = False
    labels = []

    def __init__(self, *args, **kwargs):
        self.background = ImageObject('background.png')

    def process_draw_on_surface(self, surface):
        self.background.draw_on_surface(surface)

        if self.labels == []:
            label = LabelObject('SORRY', 121)
            label.rect.left = 71
            label.rect.top = 104
            self.labels.append(label)

            label = LabelObject('BUT YOU LOSE. JUST DON' 'T CRY,', 27)
            label.rect.left = 71
            label.rect.top = 224
            self.labels.append(label)

            label = LabelObject('YOU CAN PLAY AGAIN! :)', 27)
            label.rect.left = 71
            label.rect.top = 264
            self.labels.append(label)

        for label in self.labels:
            label.draw_on_surface(surface)

    def process_inputs(self, events):
        for event in events:
            if event.type == KEYDOWN:
                self.switch_board = True

    def is_time_to_switch_board(self):
        return self.switch_board

    def get_next_board(self):
        return None
Exemplo n.º 11
0
 def __init__(self, *args, **kwargs):
     super(ShipSprite, self).__init__(*args, **kwargs)
     self.image = ImageObject('ship.png')
Exemplo n.º 12
0
 def __init__(self, *args, **kwargs):
     super(BossSprite, self).__init__(*args, **kwargs)
     self.image = ImageObject('boss.png')
     self.last_fire_time = pygame.time.get_ticks()
Exemplo n.º 13
0
 def __init__(self, *args, **kwargs):
     self.background = ImageObject('background.png')
Exemplo n.º 14
0
 def __init__(self, buffer, buffer_size, board_after):
     self.image = pygame.image.frombuffer(buffer, buffer_size, 'RGB')
     self.next_board = board_after
     self.background = ImageObject('background.png')
Exemplo n.º 15
0
    def process_draw_on_surface(self, surface):
        self.background.draw_on_surface(surface)

        if self.objects == []:
            label = LabelObject('HOW TO PLAY?', 30)
            label.rect.left = 190
            label.rect.top = 25
            self.objects.append(label)

            label = LabelObject('Move your ship by pressing up and down.', 18)
            label.rect.left = 120
            label.rect.top = 120
            self.objects.append(label)

            label = LabelObject('To shoot press spacebar.', 18)
            label.rect.left = 120
            label.rect.top = 145
            self.objects.append(label)

            image = ImageObject('ship.png')
            image.rect.left = 45
            image.rect.top = 120
            self.objects.append(image)

            image = ImageObject('arrows.png')
            image.rect.left = 49
            image.rect.top = 176
            self.objects.append(image)

            image = ImageObject('arrows.png')
            image.rect.left = 49
            image.rect.top = 75
            image.surface_to_draw = pygame.transform.flip(
                image.surface_to_draw, False, True)
            self.objects.append(image)

            label = LabelObject('But watch out for', 18)
            label.rect.left = 120
            label.rect.top = 240
            self.objects.append(label)

            label = LabelObject('THE BOSS!', 28)
            label.rect.left = 350
            label.rect.top = 235
            self.objects.append(label)

            label = LabelObject('You must kill him before he shows', 18)
            label.rect.left = 200
            label.rect.top = 340
            self.objects.append(label)

            label = LabelObject('9 TIMES', 68)
            label.rect.left = 240
            label.rect.top = 370
            self.objects.append(label)

            image = ImageObject('boss.png')
            image.rect.left = 39
            image.rect.top = 300
            self.objects.append(image)

            self.objects.append(image)

        for element in self.objects:
            element.draw_on_surface(surface)

        buffer = pygame.image.tostring(surface, 'RGB')
        self.buffer = buffer
        self.buffer_size = surface.get_size()
Exemplo n.º 16
0
class GameBoard(BoardBase):
    status = None
    score = 0
    life = 100
    boss_life = 100

    bullets = []

    background = None
    background_x = 0
    background_speed = 0.07
    background_time = 0
    background_width = 3161

    ship = None
    bullets_group = None
    enemy_group = None
    inactive_group = None

    level = 1
    level_file = None
    last_file_read = 0
    level_speed = 1000

    attempts_left = 9

    def __init__(self, level=1):
        self.level = level

        self.background = ImageObject('background.png')

        self.ship = ShipSprite()
        self.bullets_group = pygame.sprite.Group()
        self.enemy_group = pygame.sprite.Group()
        self.inactive_group = pygame.sprite.Group()

        self.level_file = open(os.path.join('data', 'levels', 'level_%d.txt' % self.level))
        self.level_file.readline()  # First line indicates just limit of file width

    def process_draw_on_surface(self, surface):
        time_before = self.background_time
        if self.background_time != 0:
            self.background_time = pygame.time.get_ticks()
            elapsed = self.background_time - time_before
        else:
            self.background_time = pygame.time.get_ticks()
            elapsed = 0
        self.background_x -= int(elapsed * self.background_speed)
        if self.background_x < -self.background_width:
            self.background_x += self.background_width
        for i in range(3):
            self.background.rect.left = int(self.background_x) + (self.background_width * (i - 1))
            self.background.draw_on_surface(surface, self)

        score_label = LabelObject('Score: %d' % self.score, 14)
        score_label.change_realign('top-right', right=15, top=15)
        score_label.draw_on_surface(surface, self)

        life_label = LabelObject('Life: %d' % self.life, 14)
        life_label.change_realign('top-left', left=15, top=15)
        life_label.draw_on_surface(surface, self)

        life_label = LabelObject('Attempts left: %d' % self.attempts_left, 14)
        life_label.change_realign('top-center', top=15)
        life_label.draw_on_surface(surface, self)

        for bullet in self.bullets_group.sprites():
            if bullet.image.rect.left >= 640:
                self.bullets_group.remove(bullet)
            else:
                bullet.draw_on_surface(surface, self)

        self.ship.draw_on_surface(surface, self)

        for enemy in self.enemy_group.sprites():
            if isinstance(enemy, EnemySprite):
                if enemy.is_completed():
                    self.enemy_group.remove(enemy)
            enemy.draw_on_surface(surface, self)

        for inactive in self.inactive_group.sprites():
            if isinstance(inactive, EnemySprite):
                if inactive.is_completed():
                    self.inactive_group.remove(inactive)
                    continue
            inactive.draw_on_surface(surface, self)

        for hit in pygame.sprite.groupcollide(self.enemy_group, self.bullets_group, 0, 1):
            if isinstance(hit, AsteroidSprite):
                self.score += 9

            if isinstance(hit, BulletSprite):
                hit.kill()

            if isinstance(hit, BossSprite):
                self.score += 13
                hit.hit()
                self.boss_life = hit.life
                if hit.life <= 0:
                    self.status = PLAYER_WON
                    return False

            if isinstance(hit, EnemySprite):
                self.score += 7
                hit.kill()
                hit.show_explosion()
                sound = SoundObject()
                sound.play('boom', 0)
                self.inactive_group.add(hit)

        hit = pygame.sprite.spritecollideany(self.ship, self.enemy_group)
        if hit:
            fatal = isinstance(hit, AsteroidSprite) or isinstance(hit, BossSprite)
            if not fatal:
                hit.kill()

                if isinstance(hit, EnemySprite):
                    hit.show_explosion()
                    sound = SoundObject()
                    sound.play('boom', 0)

                self.life -= 25
            else:
                self.status = PLAYER_LOSE
        else:
            self.read_level_info()

        if self.attempts_left == 0 or self.life == 0:
            self.status = PLAYER_LOSE

        buffer = pygame.image.tostring(surface, 'RGB')
        self.buffer = buffer
        self.buffer_size = surface.get_size()

    def process_inputs(self, events):
        key = pygame.key.get_pressed()
        if key[K_DOWN]:
            self.ship.move_ship_down()
        if key[K_UP]:
            self.ship.move_ship_up()
        if key[K_SPACE]:
            self.ship.fire_bullet(self.bullets_group)
        if key[K_LEFT]:
            self.ship.move_ship_left()
        if key[K_RIGHT]:
            self.ship.move_ship_right()

    def is_time_to_switch_board(self):
        return self.status is not None

    def get_next_board(self):
        from pywander.boards.switch import SwitchBoard
        from pywander.boards.won import WonBoard
        from pywander.boards.lose import LoseBoard

        if self.status == PLAYER_WON:
            return SwitchBoard(self.buffer, self.buffer_size, WonBoard(self.level + 1))
        else:
            return SwitchBoard(self.buffer, self.buffer_size, LoseBoard())

    def add_enemy(self, key):
        enemy = EnemySprite()
        enemy.image.rect.left = 680
        enemy.image.rect.top = key * 30
        self.enemy_group.add(enemy)

    def add_asteroid(self, key):
        enemy = AsteroidSprite()
        enemy.image.rect.left = 680
        enemy.image.rect.top = key * 30
        self.enemy_group.add(enemy)

    def add_boss(self, key):
        enemy = BossSprite()
        enemy.life = self.boss_life
        enemy.image.rect.left = 645
        enemy.image.rect.top = key * 30
        self.enemy_group.add(enemy)

    def read_level_info(self):
        time_now = pygame.time.get_ticks()
        if self.last_file_read + self.level_speed < time_now:
            line = self.level_file.readline()
            key = 0
            for obj in line:
                if obj == '^':
                    self.add_enemy(key)
                if obj == 'O':
                    self.add_asteroid(key)
                if obj == '@':
                    self.add_boss(key)
                key += 1
            self.last_file_read = time_now
Exemplo n.º 17
0
class HowToBoard(BoardBase):
    switch_board = False
    objects = []

    def __init__(self, *args, **kwargs):
        self.background = ImageObject('background.png')

    def process_draw_on_surface(self, surface):
        self.background.draw_on_surface(surface)

        if self.objects == []:
            label = LabelObject('HOW TO PLAY?', 30)
            label.rect.left = 190
            label.rect.top = 25
            self.objects.append(label)

            label = LabelObject('Move your ship by pressing up and down.', 18)
            label.rect.left = 120
            label.rect.top = 120
            self.objects.append(label)

            label = LabelObject('To shoot press spacebar.', 18)
            label.rect.left = 120
            label.rect.top = 145
            self.objects.append(label)

            image = ImageObject('ship.png')
            image.rect.left = 45
            image.rect.top = 120
            self.objects.append(image)

            image = ImageObject('arrows.png')
            image.rect.left = 49
            image.rect.top = 176
            self.objects.append(image)

            image = ImageObject('arrows.png')
            image.rect.left = 49
            image.rect.top = 75
            image.surface_to_draw = pygame.transform.flip(
                image.surface_to_draw, False, True)
            self.objects.append(image)

            label = LabelObject('But watch out for', 18)
            label.rect.left = 120
            label.rect.top = 240
            self.objects.append(label)

            label = LabelObject('THE BOSS!', 28)
            label.rect.left = 350
            label.rect.top = 235
            self.objects.append(label)

            label = LabelObject('You must kill him before he shows', 18)
            label.rect.left = 200
            label.rect.top = 340
            self.objects.append(label)

            label = LabelObject('9 TIMES', 68)
            label.rect.left = 240
            label.rect.top = 370
            self.objects.append(label)

            image = ImageObject('boss.png')
            image.rect.left = 39
            image.rect.top = 300
            self.objects.append(image)

            self.objects.append(image)

        for element in self.objects:
            element.draw_on_surface(surface)

        buffer = pygame.image.tostring(surface, 'RGB')
        self.buffer = buffer
        self.buffer_size = surface.get_size()

    def process_inputs(self, events):
        for event in events:
            if event.type == KEYDOWN:
                self.switch_board = True

    def is_time_to_switch_board(self):
        return self.switch_board

    def get_next_board(self):
        return SwitchBoard(self.buffer, self.buffer_size, GameBoard())
Exemplo n.º 18
0
    def process_draw_on_surface(self, surface):
        self.background.draw_on_surface(surface)

        if self.objects == []:
            label = LabelObject('HOW TO PLAY?', 30)
            label.rect.left = 190
            label.rect.top = 25
            self.objects.append(label)

            label = LabelObject('Move your ship by pressing up and down.', 18)
            label.rect.left = 120
            label.rect.top = 120
            self.objects.append(label)

            label = LabelObject('To shoot press spacebar.', 18)
            label.rect.left = 120
            label.rect.top = 145
            self.objects.append(label)

            image = ImageObject('ship.png')
            image.rect.left = 45
            image.rect.top = 120
            self.objects.append(image)

            image = ImageObject('arrows.png')
            image.rect.left = 49
            image.rect.top = 176
            self.objects.append(image)

            image = ImageObject('arrows.png')
            image.rect.left = 49
            image.rect.top = 75
            image.surface_to_draw = pygame.transform.flip(image.surface_to_draw, False, True)
            self.objects.append(image)

            label = LabelObject('But watch out for', 18)
            label.rect.left = 120
            label.rect.top = 240
            self.objects.append(label)

            label = LabelObject('THE BOSS!', 28)
            label.rect.left = 350
            label.rect.top = 235
            self.objects.append(label)

            label = LabelObject('You must kill him before he shows', 18)
            label.rect.left = 200
            label.rect.top = 340
            self.objects.append(label)

            label = LabelObject('9 TIMES', 68)
            label.rect.left = 240
            label.rect.top = 370
            self.objects.append(label)

            image = ImageObject('boss.png')
            image.rect.left = 39
            image.rect.top = 300
            self.objects.append(image)

            self.objects.append(image)

        for element in self.objects:
            element.draw_on_surface(surface)

        buffer = pygame.image.tostring(surface, 'RGB')
        self.buffer = buffer
        self.buffer_size = surface.get_size()
Exemplo n.º 19
0
class HowToBoard(BoardBase):
    switch_board = False
    objects = []

    def __init__(self, *args, **kwargs):
        self.background = ImageObject('background.png')

    def process_draw_on_surface(self, surface):
        self.background.draw_on_surface(surface)

        if self.objects == []:
            label = LabelObject('HOW TO PLAY?', 30)
            label.rect.left = 190
            label.rect.top = 25
            self.objects.append(label)

            label = LabelObject('Move your ship by pressing up and down.', 18)
            label.rect.left = 120
            label.rect.top = 120
            self.objects.append(label)

            label = LabelObject('To shoot press spacebar.', 18)
            label.rect.left = 120
            label.rect.top = 145
            self.objects.append(label)

            image = ImageObject('ship.png')
            image.rect.left = 45
            image.rect.top = 120
            self.objects.append(image)

            image = ImageObject('arrows.png')
            image.rect.left = 49
            image.rect.top = 176
            self.objects.append(image)

            image = ImageObject('arrows.png')
            image.rect.left = 49
            image.rect.top = 75
            image.surface_to_draw = pygame.transform.flip(image.surface_to_draw, False, True)
            self.objects.append(image)

            label = LabelObject('But watch out for', 18)
            label.rect.left = 120
            label.rect.top = 240
            self.objects.append(label)

            label = LabelObject('THE BOSS!', 28)
            label.rect.left = 350
            label.rect.top = 235
            self.objects.append(label)

            label = LabelObject('You must kill him before he shows', 18)
            label.rect.left = 200
            label.rect.top = 340
            self.objects.append(label)

            label = LabelObject('9 TIMES', 68)
            label.rect.left = 240
            label.rect.top = 370
            self.objects.append(label)

            image = ImageObject('boss.png')
            image.rect.left = 39
            image.rect.top = 300
            self.objects.append(image)

            self.objects.append(image)

        for element in self.objects:
            element.draw_on_surface(surface)

        buffer = pygame.image.tostring(surface, 'RGB')
        self.buffer = buffer
        self.buffer_size = surface.get_size()

    def process_inputs(self, events):
        for event in events:
            if event.type == KEYDOWN:
                self.switch_board = True

    def is_time_to_switch_board(self):
        return self.switch_board

    def get_next_board(self):
        return SwitchBoard(self.buffer, self.buffer_size, GameBoard())
Exemplo n.º 20
0
 def __init__(self, *args, **kwargs):
     super(SpriteBase, self).__init__(*args, **kwargs)
     self.image = ImageObject('ship.png')
     self.rect = self.image.rect
Exemplo n.º 21
0
 def __init__(self, *args, **kwargs):
     super(AsteroidSprite, self).__init__(*args, **kwargs)
     self.image = ImageObject('asteroid_1.png')
     self.time = pygame.time.get_ticks()
Exemplo n.º 22
0
 def __init__(self, level):
     self.level = level
     self.background = ImageObject('background.png')
Exemplo n.º 23
0
 def __init__(self, *args, **kwargs):
     super(EnemySprite, self).__init__(*args, **kwargs)
     self.image = ImageObject('enemy_ship.png')
     self.time = pygame.time.get_ticks()
Exemplo n.º 24
0
class GameBoard(BoardBase):
    status = None
    score = 0
    life = 100
    boss_life = 100

    bullets = []

    background = None
    background_x = 0
    background_speed = 0.07
    background_time = 0
    background_width = 3161

    ship = None
    bullets_group = None
    enemy_group = None
    inactive_group = None

    level = 1
    level_file = None
    last_file_read = 0
    level_speed = 1000

    attempts_left = 9

    def __init__(self, level=1):
        self.level = level

        self.background = ImageObject('background.png')

        self.ship = ShipSprite()
        self.bullets_group = pygame.sprite.Group()
        self.enemy_group = pygame.sprite.Group()
        self.inactive_group = pygame.sprite.Group()

        self.level_file = open(
            os.path.join('data', 'levels', 'level_%d.txt' % self.level))
        self.level_file.readline(
        )  # First line indicates just limit of file width

    def process_draw_on_surface(self, surface):
        time_before = self.background_time
        if self.background_time != 0:
            self.background_time = pygame.time.get_ticks()
            elapsed = self.background_time - time_before
        else:
            self.background_time = pygame.time.get_ticks()
            elapsed = 0
        self.background_x -= int(elapsed * self.background_speed)
        if self.background_x < -self.background_width:
            self.background_x += self.background_width
        for i in range(3):
            self.background.rect.left = int(
                self.background_x) + (self.background_width * (i - 1))
            self.background.draw_on_surface(surface, self)

        score_label = LabelObject('Score: %d' % self.score, 14)
        score_label.change_realign('top-right', right=15, top=15)
        score_label.draw_on_surface(surface, self)

        life_label = LabelObject('Life: %d' % self.life, 14)
        life_label.change_realign('top-left', left=15, top=15)
        life_label.draw_on_surface(surface, self)

        life_label = LabelObject('Attempts left: %d' % self.attempts_left, 14)
        life_label.change_realign('top-center', top=15)
        life_label.draw_on_surface(surface, self)

        for bullet in self.bullets_group.sprites():
            if bullet.image.rect.left >= 640:
                self.bullets_group.remove(bullet)
            else:
                bullet.draw_on_surface(surface, self)

        self.ship.draw_on_surface(surface, self)

        for enemy in self.enemy_group.sprites():
            if isinstance(enemy, EnemySprite):
                if enemy.is_completed():
                    self.enemy_group.remove(enemy)
            enemy.draw_on_surface(surface, self)

        for inactive in self.inactive_group.sprites():
            if isinstance(inactive, EnemySprite):
                if inactive.is_completed():
                    self.inactive_group.remove(inactive)
                    continue
            inactive.draw_on_surface(surface, self)

        for hit in pygame.sprite.groupcollide(self.enemy_group,
                                              self.bullets_group, 0, 1):
            if isinstance(hit, AsteroidSprite):
                self.score += 9

            if isinstance(hit, BulletSprite):
                hit.kill()

            if isinstance(hit, BossSprite):
                self.score += 13
                hit.hit()
                self.boss_life = hit.life
                if hit.life <= 0:
                    self.status = PLAYER_WON
                    return False

            if isinstance(hit, EnemySprite):
                self.score += 7
                hit.kill()
                hit.show_explosion()
                sound = SoundObject()
                sound.play('boom', 0)
                self.inactive_group.add(hit)

        hit = pygame.sprite.spritecollideany(self.ship, self.enemy_group)
        if hit:
            fatal = isinstance(hit, AsteroidSprite) or isinstance(
                hit, BossSprite)
            if not fatal:
                hit.kill()

                if isinstance(hit, EnemySprite):
                    hit.show_explosion()
                    sound = SoundObject()
                    sound.play('boom', 0)

                self.life -= 25
            else:
                self.status = PLAYER_LOSE
        else:
            self.read_level_info()

        if self.attempts_left == 0 or self.life == 0:
            self.status = PLAYER_LOSE

        buffer = pygame.image.tostring(surface, 'RGB')
        self.buffer = buffer
        self.buffer_size = surface.get_size()

    def process_inputs(self, events):
        key = pygame.key.get_pressed()
        if key[K_DOWN]:
            self.ship.move_ship_down()
        if key[K_UP]:
            self.ship.move_ship_up()
        if key[K_SPACE]:
            self.ship.fire_bullet(self.bullets_group)
        if key[K_LEFT]:
            self.ship.move_ship_left()
        if key[K_RIGHT]:
            self.ship.move_ship_right()

    def is_time_to_switch_board(self):
        return self.status is not None

    def get_next_board(self):
        from pywander.boards.switch import SwitchBoard
        from pywander.boards.won import WonBoard
        from pywander.boards.lose import LoseBoard

        if self.status == PLAYER_WON:
            return SwitchBoard(self.buffer, self.buffer_size,
                               WonBoard(self.level + 1))
        else:
            return SwitchBoard(self.buffer, self.buffer_size, LoseBoard())

    def add_enemy(self, key):
        enemy = EnemySprite()
        enemy.image.rect.left = 680
        enemy.image.rect.top = key * 30
        self.enemy_group.add(enemy)

    def add_asteroid(self, key):
        enemy = AsteroidSprite()
        enemy.image.rect.left = 680
        enemy.image.rect.top = key * 30
        self.enemy_group.add(enemy)

    def add_boss(self, key):
        enemy = BossSprite()
        enemy.life = self.boss_life
        enemy.image.rect.left = 645
        enemy.image.rect.top = key * 30
        self.enemy_group.add(enemy)

    def read_level_info(self):
        time_now = pygame.time.get_ticks()
        if self.last_file_read + self.level_speed < time_now:
            line = self.level_file.readline()
            key = 0
            for obj in line:
                if obj == '^':
                    self.add_enemy(key)
                if obj == 'O':
                    self.add_asteroid(key)
                if obj == '@':
                    self.add_boss(key)
                key += 1
            self.last_file_read = time_now