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;