Example #1
0
class SpaceGame(GameApp):
    def init_game(self):
        self.ship = Ship(self, CANVAS_WIDTH // 2, CANVAS_HEIGHT // 2)

        self.level = StatusWithText(self, 100, 580, 'Level: %d', 1)
        self.level_wait = 0

        # StatusWithText encap
        self.score = StatusWithText(self, 100, 20, 'Score: %d', 0)
        self.score_wait = 0
        
        self.bomb_power = StatusWithText(self, 700, 20, 'Power: %d%%', BOMB_FULL_POWER)
        self.bomb_wait = 0

        self.elements.append(self.ship)

        self.enemies = []
        self.bullets = []

        # strategy pattern
        self.enemy_creation_strategies = [
            (0.2, StarEnemyGenerationStrategy()),
            (1.0, EdgeEnemyGenerationStrategy())
        ]

        # CoR pattern
        self.init_key_handlers()

        # canvas configure
        self.canvas.configure(bg="darkgray")
        for item in [self.level, self.score, self.bomb_power]:
            self.canvas.itemconfigure(item.label_text.canvas_object_id, fill="white")

    def add_enemy(self, enemy):
        self.enemies.append(enemy)

    def add_bullet(self, bullet):
        self.bullets.append(bullet)

    def bullet_count(self):
        return len(self.bullets)

    ### START: bomb improvement ###
    def bomb(self):
        if self.bomb_power.value == BOMB_FULL_POWER:
            self.bomb_power.value = 0

            self.create_bomb()
            self.process_bomb_destruction()

    def create_bomb(self):
        self.bomb_canvas_id = self.canvas.create_oval(
                self.ship.x - BOMB_RADIUS, 
                self.ship.y - BOMB_RADIUS,
                self.ship.x + BOMB_RADIUS, 
                self.ship.y + BOMB_RADIUS
                )
        self.after(200, lambda: self.canvas.delete(self.bomb_canvas_id))

    def process_bomb_destruction(self):
        for e in self.enemies:
                if self.ship.distance_to(e) <= BOMB_RADIUS:
                    e.to_be_deleted = True
    ### END: bomb improvement ###

    def update_score(self):
        self.score_wait += 1
        if self.score_wait >= SCORE_WAIT:
            self.score.value += 1
            self.score_wait = 0

    def update_bomb_power(self):
        self.bomb_wait += 1
        if (self.bomb_wait >= BOMB_WAIT) and (self.bomb_power.value != BOMB_FULL_POWER):
            self.bomb_power.value += 1
            self.bomb_wait = 0

    def update_level(self):
        self.level_wait += 1
        if self.level_wait >= LEVEL_WAIT:
            self.level.value += 1
            self.level_wait = 0

            # add more enemies
            if self.level.value % 20 == 0:
                self.enemy_creation_strategies.append((0.2, StarEnemyGenerationStrategy()))
                self.enemy_creation_strategies.append((1.0, EdgeEnemyGenerationStrategy()))

    def create_enemies(self):
        p = random()

        for prob, strategy in self.enemy_creation_strategies:
            if p < prob:
                enemies = strategy.generate(self, self.ship)
                break

        for e in enemies:
            self.add_enemy(e)

    def pre_update(self):
        # raise more enemies creation chance by level
        if random() < 0.05 * self.level.value:
            self.create_enemies()

    def process_bullet_enemy_collisions(self):
        for b in self.bullets:
            for e in self.enemies:
                if b.is_colliding_with_enemy(e):
                    b.to_be_deleted = True
                    e.to_be_deleted = True

    def process_ship_enemy_collision(self):
        for e in self.enemies:
            if self.ship.is_colliding_with_enemy(e):
                self.stop_animation()

    # ship edge collision
    def process_ship_edge_collision(self):
        w, h = CANVAS_WIDTH, CANVAS_HEIGHT
        x, y = self.ship.x, self.ship.y
        if not (0 <= x <= w and 0 <= y <= h):
            self.stop_animation()

    def process_collisions(self):
        self.process_bullet_enemy_collisions()
        self.process_ship_enemy_collision()
        self.process_ship_edge_collision()

    def update_and_filter_deleted(self, elements):
        new_list = []
        for e in elements:
            e.update()
            e.render()
            if e.to_be_deleted:
                e.delete()
            else:
                new_list.append(e)
        return new_list

    def post_update(self):
        self.process_collisions()

        self.bullets = self.update_and_filter_deleted(self.bullets)
        self.enemies = self.update_and_filter_deleted(self.enemies)

        self.update_score()
        self.update_bomb_power()
        self.update_level()
    
    # CoR pattern
    def init_key_handlers(self):
        key_pressed_handler = ShipMovementKeyPressedHandler(self, self.ship)
        key_pressed_handler = BombKeyPressedHandler(self, self.ship, key_pressed_handler)
        self.key_pressed_handler = key_pressed_handler

        key_released_handler = ShipMovementKeyReleasedHandler(self, self.ship)
        self.key_released_handler = key_released_handler
Example #2
0
class SpaceGame(GameApp):
    def init_game(self):
        self.ship = Ship(self, CANVAS_WIDTH // 2, CANVAS_HEIGHT // 2)
        self.score_wait = 0
        self.level = 1
        self.level_text = Text(self, '', 100, 580)
        self.update_level_text()

        self.score = StatusWithText(self, 100, 20, 'Score: %d', 0)

        self.bomb_power = BOMB_FULL_POWER
        self.bomb_wait = 0
        self.bomb_power_text = Text(self, '', 700, 20)
        self.update_bomb_power_text()

        self.elements.append(self.ship)
        self.power_up = []
        self.enemies = []
        self.bullets = []

        self.enemy_creation_strategies = [
            StarEnemyGenerationStrategy(),
            EdgeEnemyGenerationStrategy(),
            GhostEnemyGenerationStrategy()
        ]
        self.init_key_handlers()

    def init_key_handlers(self):
        key_pressed_handler = ShipMovementKeyPressedHandler(self, self.ship)
        key_pressed_handler = BombKeyPressedHandler(self, self.ship,
                                                    key_pressed_handler)
        self.key_pressed_handler = key_pressed_handler

        key_released_handler = ShipMovementKeyReleasedHandler(self, self.ship)
        self.key_released_handler = key_released_handler

    def create_enemies(self):
        p = random()

        for i in range(len(self.enemy_creation_strategies)):
            if p < 0.2:
                enemies = self.enemy_creation_strategies[0].generate(
                    self, self.ship)
                break
            elif p < 0.5:
                enemies = self.enemy_creation_strategies[1].generate(
                    self, self.ship)
            else:
                enemies = self.enemy_creation_strategies[2].generate(
                    self, self.ship)

        for e in enemies:
            self.add_enemy(e)

    def add_enemy(self, enemy):
        self.enemies.append(enemy)

    def add_bullet(self, bullet):
        self.bullets.append(bullet)

    def bullet_count(self):
        return len(self.bullets)

    def powerup(self):
        self.create_power_up()
        self.after_function(15000, self.canvas.delete(self.bomb_canvas_id))

    def create_power_up(self):
        pass

    def bomb(self):
        if self.bomb_power == BOMB_FULL_POWER:
            self.bomb_power = 0

            self.bomb_canvas_id = self.canvas.create_oval(
                self.ship.x - BOMB_RADIUS, self.ship.y - BOMB_RADIUS,
                self.ship.x + BOMB_RADIUS, self.ship.y + BOMB_RADIUS)

            self.after(200, lambda: self.canvas.delete(self.bomb_canvas_id))

            for e in self.enemies:
                if self.ship.distance_to(e) <= BOMB_RADIUS:
                    e.to_be_deleted = True

    def create_bomb(self):
        self.bomb_canvas_id = self.canvas.create_oval(
            self.ship.x - BOMB_RADIUS, self.ship.y - BOMB_RADIUS,
            self.ship.x + BOMB_RADIUS, self.ship.y + BOMB_RADIUS)

    def enemy_distroyed_by_bomb(self):
        for e in self.enemies:
            if self.ship.distance_to(e) <= BOMB_RADIUS:
                e.to_be_deleted = True

    # def update_score_text(self):
    #     self.score_text.set_text('Score: %d' % self.score)

    def update_bomb_power_text(self):
        self.bomb_power_text.set_text('Power: %d%%' % self.bomb_power)

    def update_level_text(self):
        self.level_text.set_text('Level: %d' % self.level)

    def update_score(self):
        self.score_wait += 1
        if self.score_wait >= SCORE_WAIT:
            # self.score += 1
            self.score.value += 1
            self.score_wait = 0
            # self.update_score_text()

    def update_bomb_power(self):
        self.bomb_wait += 1
        if (self.bomb_wait >= BOMB_WAIT) and (self.bomb_power !=
                                              BOMB_FULL_POWER):
            self.bomb_power += 1
            self.bomb_wait = 0
            self.update_bomb_power_text()

    # def create_enemy_star(self):
    #     enemies = []
    #
    #     x = randint(100, CANVAS_WIDTH - 100)
    #     y = randint(100, CANVAS_HEIGHT - 100)
    #
    #     while vector_len(x - self.ship.x, y - self.ship.y) < 200:
    #         x = randint(100, CANVAS_WIDTH - 100)
    #         y = randint(100, CANVAS_HEIGHT - 100)
    #
    #     for d in range(18):
    #         dx, dy = direction_to_dxdy(d * 20)
    #         enemy = Enemy(self, x, y, dx * ENEMY_BASE_SPEED, dy * ENEMY_BASE_SPEED)
    #         enemies.append(enemy)
    #
    #     return enemies

    # def create_enemy_from_edges(self):
    #     x, y = random_edge_position()
    #     vx, vy = normalize_vector(self.ship.x - x, self.ship.y - y)
    #
    #     vx *= ENEMY_BASE_SPEED
    #     vy *= ENEMY_BASE_SPEED
    #
    #     enemy = Enemy(self, x, y, vx, vy)
    #     return [enemy]

    def pre_update(self):
        if random() < 0.1:
            self.create_enemies()

    def process_bullet_enemy_collisions(self):
        for b in self.bullets:
            for e in self.enemies:
                if b.is_colliding_with_enemy(e):
                    b.to_be_deleted = True
                    e.to_be_deleted = True

    def process_ship_enemy_collision(self):
        for e in self.enemies:
            if self.ship.is_colliding_with_enemy(e):
                self.stop_animation()

    def process_collisions(self):
        self.process_bullet_enemy_collisions()
        # self.process_ship_enemy_collision()

    def update_and_filter_deleted(self, elements):
        new_list = []
        for e in elements:
            e.update()
            e.render()
            if e.to_be_deleted:
                e.delete()
            else:
                new_list.append(e)
        return new_list

    def post_update(self):
        self.process_collisions()

        self.bullets = self.update_and_filter_deleted(self.bullets)
        self.enemies = self.update_and_filter_deleted(self.enemies)

        self.update_score()
        self.update_bomb_power()
Example #3
0
class SpaceGame(GameApp):
    def init_game(self):
        self.ship = Ship(self, CANVAS_WIDTH // 2, CANVAS_HEIGHT // 2)

        self.level = 1
        self.level_text = Text(self, '', 100, 580)
        self.update_level_text()

        self.score_wait = 0
        self.score = StatusWithText(self, 100, 20, 'Score: %d', 0)

        self.bomb_power = BOMB_FULL_POWER
        self.bomb_wait = 0
        self.bomb_power_text = Text(self, '', 700, 20)
        self.update_bomb_power_text()

        self.elements.append(self.ship)

        self.enemies = []
        self.bullets = []

        self.enemy_creation_strategies = [(0.2, StarEnemyGenerationStrategy()),
                                          (1.0, EdgeEnemyGenerationStrategy())]

        self.init_key_handlers()

    def add_enemy(self, enemy):
        self.enemies.append(enemy)

    def add_bullet(self, bullet):
        self.bullets.append(bullet)

    def bullet_count(self):
        return len(self.bullets)

    def bomb(self):
        if self.bomb_power == BOMB_FULL_POWER:
            self.bomb_power = 0

            self.bomb_canvas_id = self.canvas.create_oval(
                self.ship.x - BOMB_RADIUS, self.ship.y - BOMB_RADIUS,
                self.ship.x + BOMB_RADIUS, self.ship.y + BOMB_RADIUS)

            self.after(200, lambda: self.canvas.delete(self.bomb_canvas_id))

            for e in self.enemies:
                if self.ship.distance_to(e) <= BOMB_RADIUS:
                    e.to_be_deleted = True

            self.update_bomb_power_text()

    def update_bomb_power_text(self):
        self.bomb_power_text.set_text('Power: %d%%' % self.bomb_power)

    def update_level_text(self):
        self.level_text.set_text('Level: %d' % self.level)

    def update_score(self):
        self.score_wait += 1
        if self.score_wait >= SCORE_WAIT:
            self.score.value += 1
            self.score_wait = 0

    def update_bomb_power(self):
        self.bomb_wait += 1
        if (self.bomb_wait >= BOMB_WAIT) and (self.bomb_power !=
                                              BOMB_FULL_POWER):
            self.bomb_power += 1
            self.bomb_wait = 0
            self.update_bomb_power_text()

    def create_enemies(self):
        p = random()

        for prob, strategy in self.enemy_creation_strategies:
            if p < prob:
                enemies = strategy.generate(self, self.ship)
                break

        for e in enemies:
            self.add_enemy(e)

    def pre_update(self):
        if random() < 0.1:
            self.create_enemies()

    def process_bullet_enemy_collisions(self):
        for b in self.bullets:
            for e in self.enemies:
                if b.is_colliding_with_enemy(e):
                    b.to_be_deleted = True
                    e.to_be_deleted = True

    def process_ship_enemy_collision(self):
        for e in self.enemies:
            if self.ship.is_colliding_with_enemy(e):
                self.stop_animation()

    def process_collisions(self):
        self.process_bullet_enemy_collisions()
        self.process_ship_enemy_collision()

    def update_and_filter_deleted(self, elements):
        new_list = []
        for e in elements:
            e.update()
            e.render()
            if e.to_be_deleted:
                e.delete()
            else:
                new_list.append(e)
        return new_list

    def post_update(self):
        self.process_collisions()

        self.bullets = self.update_and_filter_deleted(self.bullets)
        self.enemies = self.update_and_filter_deleted(self.enemies)

        self.update_score()
        self.update_bomb_power()

    def init_key_handlers(self):
        key_pressed_handler = ShipMovementKeyPressedHandler(self, self.ship)
        key_pressed_handler = BombKeyPressedHandler(self, self.ship,
                                                    key_pressed_handler)
        self.key_pressed_handler = key_pressed_handler
        key_released_handler = ShipMovementKeyReleasedHandler(self, self.ship)
        self.key_released_handler = key_released_handler
Example #4
0
class SpaceGame(GameApp):
    def init_game(self):
        self.ship = Ship(self, CANVAS_WIDTH // 2, CANVAS_HEIGHT // 2)

        self.level = StatusWithText(self, 100, 580, 'Level: %d', 0)

        self.score_wait = 0
        self.score = StatusWithText(self, 100, 20, 'Score: %d', 0)

        self.bomb_wait = 0
        self.bomb_power = StatusWithText(self, 700, 20, 'Power: %d%%', 0)

        self.elements.append(self.ship)

        self.enemy_creation_strategies = [(0.2, StarEnemyGenerationStrategy()),
                                          (1.0, EdgeEnemyGenerationStrategy())]

        self.init_key_handlers()

        self.enemies = []
        self.bullets = []

    def add_enemy(self, enemy):
        self.enemies.append(enemy)

    def add_bullet(self, bullet):
        self.bullets.append(bullet)

    def bullet_count(self):
        return len(self.bullets)

    def bomb(self):
        if self.bomb_power.value == BOMB_FULL_POWER:
            self.bomb_power.value = 0

            self.bomb_circle

            self.after(200, lambda: self.canvas.delete(self.bomb_canvas_id))

            self.enemy_destroying

    def bomb_circle(self):
        self.bomb_canvas_id = self.canvas.create_oval(
            self.ship.x - BOMB_RADIUS, self.ship.y - BOMB_RADIUS,
            self.ship.x + BOMB_RADIUS, self.ship.y + BOMB_RADIUS)

    def enemy_destroying(self):
        for e in self.enemies:
            if self.ship.distance_to(e) <= BOMB_RADIUS:
                e.to_be_deleted = True

    def update_score(self):
        self.score_wait += 1
        if self.score_wait >= SCORE_WAIT:
            self.score_wait = 0
            self.score.value += 1

    def update_bomb_power(self):
        self.bomb_wait += 1
        if (self.bomb_wait >= BOMB_WAIT) and (self.bomb_power.value !=
                                              BOMB_FULL_POWER):
            self.bomb_power.value += 1
            self.bomb_wait = 0

    def create_enemy_star(self):
        enemies = []

        x = randint(100, CANVAS_WIDTH - 100)
        y = randint(100, CANVAS_HEIGHT - 100)

        while vector_len(x - self.ship.x, y - self.ship.y) < 200:
            x = randint(100, CANVAS_WIDTH - 100)
            y = randint(100, CANVAS_HEIGHT - 100)

        for d in range(18):
            dx, dy = direction_to_dxdy(d * 20)
            enemy = Enemy(self, x, y, dx * ENEMY_BASE_SPEED,
                          dy * ENEMY_BASE_SPEED)
            enemies.append(enemy)

        return enemies

    def create_enemy_from_edges(self):
        x, y = random_edge_position()
        vx, vy = normalize_vector(self.ship.x - x, self.ship.y - y)

        vx *= ENEMY_BASE_SPEED
        vy *= ENEMY_BASE_SPEED

        enemy = Enemy(self, x, y, vx, vy)
        return [enemy]

    def create_enemies(self):
        p = random()

        for prob, strategy in self.enemy_creation_strategies:
            if p < prob:
                enemies = strategy.generate(self, self.ship)
                break

        for e in enemies:
            self.add_enemy(e)

    def pre_update(self):
        if random() < 0.1:
            self.create_enemies()

    def process_bullet_enemy_collisions(self):
        for b in self.bullets:
            for e in self.enemies:
                if b.is_colliding_with_enemy(e):
                    b.to_be_deleted = True
                    e.to_be_deleted = True

    def process_ship_enemy_collision(self):
        for e in self.enemies:
            if self.ship.is_colliding_with_enemy(e):
                self.stop_animation()

    def process_collisions(self):
        self.process_bullet_enemy_collisions()
        self.process_ship_enemy_collision()

    def update_and_filter_deleted(self, elements):
        new_list = []
        for e in elements:
            e.update()
            e.render()
            if e.to_be_deleted:
                e.delete()
            else:
                new_list.append(e)
        return new_list

    def post_update(self):
        self.process_collisions()

        self.bullets = self.update_and_filter_deleted(self.bullets)
        self.enemies = self.update_and_filter_deleted(self.enemies)

        self.update_score()
        self.update_bomb_power()

    def init_key_handlers(self):
        key_pressed_handler = ShipMovementKeyPressedHandler(self, self.ship)
        key_pressed_handler = BombKeyPressedHandler(self, self.ship,
                                                    key_pressed_handler)
        self.key_pressed_handler = key_pressed_handler

        key_released_handler = ShipMovementKeyReleasedHandler(self, self.ship)
        self.key_released_handler = key_released_handler
Example #5
0
class SpaceGame(GameApp):
    def init_game(self):
        self.ship = Ship(self, CANVAS_WIDTH // 2, CANVAS_HEIGHT // 2)

        # self.level = 1
        # self.level_text = Text(self, '', 100, 580)
        self.level = StatusWithText(self, 100, 580, 'Level: %d', 1)
        # self.update_level_text()

        self.score_wait = 0
        # self.score = 0
        # self.score_wait = 0
        # self.score_text = Text(self, '', 100, 20)
        # self.update_score_text()
        self.score = StatusWithText(self, 100, 20, 'Score: %d', 0)

        # self.bomb_power = BOMB_FULL_POWER
        self.bomb_wait = 0
        # self.bomb_power_text = Text(self, '', 700, 20)
        self.bomb_power = StatusWithText(self, 700, 20, 'Power: %d',
                                         BOMB_FULL_POWER)
        # self.update_bomb_power_text()

        self.elements.append(self.ship)

        self.enemies = []
        self.bullets = []

        self.enemy_creation_strategies = [(0.2, StarEnemyGenerationStrategy()),
                                          (1.0, EdgeEnemyGenerationStrategy())]

        self.init_key_handlers()

    def init_key_handlers(self):
        key_pressed_handler = ShipMovementKeyPressedHandler(self, self.ship)
        key_pressed_handler = BombKeyPressedHandler(self, self.ship,
                                                    key_pressed_handler)
        self.key_pressed_handler = key_pressed_handler

        key_released_handler = ShipMovementKeyReleasedHandler(self, self.ship)
        self.key_released_handler = key_released_handler

    def add_enemy(self, enemy):
        self.enemies.append(enemy)

    def add_bullet(self, bullet):
        self.bullets.append(bullet)

    def bullet_count(self):
        return len(self.bullets)

    def bomb(self):

        if self.bomb_power.value == BOMB_FULL_POWER:
            self.bomb_power.value = 0

            self.bomb_canvas_id = self.create_bomb()

            self.after(200, lambda: self.canvas.delete(self.bomb_canvas_id))

            # for e in self.enemies:
            #     if self.ship.distance_to(e) <= BOMB_RADIUS:
            #         e.to_be_deleted = True

            self.destroy_enemie(len(self.enemies))

            self.update_bomb_power_text()

    def create_bomb(self):
        self.canvas.create_oval(self.ship.x - BOMB_RADIUS,
                                self.ship.y - BOMB_RADIUS,
                                self.ship.x + BOMB_RADIUS,
                                self.ship.y + BOMB_RADIUS)

    def destroy_enemie(self, enemie_amount):
        if enemie_amount == 0:
            return
        if self.ship.distance_to(self.enemies[enemie_amount]) <= BOMB_RADIUS:
            self.enemies[enemie_amount].to_be_deleted = True
        self.destroy_enemie(enemie_amount - 1)

    # def update_score_text(self):
    #     self.score_text.set_text('Score: %d' % self.score)

    def update_bomb_power_text(self):
        self.bomb_power_text.set_text('Power: %d%%' % self.bomb_power)

    def update_level_text(self):
        self.level_text.set_text('Level: %d' % self.level)

    def update_score(self):
        self.score_wait += 1
        if self.score_wait >= SCORE_WAIT:
            # self.score += 1
            self.score.value += 1

            self.score_wait = 0
            # self.update_score_text()
        self.level.value = self.score.value // 10 + 1

    def update_bomb_power(self):
        self.bomb_wait += 1
        if (self.bomb_wait >= BOMB_WAIT) and (self.bomb_power.value !=
                                              BOMB_FULL_POWER):
            self.bomb_power.value += 1
            self.bomb_wait = 0
            # self.update_bomb_power_text()

    def create_enemy_star(self):
        enemies = []

        x = randint(100, CANVAS_WIDTH - 100)
        y = randint(100, CANVAS_HEIGHT - 100)

        while vector_len(x - self.ship.x, y - self.ship.y) < 200:
            x = randint(100, CANVAS_WIDTH - 100)
            y = randint(100, CANVAS_HEIGHT - 100)

        for d in range(18):
            dx, dy = direction_to_dxdy(d * 20)
            enemy = Enemy(self, x, y, dx * ENEMY_BASE_SPEED,
                          dy * ENEMY_BASE_SPEED)
            enemies.append(enemy)

        return enemies

    def create_enemy_from_edges(self):
        x, y = random_edge_position()
        vx, vy = normalize_vector(self.ship.x - x, self.ship.y - y)

        vx *= ENEMY_BASE_SPEED
        vy *= ENEMY_BASE_SPEED

        enemy = Enemy(self, x, y, vx, vy)
        return [enemy]

    def create_enemies(self):
        # if random() < 0.2:
        #     enemies = self.create_enemy_star()
        # else:
        #     enemies = self.create_enemy_from_edges()

        p = random()

        for prob, strategy in self.enemy_creation_strategies:
            if p < prob:
                enemies = strategy.generate(self, self.ship)
                break

        for e in enemies:
            self.add_enemy(e)

    def pre_update(self):
        if random() < 0.1:
            self.create_enemies()

    def process_bullet_enemy_collisions(self):
        for b in self.bullets:
            for e in self.enemies:
                if b.is_colliding_with_enemy(e):
                    b.to_be_deleted = True
                    e.to_be_deleted = True

    def process_ship_enemy_collision(self):
        for e in self.enemies:
            if self.ship.is_colliding_with_enemy(e):
                self.stop_animation()
                self.end_game()
                self.init_game()

    def process_collisions(self):
        self.process_bullet_enemy_collisions()
        # -- comment out this line to prevent ship collision
        self.process_ship_enemy_collision()

    def update_and_filter_deleted(self, elements):
        new_list = []
        for e in elements:
            e.update()
            e.render()
            if e.to_be_deleted:
                e.delete()
            else:
                new_list.append(e)
        return new_list

    def post_update(self):
        self.process_collisions()

        self.bullets = self.update_and_filter_deleted(self.bullets)
        self.enemies = self.update_and_filter_deleted(self.enemies)

        self.update_score()
        self.update_bomb_power()

    # def on_key_pressed(self, event):
    #     if event.keysym == 'Left':
    #         self.ship.start_turn('LEFT')
    #     elif event.keysym == 'Right':
    #         self.ship.start_turn('RIGHT')
    #     elif event.char == ' ':
    #         self.ship.fire()
    #     elif event.char.upper() == 'Z':
    #         self.bomb()

    # def on_key_released(self, event):
    #     if event.keysym == 'Left':
    #         self.ship.stop_turn('LEFT')
    #     elif event.keysym == 'Right':
    #         self.ship.stop_turn('RIGHT')

    def end_game(self):
        for enemie in self.enemies:
            enemie.to_be_deleted = True
        self.enemies.clear()
        for b in self.bullets:
            b.to_be_deleted = True
        self.bullets.clear()
        for e in self.elements:
            e.to_be_deleted = True
        self.elements.clear()
        self.level.to_be_deleted = True
        self.score.to_be_deleted = True
        self.bomb_power.to_be_deleted = True
Example #6
0
class SpaceGame(GameApp):
    def init_game(self):
        self.ship = Ship(self, CANVAS_WIDTH // 2, CANVAS_HEIGHT // 2)

        # Debugging: Avoid death
        # This is a bad practice. GameApp should not access argument.
        # TODO: Refactor this
        self.is_debugging = len(sys.argv) >= 2

        self.level = StatusWithText(self, 100, 580, 'Level: %d', 1)
        self.level_wait = 0

        self.score_wait = 0
        self.score = StatusWithText(self, 100, 20, 'Score: %d', 0)

        self.bomb_power = StatusWithText(self, 700, 20, 'Power: %d%%',
                                         BOMB_FULL_POWER)
        self.bomb_canvas_id = None
        self.bomb_wait = 0

        self.elements.append(self.ship)

        self.init_key_handlers()

        self.enemies = []
        self.bullets = []

    def create_strategies(self):
        return [
            # Formula 0.2 + level/100
            # Ex. Level 1 = 0.2 + 1/100 == 0.21
            # Note: Floating point error is not taken in account
            (min(0.2 + (self.level.value / 100),
                 0.3), StarEnemyGenerationStrategy()),
            (1.0, EdgeEnemyGenerationStrategy())
        ]

    def init_key_handlers(self):
        key_pressed_handler = ShipMovementKeyPressedHandler(self, self.ship)
        key_pressed_handler = BombKeyPressedHandler(self, self.ship,
                                                    key_pressed_handler)
        self.key_pressed_handler = key_pressed_handler

        key_released_handler = ShipMovementKeyReleasedHandler(self, self.ship)
        self.key_released_handler = key_released_handler

    def add_enemy(self, enemy):
        self.enemies.append(enemy)

    def add_bullet(self, bullet):
        self.bullets.append(bullet)

    def bullet_count(self):
        return len(self.bullets)

    def create_bomb(self):
        self.bomb_canvas_id = self.canvas.create_oval(
            self.ship.x - BOMB_RADIUS, self.ship.y - BOMB_RADIUS,
            self.ship.x + BOMB_RADIUS, self.ship.y + BOMB_RADIUS)

    def destroy_bomb(self):
        self.canvas.delete(self.bomb_canvas_id)

    def destroy_enemies_in_bomb(self):
        for e in self.enemies:
            if self.ship.distance_to(e) <= BOMB_RADIUS:
                e.to_be_deleted = True

    def bomb(self):
        if self.bomb_power.value == BOMB_FULL_POWER:
            self.bomb_power.value = 0
            self.create_bomb()
            self.after(200, self.destroy_bomb)
            self.destroy_enemies_in_bomb()

    def update_level(self):
        self.level_wait += 1
        if self.level_wait >= LEVEL_WAIT:
            self.level.value += 1
            self.level_wait = 0

    def update_score(self):
        self.score_wait += 1
        if self.score_wait >= SCORE_WAIT:
            self.score.value += 1
            self.score_wait = 0

    def update_bomb_power(self):
        self.bomb_wait += 1
        if (self.bomb_wait >= BOMB_WAIT) and (self.bomb_power.value !=
                                              BOMB_FULL_POWER):
            self.bomb_power.value += 1
            self.bomb_wait = 0

    def create_enemies(self):
        p = random()
        enemies = []
        for prob, strategy in self.create_strategies():
            if p < prob:
                enemies = strategy.generate(self, self.ship)
                break
        for e in enemies:
            self.add_enemy(e)

    def pre_update(self):
        if random() < 0.1:
            self.create_enemies()

    def process_bullet_enemy_collisions(self):
        for b in self.bullets:
            for e in self.enemies:
                if b.is_colliding_with_enemy(e):
                    b.to_be_deleted = True
                    e.to_be_deleted = True

    def process_ship_enemy_collision(self):
        for e in self.enemies:
            if self.ship.is_colliding_with_enemy(e):
                self.stop_animation()

    def process_collisions(self):
        self.process_bullet_enemy_collisions()
        self.process_ship_enemy_collision()

    def update_and_filter_deleted(self, elements):
        new_list = []
        for e in elements:
            e.update()
            e.render()
            if e.to_be_deleted:
                e.delete()
            else:
                new_list.append(e)
        return new_list

    def post_update(self):
        if not self.is_debugging:
            self.process_collisions()

        self.bullets = self.update_and_filter_deleted(self.bullets)
        self.enemies = self.update_and_filter_deleted(self.enemies)

        self.update_score()
        self.update_bomb_power()

        if self.score.value % 20 == 0:
            self.update_level()
Example #7
0
class SpaceGame(GameApp):
    def init_game(self):
        self.ship = Ship(self, CANVAS_WIDTH // 2, CANVAS_HEIGHT // 2)

        self.level = 1
        self.level_text = Text(self, '', 100, 580)
        self.update_level_text()

        self.score = 0
        self.score_wait = 0
        self.score_text = Text(self, '', 100, 20)
        self.update_score_text()

        self.bomb_power = BOMB_FULL_POWER
        self.bomb_wait = 0
        self.bomb_power_text = Text(self, '', 700, 20)
        self.update_bomb_power_text()

        self.elements.append(self.ship)

        self.enemies = []
        self.bullets = []

    def add_enemy(self, enemy):
        self.enemies.append(enemy)

    def add_bullet(self, bullet):
        self.bullets.append(bullet)

    def bullet_count(self):
        return len(self.bullets)

    def bomb(self):
        if self.bomb_power == BOMB_FULL_POWER:
            self.bomb_power = 0

            self.bomb_canvas_id = self.canvas.create_oval(
                self.ship.x - BOMB_RADIUS, self.ship.y - BOMB_RADIUS,
                self.ship.x + BOMB_RADIUS, self.ship.y + BOMB_RADIUS)

            self.after(200, lambda: self.canvas.delete(self.bomb_canvas_id))

            for e in self.enemies:
                if self.ship.distance_to(e) <= BOMB_RADIUS:
                    e.to_be_deleted = True

            self.update_bomb_power_text()

    def update_score_text(self):
        self.score_text.set_text('Score: %d' % self.score)

    def update_bomb_power_text(self):
        self.bomb_power_text.set_text('Power: %d%%' % self.bomb_power)

    def update_level_text(self):
        self.level_text.set_text('Level: %d' % self.level)

    def update_score(self):
        self.score_wait += 1
        if self.score_wait >= SCORE_WAIT:
            self.score += 1
            self.score_wait = 0
            self.update_score_text()

    def update_bomb_power(self):
        self.bomb_wait += 1
        if (self.bomb_wait >= BOMB_WAIT) and (self.bomb_power !=
                                              BOMB_FULL_POWER):
            self.bomb_power += 1
            self.bomb_wait = 0
            self.update_bomb_power_text()

    def create_enemy_star(self):
        enemies = []

        x = randint(100, CANVAS_WIDTH - 100)
        y = randint(100, CANVAS_HEIGHT - 100)

        while vector_len(x - self.ship.x, y - self.ship.y) < 200:
            x = randint(100, CANVAS_WIDTH - 100)
            y = randint(100, CANVAS_HEIGHT - 100)

        for d in range(18):
            dx, dy = direction_to_dxdy(d * 20)
            enemy = Enemy(self, x, y, dx * ENEMY_BASE_SPEED,
                          dy * ENEMY_BASE_SPEED)
            enemies.append(enemy)

        return enemies

    def create_enemy_from_edges(self):
        x, y = random_edge_position()
        vx, vy = normalize_vector(self.ship.x - x, self.ship.y - y)

        vx *= ENEMY_BASE_SPEED
        vy *= ENEMY_BASE_SPEED

        enemy = Enemy(self, x, y, vx, vy)
        return [enemy]

    def create_enemies(self):
        if random() < 0.2:
            enemies = self.create_enemy_star()
        else:
            enemies = self.create_enemy_from_edges()

        for e in enemies:
            self.add_enemy(e)

    def pre_update(self):
        if random() < 0.1:
            self.create_enemies()

    def process_bullet_enemy_collisions(self):
        for b in self.bullets:
            for e in self.enemies:
                if b.is_colliding_with_enemy(e):
                    b.to_be_deleted = True
                    e.to_be_deleted = True

    def process_ship_enemy_collision(self):
        for e in self.enemies:
            if self.ship.is_colliding_with_enemy(e):
                self.stop_animation()

    def process_collisions(self):
        self.process_bullet_enemy_collisions()
        self.process_ship_enemy_collision()

    def update_and_filter_deleted(self, elements):
        new_list = []
        for e in elements:
            e.update()
            e.render()
            if e.to_be_deleted:
                e.delete()
            else:
                new_list.append(e)
        return new_list

    def post_update(self):
        self.process_collisions()

        self.bullets = self.update_and_filter_deleted(self.bullets)
        self.enemies = self.update_and_filter_deleted(self.enemies)

        self.update_score()
        self.update_bomb_power()

    def on_key_pressed(self, event):
        if event.keysym == 'Left':
            self.ship.start_turn('LEFT')
        elif event.keysym == 'Right':
            self.ship.start_turn('RIGHT')
        elif event.char == ' ':
            self.ship.fire()
        elif event.char.upper() == 'Z':
            self.bomb()

    def on_key_released(self, event):
        if event.keysym == 'Left':
            self.ship.stop_turn('LEFT')
        elif event.keysym == 'Right':
            self.ship.stop_turn('RIGHT')
Example #8
0
class SpaceGame(GameApp):
    def init_game(self):
        self.background = Sprite(
            self, "images/background.png", CANVAS_WIDTH//2, CANVAS_HEIGHT//2)
        self.ship = Ship(self, CANVAS_WIDTH // 2, CANVAS_HEIGHT // 2)

        self.level = StatusWithText(
            self, 100, CANVAS_WIDTH-CANVAS_WIDTH*0.3, 'level: %d', 1)

        self.score_wait = 0
        self.score = StatusWithText(self, 100, 20, 'Score: %d', 0)
        self.enemy_creation_strategies = [
            [0.09, TieFighterEnemyGeration()],
            [0.03, StarEnemyGenerationStrategy()],
            [0.8, EdgeEnemyGenerationStrategy()]
        ]
        self.bomb_power = StatusWithText(
            self, CANVAS_WIDTH-100, 20, 'power: %d', BOMB_FULL_POWER)
        self.bomb_wait = 0
        self.bomb_power_text = Text(self, '', 700, 20)
        self.health = StatusWithText(
            self, 700, CANVAS_WIDTH-CANVAS_WIDTH*0.3, 'health: %d', 4)
        self.elements.append(self.ship)
        self.boss = None
        self.turbo_power()
        self.enemies = []
        self.bullets = []
        self.init_key_handlers()

    def init_key_handlers(self):
        key_pressed_handler = ShipMovementKeyPressedHandler(self, self.ship)
        key_pressed_handler = BombKeyPressedHandler(
            self, self.ship, key_pressed_handler)
        self.key_pressed_handler = key_pressed_handler

        key_released_handler = ShipMovementKeyReleasedHandler(self, self.ship)
        self.key_released_handler = key_released_handler

    def deathstar_fire(self, delay=0):

        if self.boss.in_screen:
            self.boss.start_fire_dir_ship(self.ship.x, self.ship.y)
        if delay <= 200:
            self.after(100, lambda: self.deathstar_fire(delay+1))
        else:
            delay = 0
            self.after(5000, lambda: self.deathstar_fire(delay))

    def level_stage(self):
        if self.score.value >= 400 and self.boss == None:
            self.boss = DeathStar(self)
            self.boss.come_in()
            self.deathstar_fire()
        if self.score.value >= 300:
            self.level.value = 5
            self.enemy_creation_strategies[0][0] = 1
            self.enemy_creation_strategies[1][0] = 0
            self.enemy_creation_strategies[2][0] = 0
        elif self.score.value >= 200:
            self.level.value = 4
            self.enemy_creation_strategies[1][0] = 0.05
        elif self.score.value >= 100:
            self.level.value = 3
            self.enemy_creation_strategies[0][0] = 0.15
        elif self.score.value >= 10:
            self.level.value = 2
            self.enemy_creation_strategies[2][0] = 1

    def create_enemies(self):
        p = random()
        for prob, strategy in self.enemy_creation_strategies:
            if p < prob:
                enemies = strategy.generate(self, self.ship)
                for e in enemies:
                    self.add_enemy(e)

    def add_enemy(self, enemy):
        self.enemies.append(enemy)

    def add_bullet(self, bullet):
        if self.bomb_power.value > 0:
            self.bomb_power.value -= 1
            self.bullets.append(bullet)

    def bullet_count(self):
        return len(self.bullets)

    def animate_bomb(self, i):
        if len(self.bomb_list) > 0:
            self.canvas.delete(self.bomb_list[-1])
            if i == 10:
                return
        bomb = 0+BOMB_RADIUS*(i*0.1)
        self.bomb_list.append(self.canvas.create_oval(
            self.ship.x - bomb,
            self.ship.y - bomb,
            self.ship.x + bomb,
            self.ship.y + bomb, fill="#CCFFFF"))
        self.after(50, lambda: self.animate_bomb(i+1))

    def bomb(self):
        if self.bomb_power.value == BOMB_FULL_POWER:
            self.bomb_power.value = 0
            self.bomb_list = []
            self.animate_bomb(0)
            for e in self.enemies:
                if self.ship.distance_to(e) <= BOMB_RADIUS:
                    if isinstance(e, TieFighter):
                        explode = Explode(self, e.x, e.y, 200)
                        explode.update()
                    else:
                        explode = Explode(self, e.x, e.y, 50)
                        explode.update()
                    self.score.value += 1
                    e.to_be_deleted = True

    def update_level_text(self):
        self.level.value += 1

    def update_score(self):
        self.score_wait += 1
        if self.score_wait >= SCORE_WAIT:
            self.score.value += 1
            self.score_wait = 0

    def update_health(self):
        self.health_wait += 1

    def update_bomb_power(self):
        self.bomb_wait += 1
        if (self.bomb_wait >= BOMB_WAIT) and (self.bomb_power.value != BOMB_FULL_POWER):
            self.bomb_wait = 0
            self.bomb_power.value += 1

    def pre_update(self):
        if random() < 0.1:
            self.create_enemies()

    def turbo_power(self):
        if self.bomb_power.value < 10:
            self.ship.turbo = False
        if self.ship.turbo == True and self.bomb_power.value > 0:
            self.bomb_power.value -= 1
        self.after(50, self.turbo_power)

    def process_bullet_enemy_collisions(self):
        for b in self.bullets:
            for e in self.enemies:
                if b.is_colliding_with_enemy(e):
                    if isinstance(e, TieFighter):
                        explode = Explode(self, e.x, e.y, 200)
                        explode.update()
                    else:
                        explode = Explode(self, e.x, e.y, 50)
                        explode.update()
                    self.score.value += 1
                    b.to_be_deleted = True
                    e.to_be_deleted = True

    def process_ship_enemy_collision(self):
        for e in self.enemies:

            if self.ship.is_colliding_with_enemy(e):
                self.health.value -= 1
                self.ship_got_hit(50)
                e.to_be_deleted = True
                if self.health.value == 0 or isinstance(e, TieFighter):
                    self.health.value = 0
                    self.ship_got_hit(200)
                    self.ship.delete()
                    self.stop_animation()

    def process_collisions(self):
        self.process_bullet_enemy_collisions()
        self.process_ship_enemy_collision()

    def ship_got_hit(self, size):
        explode = Explode(self, self.ship.x, self.ship.y, size)
        explode.update()

    def update_and_filter_deleted(self, elements):
        new_list = []
        for e in elements:
            e.update()
            e.render()
            if e.to_be_deleted:
                e.delete()
            else:
                new_list.append(e)
        return new_list

    def post_update(self):
        self.process_collisions()
        self.level_stage()
        self.bullets = self.update_and_filter_deleted(self.bullets)
        self.enemies = self.update_and_filter_deleted(self.enemies)

        self.update_score()
        self.update_bomb_power()