package main;
use strict;
use warnings;
use SDL;
use SDLx::App;
use SDL::Event;
use SDL::Events;
use Data::Dumper;
use player;
# Set up Application Options. Let SDLx::App take care of looping
my $app = SDLx::App->new (w => 450, h => 300,
t => "Bob Loblaw", hw_surface => 1,
double_buf => 1, dt => .2, delay => 20,);
#SDL::Events::enable_key_repeat(10, 10);
# Instantiate game objects
my $player = player->new();
$app->add_move_handler(\&move_handler);
$app->add_show_handler(\&show_handler);
$app->add_move_handler(\&event_handler);
#$app->add_event_handler(\&event_handler);
# Handle game object reaction to events
sub event_handler
{
my $event = shift;
#if ($event->type == SDL_QUIT) { exit; }
$player->move_react(@_);
$player->fire_react(@_);
}
# Handle game object movement
sub move_handler
{
# add empty event to queue to force processing of event handlers
#SDL::Events::push_event(SDL::Event->new);
$player->move_bullets(@_);
$player->move(@_);
}
# Handle game object drawing
sub show_handler
{
$app->draw_rect([0,0,$app->w,$app->h], [0,0,0,0]);
$player->draw_bullets(@_);
$player->draw(@_);
$app->update;
}
# Finally, run the app
$app->run;
1;
####
#! /opt/perl/bin/perl
package Mob;
use Moose;
use SDL::Events;
use Data::Dumper;
has 'position' => (is => 'rw', builder => 'build_pos');
has 'velocity' => (is => 'rw', builder => 'build_vel');
has 'max_speed' => (is => 'rw', default => 50);
# Delta velocity, or how much we change the speed each event
has 'dv' => (is => 'rw', default => 3);
sub build_pos
{
return {x => 200, y=> 200};
}
sub build_vel
{
return {x => 2, y=> 2};
}
sub move_react
{
my $self = shift;
my $event = shift;
SDL::Events::pump_events;
my $keys = SDL::Events::get_key_state;
if ($keys->[SDLK_LEFT])
{
$self->{velocity}->{x} -= $self->{dv} unless ($self->{velocity}->{x} < -$self->{max_speed});
}
if ($keys->[SDLK_RIGHT])
{
$self->{velocity}->{x} += $self->{dv} unless ($self->{velocity}->{x} > $self->{max_speed});
}
# Slow horizontal movement if neither modifier keys are pressed
if (!$keys->[SDLK_LEFT] && !$keys->[SDLK_RIGHT])
{
if ($self->{velocity}->{x} > 0)
{
$self->{velocity}->{x} -= 1;
}
elsif ($self->{velocity}->{x} < 0)
{
$self->{velocity}->{x} += 1;
}
}
if ($keys->[SDLK_UP])
{
$self->{velocity}->{y} -= $self->{dv} unless ($self->{velocity}->{y} < -$self->{max_speed});
}
if ($keys->[SDLK_DOWN])
{
$self->{velocity}->{y} += $self->{dv} unless ($self->{velocity}->{y} > $self->{max_speed});
}
# Slow vertical movement if neither modifier keys are pressed
if (!$keys->[SDLK_UP] && !$keys->[SDLK_DOWN])
{
if ($self->{velocity}->{y} > 0)
{
$self->{velocity}->{y} -= 1;
}
elsif ($self->{velocity}->{y} < 0)
{
$self->{velocity}->{y} += 1;
}
}
}
sub move
{
my ($self, $step, $app, $time) = @_;
SDL::Events::pump_events;
my $keys = SDL::Events::get_key_state;
$self->{position}->{x} += $self->{velocity}->{x} * $step;
$self->{position}->{y} += $self->{velocity}->{y} * $step;
# No keys? Slow them ALL DOWN
if (!$keys->[SDLK_UP] && !$keys->[SDLK_DOWN] && !$keys->[SDLK_LEFT] && !$keys->[SDLK_RIGHT])
{
if ($self->{velocity}->{x} > 0)
{
$self->{velocity}->{x} -= 1;
}
elsif ($self->{velocity}->{x} < 0)
{
$self->{velocity}->{x} += 1;
}
if ($self->{velocity}->{y} > 0)
{
$self->{velocity}->{y} -= 1;
}
elsif ($self->{velocity}->{y} < 0)
{
$self->{velocity}->{y} += 1;
}
}
}
sub draw
{
my ($self, $step, $app) = @_;
$app->draw_circle_filled([$self->{position}->{x}, $self->{position}->{y}], 10, [250,255,250,255]);
}
1;
####
#! /opt/perl/bin/perl
package player;
use Moose;
use List::Util qw[min max];
use SDL::Events;
use Time::HiRes;
use Data::Dumper;
use btype;
extends 'ship';
has 'score' => (is => 'rw', isa => 'Int', default => 0);
has 'bullets' => (is => 'rw', isa => 'ArrayRef[bullet]');
has 'ammo' => (is => 'rw', isa => 'Int', default => 1000);
has 'max_ammo' => (is => 'rw', isa => 'Int', default => 1000);
sub fire_react
{
my $self = shift;
my $event = shift;
my $keys = SDL::Events::get_key_state;
if ($keys->[SDLK_SPACE] && $self->{ammo} > 0)
{
push (@{$self->{bullets}}, btype->get_shot(1, $self->{position}));
$self->{ammo} -= 1;
}
elsif (!$keys->[SDLK_SPACE])
{
$self->{ammo} = min($self->{ammo} + 1, $self->{max_ammo});
}
}
sub move_bullets
{
my ($self, $step, $app, $time) = @_;
my @tbullets;
my $length = 0;
foreach my $bullet (@{$self->{bullets}})
{
if ($bullet->{position}->{y} < -5 || $bullet->{position}->{y} > $app->h + 5)
{
push(@tbullets, $bullet);
}
elsif ($bullet->{position}->{x} < -5 || $bullet->{position}->{x} > $app->w + 5)
{
push(@tbullets, $bullet);
}
else
{
unshift(@tbullets, $bullet);
$length += 1;
}
}
@{$self->{bullets}} = splice(@tbullets, 0, $length);
foreach my $bullet (@{$self->{bullets}})
{
$bullet->move($step);
}
}
sub draw_bullets
{
my $self = shift;
foreach my $bullet (@{$self->{bullets}})
{
$bullet->draw(@_);
}
}
1;