Created
July 16, 2010 14:45
-
-
Save kthakore/478440 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=pod | |
Get the game.png from http://i.imgur.com/FxgMM.png | |
Get link.png from http://imgur.com/P7JhS | |
=head1 INSTALL | |
For windows get strawberry perl | |
Then do: | |
cpan Alien::SDL SDL | |
=cut | |
use strict; | |
use warnings; | |
use SDL::Rect; | |
use SDL::Event; | |
use SDL::Events; | |
use SDLx::Sprite; | |
use SDLx::Sprite::Animated; | |
use SDLx::Surface; | |
use SDLx::Controller; | |
my ( $width, $height ) = ( 160, 128 ); | |
my $background = SDLx::Sprite->new( image => 'game.png' ); | |
my ( $x, $y ) = ( 0, $height - $background->h ); | |
$background->{offset} = [ $width - $background->w, $y ]; | |
my $hero = SDLx::Sprite::Animated->new( | |
image => 'link.png', | |
rect => SDL::Rect->new( 70, 52, 20, 24 ), | |
ticks_per_frame => 600, | |
); | |
$hero->set_sequences( | |
stop => [ [ 0, 0 ] ], | |
stop_left => [ [ 0, 1 ] ], | |
stop_right => [ [ 0, 2 ] ], | |
stop_up => [ [ 0, 3 ] ], | |
stop_down => [ [ 0, 0 ] ], | |
down => [ | |
[ 0, 0 ], [ 1, 0 ], [ 2, 0 ], [ 3, 0 ], | |
[ 4, 0 ], [ 5, 0 ], [ 6, 0 ], [ 7, 0 ], | |
], | |
left => [ [ 0, 1 ], [ 1, 1 ], [ 2, 1 ], [ 3, 1 ], [ 4, 1 ], [ 5, 1 ], ], | |
right => [ [ 0, 2 ], [ 1, 2 ], [ 2, 2 ], [ 3, 2 ], [ 4, 2 ], [ 5, 2 ], ], | |
up => [ | |
[ 0, 3 ], [ 1, 3 ], [ 2, 3 ], [ 3, 3 ], | |
[ 4, 3 ], [ 5, 3 ], [ 6, 3 ], [ 7, 3 ], | |
], | |
); | |
$hero->sequence('stop'); | |
$hero->start; | |
my $hero_speed = 0.05; | |
my ( $hero_x, $hero_y ) = ( $hero->x, $hero->y ); | |
my ( $hero_max_x, $hero_max_y ) | |
= ( $width - $hero->rect->w, $height - $hero->rect->h ); | |
my $scroll = { | |
active => 0, | |
delta => 0.4, | |
x => 0, | |
y => 0, | |
w => 0, | |
h => 0, | |
hero_dx => 1 - $hero->rect->w / $width, | |
hero_dy => 1 - $hero->rect->h / $height, | |
}; | |
my $display = SDLx::Surface::display( | |
width => $width, | |
height => $height | |
); | |
sub on_event { | |
my $e = shift; | |
return 0 if $e->type == SDL_QUIT; | |
return 0 if $e->key_sym == SDLK_ESCAPE; | |
if ( $e->type == SDL_KEYDOWN ) { | |
$hero->sequence('left') if $e->key_sym == SDLK_LEFT; | |
$hero->sequence('right') if $e->key_sym == SDLK_RIGHT; | |
$hero->sequence('down') if $e->key_sym == SDLK_DOWN; | |
$hero->sequence('up') if $e->key_sym == SDLK_UP; | |
} | |
elsif ( $e->type == SDL_KEYUP ) { | |
$hero->sequence('stop_left') if $e->key_sym == SDLK_LEFT; | |
$hero->sequence('stop_right') if $e->key_sym == SDLK_RIGHT; | |
$hero->sequence('stop_down') if $e->key_sym == SDLK_DOWN; | |
$hero->sequence('stop_up') if $e->key_sym == SDLK_UP; | |
} | |
return 1; | |
} | |
sub move_hero { | |
my ($dt) = @_; | |
return if $scroll->{active}; | |
$hero_x -= $hero_speed * $dt if $hero->sequence eq 'left'; | |
$hero_x += $hero_speed * $dt if $hero->sequence eq 'right'; | |
$hero_y -= $hero_speed * $dt if $hero->sequence eq 'up'; | |
$hero_y += $hero_speed * $dt if $hero->sequence eq 'down'; | |
# If the hero is at the edge of the screen, start scrolling. | |
@$scroll{qw(active x w)} = ( 1, -1, $width ) if $hero_x < 0; | |
@$scroll{qw(active y h)} = ( 1, -1, $height ) if $hero_y < 0; | |
@$scroll{qw(active x w)} = ( 1, 1, $width ) if $hero_x > $hero_max_x; | |
@$scroll{qw(active y h)} = ( 1, 1, $height ) if $hero_y > $hero_max_y; | |
} | |
sub scroll_background { | |
my ($dt) = @_; | |
return unless $scroll->{active}; | |
if ( $scroll->{w} > 0 ) { | |
my $delta = $dt * $scroll->{delta}; | |
$scroll->{w} -= $delta; | |
$x -= $delta * $scroll->{x}; | |
$hero_x -= $delta * $scroll->{x} * $scroll->{hero_dx}; | |
} | |
elsif ( $scroll->{h} > 0 ) { | |
my $delta = $dt * $scroll->{delta}; | |
$scroll->{h} -= $delta; | |
$y -= $delta * $scroll->{y}; | |
$hero_y -= $delta * $scroll->{y} * $scroll->{hero_dy}; | |
} | |
else { | |
@$scroll{qw(active w h)} = ( 0, 0, 0 ); | |
} | |
} | |
sub boundary_check { | |
my $sequence = $hero->sequence; | |
if ( ( $sequence eq 'up' && $y > 0 ) | |
|| ( $sequence eq 'left' && $x > 0 ) | |
|| ( $sequence eq 'down' && $y < $background->{offset}->[1] ) | |
|| ( $sequence eq 'right' && $x < $background->{offset}->[0] ) ) | |
{ | |
$x = 0 if $x > 0; | |
$y = 0 if $y > 0; | |
$x = $background->{offset}->[0] if $x < $background->{offset}->[0]; | |
$y = $background->{offset}->[1] if $y < $background->{offset}->[1]; | |
@$scroll{qw(active w h)} = ( 0, 0, 0 ); | |
$hero->sequence( 'stop_' . $sequence ); | |
} | |
} | |
sub on_show { | |
$background->draw_xy( $display, $x, $y ); | |
$hero->draw_xy( $display->surface, $hero_x, $hero_y ); | |
$display->update(); | |
} | |
my $app = SDLx::Controller->new(); | |
$app->add_event_handler( \&on_event ); | |
$app->add_show_handler( \&on_show ); | |
$app->add_move_handler( \&move_hero ); | |
$app->add_move_handler( \&boundary_check ); | |
$app->add_move_handler( \&scroll_background ); | |
$app->run(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment