Exemplo n.º 1
0
class Enemy(Object):
    "Representa un enemigo del videojuego."
    
    def __init__(self, game, name, sprites, x, y, player):
        Object.__init__(self, game.stage)
        self.game = game
        self.name = name
        self.init_animations()
        self.image = self.animation.get_image()
        self.x = x
        self.y = y
        self.rect = pygame.Rect(self.x, self.y, 10, 10)
        self.flip = True
        self.change_state(Stand(self))
        self.dy = 0
        self.sprites = sprites
        self.last_attack = (0, 0)
        self.player = player
        self.shadow = shadow.Shadow(self)

        # Collision when is trowed
        self.collision_fly = None
        self.update_animation()

        if player:
            self.update()
            self.energy = energy.EnergyModel(name, 100, game.on_enemy_energy_model_change)
        else:
            Object.update(self)
            self.z = -self.y

    def init_animations(self):
        self.animation = Animation('enemies/' + self.name)

    def update(self):
        if self.are_in_camera_area():
            self.state.update()
            Object.update(self)
            self.z = -self.y
            self.shadow.update_from_parent()

    def kill(self):
        Object.kill(self)
        self.shadow.kill()

    def update_animation(self):
        self.image = self.animation.get_image(self.flip)
        return self.animation.advance()

    def change_state(self, state):
        self.state = state

    def set_collision(self, power=1):
        """Define una zona como 'colisionable' para golpear a otros"""

        (_, _, w, h) = self.image.get_rect()
        cw, ch = 50, 10

        if self.flip:
            x = self.x - cw - w/2 + cw + 15
        else:
            x = self.x + w/2 - cw - 15

        y = self.y + self.dy - h / 2
        
        Object.set_collision(self, (x, y), cw, ch)
        self.collision_power = power

    def do_collision_check(self, new_state_if_occur):
        "Evalúa si recibe un golpe, si es así altera su estado."

        collision = self._get_collision_receive()

        if collision:
            power, self.flip = collision

            if self.energy.must_die():
                self.change_state(HardHit(self))
            else:
                if power == 1 or power == 3:
                    self.change_state(HitStand(self))
                elif power == 2:
                    self.change_state(HitStand(self, 2))
                elif power == 5: # special
                    self.change_state(HardHit(self, -16, 8))
                else:
                    self.change_state(HardHit(self))

            self.create_hit()

    def _get_collision_receive(self):
        """Determina si en ese momento es golpeado por otro personaje."""

        e = self.game.player

        if self.sensitive and e.collision_rect and same_z_dist(e, self):
            if e.collision_rect.colliderect(self.get_screen_rect()):
                try:
                    new_flip = (self.x - e.x) / abs(self.x - e.x)
                except:
                    new_flip = 1
                return e.collision_power, new_flip == 1

    def get_collision_send(self):
        "Retorna True si detecta que ha golpeado a un personaje"

        e = self.player

        if e.sensitive and self.collision_rect and same_z_dist(e, self):
            if self.collision_rect.colliderect(e.get_screen_rect()):
                return True

    def create_hit(self, dy=0):
        """Genera un explosión que indica la existencia de un golpe."""
        dx = -40 if self.flip else 0

        x = self.x + dx
        y = self.y - 100 + dy
        self.sprites.add(Hit(x, y))

    def can_take_by_player(self):
        "Informa al jugador si este enemigo se puede sujetar."
        return isinstance(self.state, (Stand, WalkToPlayer))

    def see_to_player(self):
        self.flip = True if self.rect.x > self.player.rect.x else False

    def is_close_to_player(self):
        "Informa si el enemigo está muy cerca del protagonista."
        a, b = self, self.player
        return same_z_dist(a, b) and common.get_dist(a, b) < 100
Exemplo n.º 2
0
class Player(Object):
    
    def __init__(self, game, control, sprites, datadir, x=100, y=350):
        Object.__init__(self)
        self.game = game
        self.name = 'shaolin'
        self.datadir = datadir
        self.init_animations(datadir)
        self.image = self.animation.get_image()
        self.rect = pygame.Rect(self.x, self.y, 10, 10)
        self.flip = False
        self.change_state(Stand(self))
        self.x = x
        self.y = y
        self.dy = 0
        self.control = control
        self.sprites = sprites
        self.last_attack = (0, 0)
        self.update()
        self.id = ID(self.name, 100)


    def init_animations(self, datadir):
        self.animation = Animation(datadir + '/player/')


    def update(self):
        self.control.update()
        self.state.update()
        Object.update(self)
        self.z = -self.y


    def update_animation(self):
        self.image = self.animation.get_image(self.flip)
        return self.animation.advance()


    def change_state(self, state):
        self.state = state


    def move(self, dx, dy):
        "Intenta avanzar en la dirección indicada"

        self.x += dx
        self.y += dy

        up, down, left, right = 470, 230, 20, 1250

        if self.y > up:
            self.y = up
        elif self.y < down:
            self.y = down

        if self.x < left:
            self.x = left
        elif self.x > right:
            self.x = right


    def set_collision(self, power=1, dy=0, cw=50):
        """Define una zona como 'colisionable' para golpear a otros"""

        (_, _, w, h) = self.image.get_rect()
        ch = 10

        if self.flip:
            x = self.x - cw - w/2 + cw + 15
        else:
            x = self.x + w/2 - cw - 15

        y = self.y + self.dy - h / 2 + dy
        
        Object.set_collision(self, (x, y), cw, ch)
        self.collision_power = power

        # intenta golpear a sus enemigos (ESTO FUNCIONA)
        
        #for e in self.enemies:
        #    if same_z_dist(e, self):
        #        if self.collision_rect.colliderect(e.get_screen_rect()):
        #            print "He golpeado a otro personaje del juego"

    def get_collision_to_take_enemies(self, dy):
        """Verifica si puede sujetar a otros personajes del juego.

        Si están dadas las condiciones para sujetarlo (distancia y
        disponibilidad), retorna al enemigo. En caso contrario retorna None."""

        y_min = 10
        x_min = 30

        for e in self.game.enemies:
            if abs(common.get_dist_x(self, e)) < x_min:
                dist_y = common.get_dist_y(self, e)
                
                if dy >= 0:
                    if dist_y < 0 and dist_y > - y_min:
                        # intenta sujetar al enemigo mientras sube.
                        if e.can_take_by_player():
                            return e
                else:
                    if dist_y > 0 and dist_y < y_min:
                        # intenta sujetar al enemigo mientras baja.
                        if e.can_take_by_player():
                            return e


    def get_collision_receive(self):
        """Determina si en ese momento es golpeado por otro personaje."""

        for e in self.game.enemies:
            if self.sensitive and e.collision_rect and same_z_dist(e, self):
                if e.collision_rect.colliderect(self.get_screen_rect()):
                    try:
                        new_flip = (self.x - e.x) / abs(self.x - e.x)
                    except:
                        new_flip = 1
                    return e.collision_power, new_flip == 1

    def get_collision_send(self):
        "Retorna True si detecta que ha golpeado a un personaje"

        for e in self.game.enemies:
            if e.sensitive and self.collision_rect and same_z_dist(e, self):
                if self.collision_rect.colliderect(e.get_screen_rect()):
                    return True

    def get_screen_rect(self):
        image_rect = self.image.get_rect()
        return (self.rect.x, self.rect.y, image_rect.w, image_rect.h)

    def create_hit(self):
        """Genera un explosión que indica la existencia de un golpe."""

        if self.flip:
            dx = - 60
        else:
            dx = 30

        x = self.x + dx
        y = self.y - 130
        self.sprites.add(Hit(x, y, self.datadir))

    def can_take_by_player(self):
        """Informa al jugador si este enemigo se puede sujetar."""

        return isinstance(self.state, (Stand, Walk, Run))
Exemplo n.º 3
0
class Player(Object):
    
    def __init__(self, game, control, sprites, datadir):
        Object.__init__(self, game.stage)
        self.game = game
        self.name = 'shaolin'
        self.datadir = datadir
        self.init_animations(datadir)
        self.image = self.animation.get_image()
        self.x = 100
        self.y = 350
        self.rect = pygame.Rect(self.x, self.y, 10, 10)
        self.flip = False
        self.bandage = bandage.Bandage(self)
        self.change_state(Starting(self))
        self.dy = 0
        self.control = control
        self.sprites = sprites
        self.last_attack = (0, 0)
        self.energy_model = energy.EnergyModel(self.name, 100,
                game.on_player_energy_model_change)
        self.hit_receive_counter = 0
        self.shadow = shadow.Shadow(self)
        self.update()

    def init_animations(self, datadir):
        self.animation = Animation('shaolin')

    def update(self):
        self.state.update()
        Object.update(self)
        self.z = -self.y
        self.bandage.update_from_parent()
        self.shadow.update_from_parent()

    def update_animation(self):
        self.image = self.animation.get_image(self.flip)
        self.rect.size = self.image.get_width(), self.image.get_height()
        return self.animation.advance()

    def change_state(self, state):
        self.state = state

    def kill(self):
        Object.kill(self)
        self.shadow.kill()

    def set_collision(self, power=1, dy=0, cw=50):
        """Define una zona como 'colisionable' para golpear a otros"""

        (_, _, w, h) = self.image.get_rect()
        ch = 10

        if self.flip:
            x = self.x - cw - w/2 + cw + 15
        else:
            x = self.x + w/2 - cw - 15

        y = self.y + self.dy - h / 2 + dy
        
        Object.set_collision(self, (x, y), cw, ch)
        self.collision_power = power

        # intenta golpear a sus enemigos (ESTO FUNCIONA)
        
        #for e in self.enemies:
        #    if same_z_dist(e, self):
        #        if self.collision_rect.colliderect(e.get_screen_rect()):
        #            print "He golpeado a otro personaje del juego"

    def check_collision_receive(self):
        if self.get_collision_receive():
            power, self.flip = self.get_collision_receive()

            if power > 1:
                self.hit_receive_counter = 0
                self.change_state(HardHit(self))
            else:
                self.hit_receive_counter += 1

                if self.hit_receive_counter > 3:
                    self.change_state(HardHit(self))
                    self.hit_receive_counter = 0
                else:
                    self.change_state(HitStand(self))

            self.create_hit()


    def get_collision_to_take_enemies(self, dy):
        """Verifica si puede sujetar a otros personajes del juego.

        Si están dadas las condiciones para sujetarlo (distancia y
        disponibilidad), retorna al enemigo. En caso contrario retorna None"""

        y_min = 10
        x_min = 30

        for e in self.game.enemies:
            if abs(common.get_dist_x(self, e)) < x_min:
                dist_y = common.get_dist_y(self, e)

                
                if dy >= 0:
                    if dist_y > 0 and dist_y < y_min:
                        # intenta sujetar al enemigo mientras baja.
                        if e.can_take_by_player():
                            return e
                else:
                    if dist_y > 0 and dist_y < y_min:
                        # intenta sujetar al enemigo mientras sube.
                        if e.can_take_by_player():
                            return e

    def get_collision_receive(self):
        """Determina si en ese momento es golpeado por otro personaje."""

        for e in self.game.enemies:
            if self.sensitive and e.collision_rect and same_z_dist(e, self):
                if e.collision_rect.colliderect(self.get_screen_rect()):
                    try:
                        new_flip = (self.x - e.x) / abs(self.x - e.x)
                    except:
                        new_flip = 1
                    return e.collision_power, new_flip == 1

    def get_collision_send(self):
        "Retorna True si detecta que ha golpeado a un personaje"

        for e in self.game.enemies:
            if e.sensitive and self.collision_rect and same_z_dist(e, self):
                if self.collision_rect.colliderect(e.get_screen_rect()):
                    return True


    def create_hit(self):
        """Genera un explosión que indica la existencia de un golpe."""

        dx = - 60 if self.flip else 30
        x = self.x + dx
        y = self.y - 130
        common.audio.play('punch1')
        self.sprites.add(Hit(x, y))

    def can_take_by_player(self):
        """Informa al jugador si este enemigo se puede sujetar."""

        return isinstance(self.state, (Stand, Walk, Run))

    def do_fall_if_are_in_air(self):
        """Previene que el personaje no quede 'volando' cuando se quiere bajar
        de una caja"""

        x, y = self.get_pos()
        dist = self.stage.get_dist_to_flood(x, y, self.dy)

        if dist < 0:
            self.change_state(JumpStand(self, 0))
            return True

    def do_stand_if_are_in_flood(self):
        "Procura que el personaje 'pise' el suelo o los objetos del nivel"
        x, y = self.get_pos()
        dy = self.dy

        flood = self.stage.get_dist_to_flood(x, y, dy)

        if flood >= 0:
            self.change_state(Stand(self))
            self.dy = self.stage.get_flood_dy(x, y)
            return