view nagslang/protagonist.py @ 76:29ace74cc9de

Human
author Stefano Rivera <stefano@rivera.za.net>
date Sun, 01 Sep 2013 21:47:09 +0200
parents e118458a4e9c
children a1b4d09e6f23
line wrap: on
line source

import pymunk
import pymunk.pygame_util

from nagslang.game_object import (
    GameObject, SingleShapePhysicser, FacingImageRenderer)
from nagslang.mutators import FLIP_H
from nagslang.resources import resources


class Protagonist(GameObject):
    """Representation of our fearless protagonist.

    TODO: Factor out a bunch of this stuff when we need it for other objects.
    """

    HUMAN_FORM = 'human'
    WOLF_FORM = 'wolf'

    def __init__(self, position):
        self._setup_physics(position)
        self._setup_renderers()
        self.inventory = {}
        self.form = self.HUMAN_FORM

        super(Protagonist, self).__init__(
            self._renderers[self.form], SingleShapePhysicser(self.shape))

        self.go_human()

    def _setup_physics(self, position):
        self._body = pymunk.Body(10, 10000)
        self._body.position = position
        self._body.velocity_func = self.velocity_func

        self.shape = pymunk.Circle(self._body, 30)
        self.shape.elasticity = 1.0
        self.shape.friction = 10.0

    def _get_image(self, name, *transforms):
        return resources.get_image('creatures', name, transforms=transforms)

    def _setup_renderers(self):
        self._renderers = {
            self.HUMAN_FORM: FacingImageRenderer(
                self._get_image('human_1.png'),
                self._get_image('human_1.png', FLIP_H)),
            self.WOLF_FORM: FacingImageRenderer(
                self._get_image('werewolf_1.png'),
                self._get_image('werewolf_1.png', FLIP_H)),
        }

    @classmethod
    def from_saved_state(cls, saved_state):
        """Create an instance from the provided serialised state.
        """
        obj = cls()
        # TODO: Update from saved state.
        return obj

    def velocity_func(self, body, gravity, damping, dt):
        return pymunk.Body.update_velocity(body, gravity, self.damping, dt)

    def go_werewolf(self):
        self.form = self.WOLF_FORM
        self._body.mass = 100
        self._body.moment = 10000
        self._body.velocity_limit = 1000
        self.impulse_factor = 4000
        self.damping = 0.9
        self.renderer = self._renderers[self.form]

    def go_human(self):
        self.form = self.HUMAN_FORM
        self._body.mass = 10
        self._body.moment = 1000
        self._body.velocity_limit = 1000
        self.impulse_factor = 500
        self.damping = 0.8
        self.renderer = self._renderers[self.form]

    def set_direction(self, dx, dy):
        if (dx, dy) == (0, 0):
            return
        vec = pymunk.Vec2d((dx, dy))
        self._body.angle = vec.angle
        self._body.apply_impulse(
            (dx * self.impulse_factor, dy * self.impulse_factor))

    def toggle_form(self):
        if self.form == self.WOLF_FORM:
            self.go_human()
        else:
            self.go_werewolf()

    def act_on(self, target):
        """Perform an action on the target.
        """
        # TODO: Decide how best to do this.
        pass

    def attack(self):
        """Attempt to hurt something.
        """
        pass

    def in_wolf_form(self):
        return self.form == self.WOLF_FORM

    def in_human_form(self):
        return self.form == self.HUMAN_FORM

    def has_item(self, item):
        return item in self.inventory

    def environmental_movement(self, dx, dy):
        if (dx, dy) == (0, 0):
            return
        self._body.apply_impulse((dx, dy))