#!/usr/bin/perl -w use strict; use SDL::App; use SDL::Surface; use SDL::Event; $| = 1; my (@update_rects, @fire_items, %images, $app, $event, $background); sub init_sdl { my $sdlflags = SDL_ANYFORMAT | SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_HWACCEL | SDL_ASYNCBLIT; $app = new SDL::App ( -flags => $sdlflags,-title => 'Space',-width => '800',-height => '600'); $event = new SDL::Event; $event->set(SDL_SYSWMEVENT,SDL_IGNORE); $background = new SDL::Surface(-width => $app->width, -height => $app->height, -depth => 32, -Amask => '0 but true'); #load images foreach ('ship', 'beam1') { $images{$_} = new SDL::Surface(-name => "/home/mirage/perl/space/images/$_.png"); $images{$_}->{-surface} or die "FATAL: Couldn't load image file $_.\n"; } } sub put_image($$$) { my ($image, $x, $y) = @_; my $rect = new SDL::Rect(-width => $image->width, -height => $image->height); my $drect = new SDL::Rect(-width => $image->width, -height => $image->height, -x => $x, -y => $y); $image->blit($rect, $app, $drect); push @update_rects, $drect; } #sub fillrect { # my ($width, $height, $x, $y) = @_; # my $rect = new SDL::Rect(-width => $width, -height => $height, -x => $x, -y => $y); # $app->fill($rect,0x000000); #} sub erase_image_from($$$$$) { my ($width, $height, $x, $y, $img) = @_; my $drect = new SDL::Rect(-width => $width, -height => $height, -x => $x, '-y' => $y); $img->blit($drect, $app, $drect); push @update_rects, $drect; } sub erase_image($$$$) { my ($width, $height, $x, $y) = @_; erase_image_from($width, $height, $x, $y, $background); } sub handle_fire { my ($new, $x, $y) = @_; my $skip = 0; if($new){ push(@fire_items, $x.' '.$y); } my $i = 0; while($i < @fire_items) { my ($xc, $yc) = split(' ',$fire_items[$i]); splice(@fire_items,$i,1) and $skip = 1 unless $xc < $app->width + $images{'beam1'}->width; if($skip){ $skip = 0; next; } &erase_image($images{'beam1'}->width, $images{'beam1'}->height,$xc-10,$yc); &put_image($images{'beam1'}, $xc, $yc); $fire_items[$i]=join(' ',$xc + 10, $yc); $i++; } } &init_sdl; my $x = 50; my $y = ($app->height / 2) - $images{'ship'}->height; my ($xplus, $yplus, $xminus, $yminus, $fire) = 0; while(1) { $event->pump(); if ($event->poll != 0) { if ($event->type == SDL_KEYDOWN) { my $key = $event->key_sym(); $xplus = 1 if $key eq SDLK_RIGHT; $xminus = 1 if $key eq SDLK_LEFT; $yminus = 1 if $key eq SDLK_UP; $yplus = 1 if $key eq SDLK_DOWN; $fire = 1 if $key eq SDLK_SPACE; exit if $key eq SDLK_ESCAPE; } if ($event->type == SDL_KEYUP) { my $key = $event->key_sym(); $xplus = 0 if $key eq SDLK_RIGHT; $xminus = 0 if $key eq SDLK_LEFT; $yminus = 0 if $key eq SDLK_UP; $yplus = 0 if $key eq SDLK_DOWN; $fire = 0 if $key eq SDLK_SPACE; } } #delete if movement if($xplus or $xminus or $yplus or $yminus) { &erase_image($images{'ship'}->width, $images{'ship'}->height,$x,$y); } #change values if key is pressed my $step = 10; $x+=$step if $xplus and $x < ($app->width - $images{'ship'}->width); $x-=$step if $xminus and $x >= $step; $y+=$step if $yplus and $y < ($app->height - $images{'ship'}->height); $y-=$step if $yminus and $y >= $step ; #draw gunshots, possibly add new one &handle_fire($fire, $x, $y); #draw ship &put_image($images{'ship'},$x,$y); $app->update(@update_rects); @update_rects=(); &SDL::DisplayFormat($images{'ship'}->{-surface}); &SDL::Delay(20); } __END__