package Hexed::Map; use strict; use warnings; use include; use Hexed::Util; use Curses; # Set up the window, but not the pad (yet). sub init { my ($class, $dat) = @_; $dat->{Pad} = undef; $dat->{MapHeight} = $dat->{MapWidth} = 0; $dat->{OffY} = $dat->{OffX} = 0; # Set up our offset pointers. die "How do we render!?\n" unless $dat->{Opts}{Render}; $dat->{Render} = $dat->{Opts}{Render}; delete $dat->{Opts}; return bless $dat, $class; } # Swap in a new map with fixed dimensions. sub setup { my ($win, $map) = @_; my $height = $map->height; my $width = $map->width; # Reset the offset pointers. $win->{OffY} = $win->{OffX} = 0; # Create a new pad and initialize it. (+1 due to ncurses offset) my $pad = newpad($height + 1, $width + 1); # Fill it up with the map's contents. foreach my $y (0 .. $height) { foreach my $x (0 .. $width) { my $draw = $win->{Render}->($map->{Map}[$y][$x]); $pad->addch($y, $x, $draw); } } # Set up a map handler so updating a tile tells us too. $map->{OnChange} = sub { my $self = shift; # Magic closureness ensures we see the reference to the window here! $win->_mod(@_); }; $win->{MapHeight} = $height; $win->{MapWidth} = $width; $win->{Pad} = $pad; return 1; } # Modify a tile. Should be automatically called by the map interface. sub _mod { my ($self, $y, $x, $new) = @_; my $draw = $self->{Render}->($new); $self->{Pad}->addch($y, $x, $draw); } # Redraw the window. sub draw { my $self = shift; die "No map has been setup yet!\n" unless $self->{Pad}; $self->{Win}->refresh if shift; # fullscreen HexedUI stuff kills border $self->{Pad}->prefresh( $self->{OffY}, $self->{OffX}, # Where to start in the map? $self->{Y1}, $self->{X1}, $self->{Y2}, $self->{X2} # Where on the screen? ); # LIVECD THING: sleep or input #select(undef, undef, undef, 0.1); #getch; return 1; } # Shift the frame right. sub right { my $self = shift; $self->{OffX}++ if $self->{OffX} + 1 <= $self->{MapWidth} - $self->{Width}; } # Shift the frame left. sub left { my $self = shift; $self->{OffX}-- if $self->{OffX} - 1 >= 0; } # Shift the frame up. sub up { my $self = shift; $self->{OffY}-- if $self->{OffY} - 1 >= 0; } # Shift the frame down. sub down { my $self = shift; $self->{OffY}++ if $self->{OffY} + 1 <= $self->{MapHeight} - $self->{Height}; } 42;