Skip to content

Instantly share code, notes, and snippets.

@kthakore
Created July 16, 2010 14:45
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kthakore/478440 to your computer and use it in GitHub Desktop.
Save kthakore/478440 to your computer and use it in GitHub Desktop.
=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