Beispiel #1
0
def get_control_points(interval):
    """
    Returns all 4 control points of a bezier interval

    Args:
        interval (dict) : Holds one interval of the bezier curve that is two waypoints

    Returns:
        (misc.Vector, misc.Vector, misc.Vector, misc.Vector) If the interval holds position bezier
        (float, float, float, float)       Else : the interval holds value bezier
    """
    # If the interval is for position or vector
    if "to" in interval.keys():
        st = Vector(interval["s"][0], interval["s"][1])
        en = Vector(interval["e"][0], interval["e"][1])
        to = Vector(interval["synfig_to"][0], interval["synfig_to"][1])
        ti = Vector(interval["synfig_ti"][0], interval["synfig_ti"][1])

    # If the interval is for real values
    else:
        st = interval["s"][0]
        en = interval["e"][0]
        to = interval["synfig_o"][0]
        ti = interval["synfig_i"][0]
    return st, to, ti, en
def handle_color():
    """
    Default linear tangent values for color interpolations

    Args:
        (None)

    Returns:
        (misc.Vector, misc.Vector) : out and in tangents for color parameter
    """
    out_val = Vector(0.5, 0.5, "color")
    in_val = Vector(0.5, 0.5, "color")
    return out_val, in_val
def game_map(player, orc, air, candy):
    """Create a level and place the other objects in it."""
    from misc import Vector
    from dungeon import Dungeon
    from registry import Registry
    registry = Registry()
    dungeon = Dungeon()
    dungeon.initialize(player, registry)
    level = dungeon.current_level
    # Place player and orc in this level
    player.place(level, Vector(0, 0))
    orc.place(level, Vector(5, 5))
    candy.place(level, Vector(1, 0))
    air.place(level, Vector(0, 1))
    return level
Beispiel #4
0
 def _init_room(self, room):
     """Make the tiles in the map that correspond to the room walkable."""
     for x in range(room.x1 + 1, room.x2):
         for y in range(room.y1 + 1, room.y2):
             pos = Vector(x, y)
             self.walkable[pos] = True
             self.transparent[pos] = True
Beispiel #5
0
    def compute_path(self, pos1, pos2):
        """
        Calculate a path between pos1 and pos2 in the game map.

        Args:
            pos1 (Vector): Vector representing the starting point.
            pos2 (Vector): Vector representing the destination.

        Returns:
            list(Vector): A list of vectors, where each vector represents the position of the next tile in the path.
                The list goes up to the pos2.
        """
        # Get current walkable state
        pos1_walkable = self.walkable[pos1]
        pos2_walkable = self.walkable[pos2]
        # Set origin and destination to walkable for the actual computation to work
        self.walkable[pos1] = self.walkable[pos2] = True
        # Compute path
        path = self._map.compute_path(pos1.x, pos1.y, pos2.x, pos2.y)
        # Convert path to vectors
        path = [Vector(x, y) for x, y in [tile for tile in path]]
        # Revert origin and destination walkable state to its original state
        self.walkable[pos1] = pos1_walkable
        self.walkable[pos2] = pos2_walkable
        return path
def clamped_vector(p1, p2, p3, animated, i, lottie, ease):
    """
    Function to generate the collective tangents i.e. x tangent and y tangent
    when clamped waypoints are used

    Args:
        p1       (misc.Vector)         : First point in Co-ordinate System
        p2       (misc.Vector)         : Second point in Co-ordinate System
        p3       (misc.Vector)         : Third point in Co-ordinate System
        animated (lxml.etree._Element) : Synfig format animation
        i        (int)                 : Iterator over animation
        ease     (str)                 : Specifies if it is an ease in animation ease out

    Returns:
        (misc.Vector) : Clamped Vector is returned
    """
    x_tan = clamped_tangent(p1.val1, p2.val1, p3.val1, animated, i)
    y_tan = clamped_tangent(p1.val2, p2.val2, p3.val2, animated, i)

    if isclose(x_tan, 0.0) or isclose(y_tan, 0.0):
        if ease == "in":
            ease_in(lottie)
        else:
            ease_out(lottie)
    return Vector(x_tan, y_tan, animated.attrib["type"])
    def handle_key_input(cls):
        """
        Use tdl's user input features to react to keyborad input.

        Returns:
            True if an action that consumes a turn was performed by the player, False otherwise.
        """
        # TODO: Have key mapping in config file and use enums (or something similar) instead
        if not cls.user_input:
            return False

        key_char = cls.user_input.char

        move_direction = None
        # Vertical and horizontal movement
        if cls.user_input.key == 'UP' or key_char == 'k':
            move_direction = Vector(0, -1)
        elif cls.user_input.key == 'DOWN' or key_char == 'j':
            move_direction = Vector(0, 1)
        elif cls.user_input.key == 'LEFT' or key_char == 'h':
            move_direction = Vector(-1, 0)
        elif cls.user_input.key == 'RIGHT' or key_char == 'l':
            move_direction = Vector(1, 0)

        # Diagonal movement
        elif key_char == 'y':
            move_direction = Vector(-1, -1)
        elif key_char == 'u':
            move_direction = Vector(1, -1)
        elif key_char == 'b':
            move_direction = Vector(-1, 1)
        elif key_char == 'n':
            move_direction = Vector(1, 1)

        # Check if the action is a movement action
        if move_direction is not None:
            return cls.movement_action(move_direction)

        if cls.user_input.key == 'ENTER' and cls.user_input.alt:
            # Alt+Enter: toggle fullscreen
            tdl.set_fullscreen(not tdl.get_fullscreen())
            return False

        elif cls.user_input.key == 'ESCAPE':
            # Exit game
            # TODO: Find more elegant way to terminate the program
            exit()

        elif cls.user_input.char == 'g':
            return cls.pickup_action()

        elif cls.user_input.char == 'e':
            return cls.interact_action()

        else:
            return False
Beispiel #8
0
    def center(self):
        """
        Get the center of this room object as a Vector.

        Returns:
            Vector: The center of this room object.
        """
        center_x = int((self.x1 + self.x2) / 2)
        center_y = int((self.y1 + self.y2) / 2)
        return Vector(center_x, center_y)
Beispiel #9
0
    def generate(self):
        """
        Generate the level's layout.
        """
        # Initialize map
        for x in range(self.width):
            for y in range(self.height):
                pos = Vector(x, y)
                self.walkable[pos] = False
                self.transparent[pos] = False

        for r in range(self.room_max_count):
            # Random width and height
            w = randint(self.room_min_size, self.room_max_size)
            h = randint(self.room_min_size, self.room_max_size)
            # Random position without going out of the boundaries of the map
            x = randint(0, self.width - w - 1)
            y = randint(0, self.height - h - 1)

            new_room = Room(x, y, w, h)

            # If it intersects with an existent room, start over
            for room in self.rooms:
                if new_room.intersect(room):
                    break
            else:
                # Room is valid
                self._init_room(new_room)

                center = new_room.center()

                if not self.rooms:
                    # First room, place up stairs
                    self.up_stairs.place(self, center)

                else:
                    # Connect room to previous room
                    previous = self.rooms[-1].center()

                    # Flip a coin
                    if randint(0, 1) == 1:
                        # First move horizontally, then vertically
                        self._create_h_tunnel(previous.x, center.x, previous.y)
                        self._create_v_tunnel(previous.y, center.y, center.x)
                    else:
                        # First move vertically, then horizontally
                        self._create_v_tunnel(previous.y, center.y, previous.x)
                        self._create_h_tunnel(previous.x, center.x, center.y)

                self.rooms.append(new_room)

        # Place down stairs
        random_room = choice(self.rooms)
        self.place_entity_randomly(self.down_stairs, random_room)
    def _render_map(cls):
        """
        Renders the current game map if necessary.
        """
        cur_map = cls.dungeon.current_level
        if cls.dungeon.fov_recomputed:
            cls.dungeon.fov_recomputed = False

            # First clear the old console before re-draw
            cls.console.clear(fg=Colors.WHITE, bg=Colors.BLACK)

            for x in range(cur_map.width):
                for y in range(cur_map.height):
                    pos = Vector(x, y)
                    wall = not cur_map.transparent[pos]

                    # If position is visible, draw a bright tile
                    if cur_map.fov[pos]:
                        if wall:
                            cls.console.draw_char(x,
                                                  y,
                                                  None,
                                                  fg=None,
                                                  bg=Colors.WALL_VISIBLE)
                        else:
                            cls.console.draw_char(x,
                                                  y,
                                                  None,
                                                  fg=None,
                                                  bg=Colors.GROUND_VISIBLE)
                        # Tiles in FOV will be remembered after they get out
                        # of sight, out of mind :^)
                        cur_map.explored[pos] = True

                    # Position is not visible, but has been explored before
                    elif cur_map.explored[pos]:
                        if wall:
                            cls.console.draw_char(x,
                                                  y,
                                                  None,
                                                  fg=None,
                                                  bg=Colors.WALL_DARK)
                        else:
                            cls.console.draw_char(x,
                                                  y,
                                                  None,
                                                  fg=None,
                                                  bg=Colors.GROUND_DARK)
Beispiel #11
0
def get_last_control_point(interval):
    """
    Returns the last control point of a bezier interval

    Args:
        interval (dict) : Holds one interval of the bezier curve that is two waypoints

    Returns:
        (misc.Vector) If the interval holds position bezier
        (float)       Else : the interval holds value bezier
    """
    if len(interval["e"]) >= 2:
        en = Vector(interval["e"][0], interval["e"][1])
    else:
        en = interval["e"][0]
    return en
Beispiel #12
0
    def place_entity_randomly(self, entity, room, allow_overlap=False):
        """
        Places the given entity randomly in a given room.
        """
        # For now, naively assume that there's a free spot
        while True:
            # Get a random position inside the room
            x = randint(room.x1 + 1, room.x2 - 1)
            y = randint(room.y1 + 1, room.y2 - 1)
            position = Vector(x, y)

            # Check if there's already an entity in this spot
            if not allow_overlap and [
                    entity
                    for entity in self.entities if entity.pos == position
            ]:
                continue

            # We found a valid spot, place the entity
            entity.place(self, position)
            return
Beispiel #13
0
class Entity(ABC):
    """
    An entity is any object that can be visually represented in the game map.

    Entities are represented by a character that is displayed to the screen,
    and a color that is applied to said character.

    Note:
        This is an abstract class and cannot be instanciated directly, it must be
        sub-classed in order for it to be usable.

    Examples:
        * A chest containing items, traps, etc.
        * The player character.
        * Enemies.

    Args:
        key (Enum): An identifier for the entity in the registry.
        name (str): A name for the entity, doesn't have to be unique.
        type (str): Pseudo-type of this entity, can be one of 'player', 'npc',
            'enemy', 'item', ...
        char (str): How the entity will be visually displayed.
        color (Colors): Color of the character that visually represents this entity.
        blocks (bool): Whether this entity is blocking or not.
        render_priority (RenderPriority): At what layer should this entity be
            rendered.
    """

    pos = Vector(0, 0)
    game_map = None

    @abstractmethod
    def __init__(self, key, name, type, char, color, blocks, render_priority):
        self.key = key
        self.name = name
        self.type = type
        self.char = char
        self.color = color
        self.blocks = blocks
        self.render_priority = render_priority
        self.behavior = None

    def __repr__(self):
        return f"{self.key.name} '{self.name}' <{self.type}>@{self.pos}"

    def move(self, direction):
        """
        Move this entity in the specified direction in the given map.

        Args:
            direction (Vector): Direction towards which to move this entity.
       """

        old_pos = self.pos
        self.pos += direction
        if self.blocks:
            # Update blocked tile in the map
            self.game_map.walkable[old_pos] = True
            self.game_map.walkable[self.pos] = False

    def distance_to(self, dest):
        """
        Calculate the distance between this entity and the destination position.

        Args:
            dest (Vector): Vector to calculate the distance to.

        Returns:
            float: The relative distance between this entity and the destination
                position.
        """
        return (self.pos - dest).norm

    def move_towards(self, dest):
        """
        Move towards the destination if there's a clear path.

        Args:
            dest (Vector): Position to move to.
        """

        path = self.game_map.compute_path(self.pos, dest)
        if not path:
            # Don't do anything
            return
        next_tile = path[0]
        direction = next_tile - self.pos

        if self.game_map.walkable[
                next_tile] and not self.game_map.get_blocking_entity_at_location(
                    next_tile):
            self.move(direction)

    def place(self, game_map, position):
        """
        Place the entity at a certain position in the given map.

        Args:
            game_map (Level): Level in which to place the entity.
            position (Vector): Position in the level where the entity should be placed.
        """
        # If the entity was on another map, first remove it from there
        if self.game_map:
            self.game_map.entities.remove(self)
            self.game_map.walkable[self.pos] = True
        self.game_map = game_map
        self.pos = position
        game_map.entities.append(self)
        if self.blocks:
            game_map.walkable[position] = False

    def take_turn(self, target):
        """
        The entity takes a turn, using the logic defined by its behavior.
        If the actor doesn't have a behavior, do nothing.

        Args:
             target (Entity): Target entity used by the behavior logic.
        """
        if self.behavior is not None:
            self.behavior(self, target)
Beispiel #14
0
 def _create_v_tunnel(self, y1, y2, x):
     """Create a vertical tunnel from y1 to y2 at a fixed x."""
     for y in range(min(y1, y2), max(y1, y2) + 1):
         pos = Vector(x, y)
         self.walkable[pos] = True
         self.transparent[pos] = True
Beispiel #15
0
 def _create_h_tunnel(self, x1, x2, y):
     """Create an horizontal tunnel from x1 to x2 at a fixed y."""
     for x in range(min(x1, x2), max(x1, x2) + 1):
         pos = Vector(x, y)
         self.walkable[pos] = True
         self.transparent[pos] = True
Beispiel #16
0
 def test_vector_operations(self):
     u = Vector(0.3, 2)
     v = Vector(3, -2.5)
     assert u + v == Vector(3.3, -0.5)
     assert u - v == Vector(-2.7, 4.5)
Beispiel #17
0
 def test_vector_norm(self, x, y, result):
     tol = 1e-5
     norm = Vector(x, y).norm
     assert abs(norm - result) < tol
Beispiel #18
0
 def test_vector_normalized(self):
     tol = 1e-5
     assert Vector(1, 0).normalized() == Vector(1, 0)
     assert Vector(0, -0.5).normalized() == Vector(0, -1)
     assert (Vector(-1, 1).normalized() -
             Vector(-sqrt(2), sqrt(2))).norm - 1. < tol
Beispiel #19
0
 def test_vector_repr(self):
     assert repr(Vector(-0.5, 2)) == "(-0.5, 2)"