Example #1
0
    def __init__(self, screen):
        from scene import LoadingScene, PlatformingScene

        loading_scene = LoadingScene(screen)
        loading_scene.draw()
        pygame.display.update()

        self.scene    = PlatformingScene(screen)
        self.player   = self.scene.player

        self.spawners = [getOpponent(opp_name) for opp_name in Options.selected_opponents]

        feed_sources = [getFeeder(feed_name) for feed_name in Options.selected_feeds]
        word_list    = [word for feeder in feed_sources for word in feeder.words]
        self.words   = WordMaker(word_list)

        self.free_movement = False
        
        self.direction         = 'r'   # What direction are we moving in
        self.spawncount        = 0     # Frame tick counter for spawn event
        self.jumpsoon          = False # Has a jump been scheduled by the player?
        self.selected_platform = None  # What platform are we scheduled to jump to
Example #2
0
class Controller:
    """ Event and game status handler for main game. """

    def __init__(self, screen):
        from scene import LoadingScene, PlatformingScene

        loading_scene = LoadingScene(screen)
        loading_scene.draw()
        pygame.display.update()

        self.scene    = PlatformingScene(screen)
        self.player   = self.scene.player

        self.spawners = [getOpponent(opp_name) for opp_name in Options.selected_opponents]

        feed_sources = [getFeeder(feed_name) for feed_name in Options.selected_feeds]
        word_list    = [word for feeder in feed_sources for word in feeder.words]
        self.words   = WordMaker(word_list)

        self.free_movement = False
        
        self.direction         = 'r'   # What direction are we moving in
        self.spawncount        = 0     # Frame tick counter for spawn event
        self.jumpsoon          = False # Has a jump been scheduled by the player?
        self.selected_platform = None  # What platform are we scheduled to jump to

    def switchToScene(self):
        return self.scene.switch_to

    def handleKeydown(self, key):
        shifting = (pygame.key.get_mods() & KMOD_SHIFT)

        if (self.scene.challenging):
            pass # do some other stuff with ChallengeScene

        if key in (K_LCTRL,K_RCTRL):
            self.unselect() # Release selected object
        elif key == K_SPACE:
            self.key_space()
        elif key in directions:
            self.keydown_direction(key)
        elif key == K_END: # Toggle player free movement
            self.toggle_free_movement()
        elif key in range(256): # ASCII character
            key_chr = chr(key)
            if key_chr in string.lowercase: # Word character
                self.type_normal(key_chr)
            elif key_chr in specials+shifted_specials: # Special character (,.@# etc)
                if not shifting:
                    self.type_special(key_chr)
                else:
                    self.type_special(key_chr.translate(special_keys_trans_table))

    def handleKeyup(self, key):
        if key in directions:
            self.keyup_direction(key)

    def auto_move_player(self):
        if self.player.state not in (States.shooting, States.jumping):
            # Player is capable of making a jump
            if self.jumpsoon:
                # A jump has been scheduled
                if self.direction == 'r':
                    if self.player.rect.right > self.jumppos:
                        # Distance less than the maximum jump distance
                        self.player.jump(self.selected_platform)
                        self.clear_jump()
                elif self.direction == 'l':
                    if self.player.rect.left < self.jumppos:
                        # Distance less than the maximum jump distance
                        self.player.jump(self.selected_platform)
                        self.clear_jump()
                        
        if self.player.state is not States.shooting:
            # Player is capable of movement
            if self.direction == 'r':
                self.player.direct(K_RIGHT)
            elif self.direction == 'l':
                self.player.direct(K_LEFT)

    def lazy_redraw(self):
        return self.scene.lazy_redraw()

    def tick(self, elapsed):
        if not self.free_movement:
            self.auto_move_player()

        self.collide_player_with_enemies()

        self.collide_player_with_powerups()

        self.spawn_enemies()

        self.scene.tick(elapsed)

    def draw(self):
        return self.scene.draw()

    def key_space(self):
        if (self.free_movement):
            self.player.jump()
        else:
            self.change_direction()

    def keydown_direction(self, key):
        if (self.free_movement):
            self.scene.movelist.append(key)

    def keyup_direction(self, key):
        if (self.free_movement):
            self.scene.movelist.remove(key)

    def toggle_free_movement(self):
        self.free_movement = not self.free_movement

    def clear_jump(self):
        self.jumppos = None
        self.jumpsoon = False
        if (self.selected_platform):
            self.selected_platform.selected = False     
            self.selected_platform = None   

    def collide_player_with_enemies(self):
        # TODO Retool this so it's more robust
        colliders = pygame.sprite.spritecollide(self.player, self.scene.actives, True)

        collision_hurt = False    # Was the collision with an actual, living enemy
        collision_special = False # Was the collision with a commando

        for enemy in colliders:
            if isinstance(enemy, Commando):
                collision_special = True
            elif enemy.ttl is None: # Enemies ttl is none if they haven't died
                collision_hurt = True
        if collision_hurt:
            if self.player.selected_opponent in colliders:
                # Make sure the enemy isn't selected anymore
                self.player.selected_opponent = None
            if (self.player.state != States.hit):
                # Decrease player's health and play hit animation
                self.scene.health.decrease()
                self.player.hit()
        if collision_special:
            self.scene.challenging = True
            return

    def collide_player_with_powerups(self):
        powerups = pygame.sprite.spritecollide(self.player, self.scene.powerups, True)
        for powerup in powerups:
            powerup.effect(self.scene, self.player)

    def spawn_enemies(self):            
        def spawnspot(position, direction = None):
            # Spawn more enemies in the direction the player is headed
            left_offset  = random.randint(-game_constants.w, -game_constants.w / 2)
            right_offset = random.randint(game_constants.w / 2, game_constants.w)

            if direction is None:
                xpos = position[0] + random.choice([left_offset, right_offset])
            elif direction == 'l':
                xpos = position[0] + left_offset
            elif direction == 'r':
                xpos = position[0] + right_offset
                
            ypos = position[1] - random.randint(game_constants.h / 6, game_constants.h / 5)
                
            return (xpos, ypos)
    
        self.spawncount += 1

        # Rough value used for spawning of new opponents
        level = (int(self.scene.score.score) / 10) + 5
        if self.spawncount <= 120 / (.20 * level):
            return

        self.spawncount = 0

        if len(self.scene.actives) > game_constants.max_enemies:
            return
    
        characters_in_use = list(set([enemy.word.string[0] for enemy in self.scene.actives]))

        next_word = self.words.next_word(characters_in_use)

        if self.player.state in (States.idle, States.shooting):
            # Player is standing still: Spawn equally likely to each side
            spawnpos = spawnspot(self.player.position)
        else:
            # Player is moving: Spawn in direction player is moving to
            spawnpos = spawnspot(self.player.position, self.player.direction)

        if len(self.spawners):
            EnemyType = random.choice(self.spawners) # 1/n chance of all enemy types
            self.scene.actives.add(EnemyType(next_word, spawnpos, self.scene.statics))

    def command(self, key):
        platform = self.scene.type_special(key)
        if not platform: return

        platform.selected = True
        self.selected_platform = platform
        self.jumpsoon = True
        if self.direction == 'r':
            if self.player.rect.right < platform.rect.left:
                self.jumppos = platform.rect.left - game_constants.maxjump_width
            else:
                self.direction = 'l'
                self.jumppos = platform.rect.right + game_constants.maxjump_width
        elif self.direction == 'l':
            if self.player.rect.left > platform.rect.right:
                self.jumppos = platform.rect.right + game_constants.maxjump_width
            else:
                self.direction = 'r'
                self.jumppos = platform.rect.left - game_constants.maxjump_width

    def change_direction(self):
        if self.direction == 'l':
            self.direction = 'r'
        elif self.direction == 'r':
            self.direction = 'l'
        self.clear_jump()

    def _find_opponent_for_key(self, key):
        for opponent in self.scene.actives: # Try to shoot everyone!
            hit = opponent.typeon(key)
            if hit:
                self.player.selected_opponent = opponent
                break
        if not self.player.selected_opponent:
            self.scene.score.miss()
        else:
            self.player.shoot(self.player.selected_opponent)

    def _shoot_currently_targeted_opponent(self, key):
        hit = self.player.selected_opponent.typeon(key)
        if not hit:
            self.scene.score.miss()
            return

        self.player.shoot(self.player.selected_opponent)
        if self.player.selected_opponent.defeated():
            # If we killed who we're shooting at
            self.scene.score.increase(self.player.selected_opponent.value())
            # Set up death animation, kill sprite eventually
            self.player.selected_opponent.destroy()
            self.player.idle()
            
            if random.randint(0, 10) < 3: # Spawn a powerup when enemies die, sometimes.
                spawnpos = self.player.selected_opponent.rect.center
                if random.randint(0, 5) < 2:
                    powerup = Shotgun
                else:
                    powerup = Heart
                self.scene.powerups.add(powerup(spawnpos, self.scene.statics))

            self.player.selected_opponent = None

    def type_normal(self, key):
        if not self.player.selected_opponent:
            self._find_opponent_for_key(key) 
        else:
            self._shoot_currently_targeted_opponent(key)

    def type_special(self, key):
        if self.player.state in (States.falling, States.jumping):
            return
        
        self.command(key)

    def unselect(self):
        if self.player.selected_opponent:
            self.player.selected_opponent.release()
            self.player.selected_opponent = None
        self.player.idle()