Game-EnergyLoop
view release on metacpan or search on metacpan
lib/Game/EnergyLoop.pm view on Meta::CPAN
# -*- Perl -*-
#
# Game::EnergyLoop - a simple energy system
package Game::EnergyLoop;
our $VERSION = '0.01';
use strict;
use warnings;
sub update {
my ($enlos, $initiative, $arg) = @_;
my $min = ~0;
for my $ent (@$enlos) {
my $energy = $ent->enlo_energy;
$min = $energy if $energy < $min;
}
die "negative minimum energy $min" if $min < 0;
my @active;
for my $ent (@$enlos) {
my $energy = $ent->enlo_energy;
$energy -= $min;
push @active, $ent if $energy == 0;
$ent->enlo_energy($energy);
}
$initiative->( \@active ) if defined $initiative and @active > 1;
my @newbies;
for my $ent (@active) {
my ( $new_energy, $noobs ) = $ent->enlo_update( $min, $arg );
die "negative entity new_energy $new_energy" if $new_energy < 0;
$ent->enlo_energy($new_energy);
push @newbies, @$noobs if defined $noobs;
}
push @$enlos, @newbies;
return $min;
}
# TODO may need a return flag to indicate whether game is blocked? but
# if that's important the caller could set a flag in their world object
# and check for that...
1;
__END__
=head1 NAME
Game::EnergyLoop - a simple energy system
=head1 SYNOPSIS
use Game::EnergyLoop;
use Object::Pad;
class Foo {
field $name :param;
field $energy :param;
field $priority :param :reader;
field $cur_energy = 0;
method enlo_energy ( $new = undef ) {
$cur_energy = $new if defined $new;
return $cur_energy;
}
method enlo_update( $value, $epoch ) {
print "$epoch RUN $name ($priority) $value\n";
return $energy;
}
}
sub pri { @{$_[0]} = sort {$b->priority <=> $a->priority} @{$_[0]} }
my @obj = map {
Foo->new(
name => "N$_",
energy => ( 1 + int rand 8 ),
priority => int rand 2,
( run in 0.981 second using v1.01-cache-2.11-cpan-39bf76dae61 )