NAME

Game::TileMap - Representation of tile-based two-dimensional rectangular maps

SYNOPSIS

use Game::TileMap;

# first, create a map legend

my $legend = Game::TileMap->new_legend;

$legend
	->add_wall('#')
	->add_void('.')
	->add_terrain('_' => 'pavement')
	->add_object('monster_spawns', 'a' => 'spawn_a')
	->add_object('monster_spawns', 'b' => 'spawn_b')
	->add_object('surroundings', '=' => 'chest')
	;

# next, create a map

my $map_str = <<MAP;

.__.......
.__.......
.__.......
.__.......
.__..#####
.__..#a__=
.__..#__b_
._________
.__..#####
.__.......
.__.......

MAP

my $map = Game::TileMap->new(
	legend => $legend,
	map => $map_str
);

# map can be queried to get some info about its contents
my @monsters = $map->get_all_of_class('monster_spawns');
my @chests = $map->get_all_of_type('chest');
my $true = $map->check_within_map(0, 5);
my $false = $map->check_can_be_accessed(0, 5);

DESCRIPTION

Game::TileMap is a module which helps you build and store simple two-dimensional maps of tiles, where each tile contains only one element. Maps created from this module are generally considered immutable and should only be used to define a map, not to store its changing state.

Maps can be created out of strings or arrays of arrays and are stored as an array of array of Game::TileMap::Tile. Some helpful features are in place:

  • map markers (usually just single characters) are translated into objects specified in the legend

    Map characters can't be whitespace (whitespace is removed before processing - can be used for improved visibility).

    Legend objects can't be falsy, but other than that they can be anything (string, object, reference).

  • each legend object is assigned to a class, which you can query for later

    If you add a class surroundings:

    $legend->add_object('surroundings', '@' => 'trash bin')
           ->add_object('surroundings', '=' => 'desk')
           ->add_object('surroundings', 'H' => 'locker')
           ->add_object('surroundings', 'L' => 'chair');

    Then you can easily get information about locations of those tiles on a map:

    my @all_surroundings = $map->get_all_of_class('surroundings');

    This array will contains blessed objects of Game::TileMap::Tile class.

  • you define how your maps look yourself

    Only predefined objects are walls (can't be accessed and are considered not a part of map) and voids (can't be accessed, but are a part of map). Their predefined class is terrain. You are free to introduce as many objects and classes as needed.

  • bottom-left corner of the stringified map is at [0;0], while top-right is at [max;max]

    This lets you think of a map like you think of a coordinate frame (first quarter).

  • map array has X coordinates in first dimension and Y coordinates in second dimension

    This way you can get more familiar notation:

    $map->coordinates->[3][5]; # actual point at [3;5]
  • supports multi-character maps

    my $legend = Game::TileMap->new_legend(characters_per_tile => 2);
    
    $legend
    	->add_wall('##')
    	->add_void('..')
    	->add_terrain('__' => 'pavement')
    	->add_terrain('_~' => 'mud')
    	->add_terrain('_,' => 'grass')
    ;
    
    my $map_str = <<MAP;
    _, __ __ __ _~
    _, __ ## ## _~
    __ __ ## ## _~
    _, __ ## ## _~
    _, __ __ __ _~
    MAP

Attributes

legend

A reference to map legend. Required in constructor.

coordinates

The constructed map: array of array of Game::TileMap::Tile.

size_x

Horizontal size of the map.

size_y

Vertical size of the map.

Methods

new_legend

Static method which returns a new instance of Game::TileMap::Legend. Note that legends are reusable.

new

Moose-flavored constructor. Possible arguments are:

  • map => ArrayRef | Str

    Optional.

    Map input that will be passed to from_string or from_array.

  • legend => InstanceOf ['Game::TileMap::Legend']

    Required.

    Legend of the map, which describes its contents.

from_string

my $map = Game::TileMap->new(legend => $legend);
$map->from_string($map_str);

Creates a map from a string.

from_array

my $map = Game::TileMap->new(legend => $legend);
$map->from_array($map_aref);

Creates a map from an array.

to_string

Creates a string from a map.

to_string_and_mark

print $map->to_string_and_mark([[1, 2], [1, 3]]);

print $str = $map->to_string_and_mark([[5, 5]], 'X');

Creates a string from a map and marks given positions with a marker. The default marker is '!' (times the number of characters per tile).

Useful during debugging.

check_within_map

my $bool = $map->check_within_map($pos_x, $pos_y);

Returns true if the given position is considered to be inside the map (not outside of bounds and not a wall).

Note that $pos_x and $pos_y can be decimal (not just integers).

check_can_be_accessed

my $bool = $map->check_can_be_accessed($pos_x, $pos_y);

Returns true if the given position is considered accessible (not outside of bounds and not a wall or a void).

Note that $pos_x and $pos_y can be decimal (not just integers).

get_all_of_class

my @arr = $map->get_all_of_class('class_name');

Returns all map objects (in form of Game::TileMap::Tile instances) that are assigned to a given class (found out by string equality check).

get_all_of_type

my @arr = $map->get_all_of_type($object);

Returns all map objects (in form of Game::TileMap::Tile instances) that are of a given object type (found out by string equality check).

get_class_of_object

my $class_name = $map->get_class_of_object($object);

Does the reverse of "get_all_of_class" for one $object, which can be either an instance of Game::TileMap::Tile or just a string.

SEE ALSO

Game::LevelMap is more suited for terminal games.

Games::Board is more focused on creating board games.

AUTHOR

Bartosz Jarzyna <bbrtj.pro@gmail.com>

COPYRIGHT AND LICENSE

Copyright (C) 2022 by Bartosz Jarzyna

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.