b0VIM 6.4 FT{ 5 nick nick-laptop ~nick/Projects/perlman/perlman U3210#"! U tp
t w
^ |
} g ! q
x ` x ^ Y ` ad t z y m a ` O F 8 & d W I ; ,
Z
5
} Z < 9 8 ! W
N
3 o R ; $
u ^ G , D } K C B 1 H E 4 232, 16, 0, 1, 1, 0, # 5 114, 14, 0, 1, 1, 232, 16, 0, 1, 1, 0, # 5 114, 14, 0, 1, 1, 232, 16, 0, 1, 1, 0, # 5 232, 16, 0, 1, 1, 0, # 5 114, 14, 0, 1, 1, 1, # 2 14, 16, 0, 1, 0, 1, # 0 my @intersections = ( ## ## ( 498, 552, 1, 0, 1, 0 ) ## ## corner of the screen, you can go up and left: ## directions are available, up, down, left, right. Example, the lower right ## The format of this is the upper left corner coordinate, (x, y) and which ## ## is chasing pacman. ## it reaches an intersection, unless the ghost has a high agression level and ## to determine which way to move. So a ghost will move in one direction until ## When they hit an intersection they will be given which directions they can go ## These intersections are for a method I am trying out with the ghosts ## intersections ); { x => 298, y => 265, color => 'orange' }, { x => 222, y => 265, color => 'cyan' }, { x => 260, y => 265, color => 'pink' }, my @ghostStart = ( { x => 260, y => 207, color => 'red' }, 'apple', 'pear', 'banana' ); my @levelFruits = ( 'cherry', 'strawberry', 'orange', 'pretzel', my %ghostAggressions = ( 'red' => 90, 'cyan' => 70, 'pink' => 50, 'orange' => 30 ); my @ghostColors = ( 'red', 'cyan', 'pink', 'orange' ); # in order of agression my %ghosts; # ghost data my $eattenPellets = 0; my $baseSpeed = 0.3; my $fullscreen = 0; my $directionNext = 0; my $directionOld = $direction; my $direction = $LEFT; my $perlManAnim = 0; my $perlManAnimSpeed = 7; my $perlManSpeed = 0; my $ghostSpeed = 1; my $revdFreeLife = 0; my $freeLife = $FREE_LIFE; my $players = 0; my $lives = 0; my $highScore = 0; my $score = 0; my $redraw_all = 0; my $gameOver = 0; my $playing = 0; #0 Are we playing the game? default to '0' till game starts my $level = 0; # keep track of the level, we default to '0' till the game begins my $pelletOffsetY = 0; my $pelletOffsetX = 13; my $boardOffsetY = 0; my $boardOffsetX = 5; ## End of debug vars my $drawGrid = 1; # draw path grid my $drawIntersections = 1; # draw intersections my $drawWarpGates = 1; # draw the actual gates that warp pacman my $drawWarps = 1; # draw warp collision rectangles my $collisionDebugOn = 1; # Collision data is printed to STDOUT my $numOnly = 1; # this will draw ONLY the number labels and no grey rectangles my $labelRects = 1; # this numerically labels each one my $drawPoints = 1; # this will draw the collision rectangles my $DEBUG = 1; # This will turn off ALL debugging, including the variables below ## Debugging variables ); -size => 1024 -channels => 2, -frequency => 44100, my $mixer = new SDL::Mixer( ); -flags => SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWACCEL, -depth => 32, -height => 600, -width => 800, -title => 'PerlMan', my $app = new SDL::App( my $CHASE = 1; my $PATROL = 0; my $UP_RIGHT = 8; my $DOWN_RIGHT = 7; my $DOWN_LEFT = 6; my $UP_LEFT = 5; my $RIGHT = 4; my $LEFT = 3; my $DOWN = 2; my $UP = 1; my $FREE_LIFE = 200; #should be 10000 my $LIVES = 3; ## Some 'static' variable declarations use SDL::OpenGL; use SDL::TTFont; use SDL::Sound; use SDL::Mixer; use SDL::Event; use SDL::Cursor; use SDL::Surface; use SDL::App; use SDL; ## SDL Libraries use Switch; use strict; =cut =end comment info Version : $Id: .perlman.swp,v 1.1.1.1 2009/03/28 03:35:34 nick Exp $ PerlMan -- PacMan clone written using the Perl::SDL =begin comment info #!/usr/bin/perl -w ad o Y t q o n m l L 3 p T 8
w
h
Y
B
A
q > ; 9 8 ( y ] @ "
i
Y
I
-
} $app->fill ( $rect, $color ); ); -y => $y + $boardOffsetY, -x => $x + $boardOffsetX, -width => 1, -height => 1, my $rect = SDL::Rect->new ( ); -b => 0x00, -g => 0x00, -r => 0xff, my $color = SDL::Color->new ( my ( $x, $y ) = @_; sub drawPixel { } $app->fill ( $rect, $color ); ); -y => $y1 + $boardOffsetY, -x => $x1 + $boardOffsetX, -width => ( $x2 - $x1 ), -height => ( $y2 - $y1 ), my $rect = SDL::Rect->new ( ); -b => 0x00, -g => 0xff, -r => 0x00, my $color = SDL::Color->new ( my ( $x1, $y1, $x2, $y2, $num ) = @_; sub drawRectI { } } $font->print ( $app, $rect->x, $rect->y, $num ); -bg=>$color, -fg=>$fontColor ); my $font = new SDL::TTFont ( -name=>"./fonts/CourierNew-Bold.ttf", -size=>10, ); -b => 0x00, -g => 0x00, -r => 0xff, my $fontColor = new SDL::Color ( ) if ( $numOnly ); -b => 0x00, -g => 0x00, -r => 0x00, $color = new SDL::Color ( $num /= 4; if ( $labelRects ) { $app->fill ( $rect, $color ) if ( ! $numOnly ); ); -y => $y1 + $boardOffsetY, -x => $x1 + $boardOffsetX, -width => ( $x2 - $x1 ), -height => ( $y2 - $y1 ), my $rect = SDL::Rect->new ( ); -b => 0xff, -g => 0xff, -r => 0xff, my $color = SDL::Color->new ( my ( $x1, $y1, $x2, $y2, $num ) = @_; sub drawRect { ############################### #### Temporary fucntions ############################### } } $app->grab_input ( SDL_GRAB_OFF ); SDL::Cursor::show ( undef, 1 ); $fullscreen = 0; else { ad < | @ t 4
w
v
d
a
`
I
~ { h E 9 8 x i d 6 %
B
(
J r o n [ Y X W T 3 i = M # n F C w b 8 x t j g e 9 7 6 3 d ? < } $app->grab_input ( SDL_GRAB_ON ); SDL::Cursor::show ( undef, 0 ); $fullscreen = 1; if ( ! $fullscreen ) { $app->fullscreen (); sub setFullScreen { ## ## Switch between fullscreen and windowed. Take away our mouse cursor in fullscreen ## } return $hit; # returns non-zero for a hit } $hit++; } $collisionDebugOn--; EOF +-------+---------------+---------------+ | Left | $leftA | $leftB | | Right | $rightA | $rightB | | Top | $topA | $topB | | Bottom| $bottomA | $bottomB | +-------+---------------+---------------+ | Wall | PacMan | +---------------+---------------+ Collision with wall $rect at: DirectionNext : $directionNext DirectionOld : $directionOld Direction : $direction print <<EOF; if ( $collisionDebugOn && $DEBUG ) { next if ( $leftA >= $rightB ); next if ( $rightA <= $leftB ); next if ( $topA >= $bottomB ); next if ( $bottomA <= $topB ); my $bottomA = $SDLBoardRects[$rect]->y + $SDLBoardRects[$rect]->height; my $topA = $SDLBoardRects[$rect]->y; my $rightA = $SDLBoardRects[$rect]->x + $SDLBoardRects[$rect]->width; my $leftA = $SDLBoardRects[$rect]->x; for my $rect ( 0 .. $#SDLBoardRects ) { my $bottomB = $object->y + $object->height; my $topB = $object->y; my $rightB = $object->x + $object->width; my $leftB = $object->x; my $hit = 0; my $object = shift; # must be a SDL->Rect sub wallCollision { ### ## Usefull for pacman and the ghosts ## This will tell us if we are about to hit a wall. ## Lets do some wall collisions. ## } return @SDLRects; } push ( @SDLRects, $rect ); ); -y => $gameBoardData[$idx + 1] + $boardOffsetY - 2, -x => $gameBoardData[$idx] + $boardOffsetX - 1, -width => ( $gameBoardData[$idx + 2] - $gameBoardData[$idx] + 3 ), -height => ( $gameBoardData[$idx + 3] - $gameBoardData[$idx + 1] + 4 ), my $rect = SDL::Rect->new ( for ( my $idx = 0; $idx <= $size; $idx += 4 ) { $size--; my @SDLRects = (); my $size = scalar @gameBoardData; sub boardDataToSDLRects { ## Convert our board x,y Data in to SDL rectangles so we don't need to keep redoing this } } ); -y => ( $pelletCords[$idx+1] ),# + $pelletOffsetY ), -x => ( $pelletCords[$idx] ), #+ $pelletOffsetX ), -width => 4, -height => 4, $pellets{$idx}{'rect'} = SDL::Rect->new ( ); -b => 0x97, -g => 0xb8, -r => 0xff, $pellets{$idx}{'color'} = new SDL::Color ( $pellets{$idx}{'active'} = 1; $pellets{$idx}{'points'} = 10; for ( my $idx = 0; $idx <= $pcount; $idx += 2 ) { $pcount--; my $pcount = scalar @pelletCords; sub setupPellets { ## ## locations, and activity ## populate our pellet hash with pellet images, rectangles ## We have a list of pellet coordinates. We want to ## } } &configIntroScreen unless ( defined ( $bgColor ) ); sub drawIntroScreen { } $app->sync ( ); $titleImage->blit ( 0, $app, $titleRect ); $app->fill ( 0, $bgColor ); $app->grab_input ( SDL_GRAB_OFF ); SDL::Cursor::show ( undef, 1 ); # no point in grabbing the mouse... -height=>$titleImage->height ( ), -y=>50, -x=>170 ); $titleRect = new SDL::Rect ( -width=>$titleImage->width ( ), $titleImage = new SDL::Surface ( -name=>'./images/perlman-title.gif' ); $fgColor = new SDL::Color ( -r=>0, -g=>255, -b=>255 ); #yellow $bgColor = new SDL::Color ( -r=>0, -g=>0, -b=>0 ); #black sub configIntroScreen { my ( $bgColor, $fgColor, $titleImage, $titleRect ); { ## ## Handling the opening intro screen ## } } ad x w D q 7 '
d
a
K
.
t s N z < ;
v
a
`
m ` 4 h S R g Z / } h W s p o @ 1 J N w d c # " return 0; sub seePacMan { } return 0; return 1 if ( &wallCollision ( $gRect ) == 0 ); ); -y => $ghosts{$ghost}{'rect'}->y + $changeY, -x => $ghosts{$ghost}{'rect'}->x + $changeX, -width => $ghosts{$ghost}{'rect'}->width, -height => $ghosts{$ghost}{'rect'}->height, my $gRect = SDL::Rect->new ( } case 4 { $changeX += $ghostSpeed; } #right case 3 { $changeX -= $ghostSpeed; } #left case 2 { $changeY += $ghostSpeed; } #down case 1 { $changeY -= $ghostSpeed; } #up switch ( $dir ) { my $changeX = 0; my $changeY = 0; my ( $ghost, $dir ) = @_; sub canMove { # Can we move in the direction we want to go? } # print "$rdir\n"; $ghosts{$ghost}{'direction'} = $rdir; do { $rdir = int rand ( 4 ) + 1; } while ( $rdir != $ghosts{$ghost}{'direction'} & ! &canMove ( $_, $rdir ) ); # print "Random Chase ($ghost): using direction ==> "; my $rdir = 0; my $ghost = shift; sub doRandomChase { } else { return 0; } } return 1; $ghosts{$ghost}{'pacPos'} = $UP; $ghosts{$ghost}{'direction'} = ( $ghosts{$ghost}{'scared'} ) ? $DOWN : $UP; } elsif ( &canMove ( $ghost, $UP ) ) { return 1; $ghosts{$ghost}{'pacPos'} = $DOWN; $ghosts{$ghost}{'direction'} = ( $ghosts{$ghost}{'scared'} ) ? $UP : $DOWN; #pacman is below us if ( ( $ghosts{$ghost}{'rect'}->y <= $perlManRect->y ) && ( &canMove ( $ghost, $DOWN ) ) ) { my $ghost = shift; sub tryVerticleChase { } return 0; } return 1; $ghosts{$ghost}{'pacPos'} = $LEFT; $ghosts{$ghost}{'direction'} = ( $ghosts{$ghost}{'scared'} ) ? $LEFT: $RIGHT; # PacMan is on our right } elsif ( &canMove ( $ghost, $RIGHT ) ) { return 1; $ghosts{$ghost}{'pacPos'} = $RIGHT; $ghosts{$ghost}{'direction'} = ( $ghosts{$ghost}{'scared'} ) ? $RIGHT : $LEFT; # pacman is on our left if ( ( $ghosts{$ghost}{'rect'}->x > $perlManRect->x ) && ( &canMove ( $ghost, $LEFT ) ) ) { my $ghost = shift; sub tryHorizontalChase { } } else { &doRandomChase ( $_ ) if ( &tryVerticleChase ( $_ ) == 0 ); } if ( $dx >= $dy ) { &doRandomChase ( $_ ) if ( &tryHorizontalChase ( $_ ) == 0 ); } my $dy = abs ( $ghosts{$_}{'rect'}->y - $perlManRect->y ); my $dx = abs ( $ghosts{$_}{'rect'}->x - $perlManRect->x ); ## Find PacMan and head towards him $ghosts{$_}{'targetWait'} = 200; next if ( ( $ghosts{$_}{'targetWait'} ) > $ghosts{$_}{'aggression'} ); ## Are we ready for a new target? $ghosts{$_}{'targetWait'} = 0 if ( $ghosts{$_}{'aggression'} > 50 && &seePacMan ( $_ ) ); ## If we are aggressive enough and see pacman, chase him $ghosts{$_}{'targetWait'}--; foreach ( keys %ghosts ) { sub perlManPosition { # # Determine pacman's position from a ghost and set a direction # } } EOF y+w -> $y1 x+h -> $x1 y -> $y x -> $x Corner Where we are going to be Where we were Position of PerlMan on map: print <<EOF; $y1 .= "\t\t\t\t".($pmRect->y + $perlManRect->height); my $y1 = $perlManRect->y + $perlManRect->height; $x1 .= "\t\t\t\t".($pmRect->x + $perlManRect->width); my $x1 = $perlManRect->x + $perlManRect->width; my $y = $perlManRect->y."\t\t\t\t".$pmRect->y; my $x = $perlManRect->x."\t\t\t\t".$pmRect->x; if ( $DEBUG ) { sub positionDebug { } $app->sync(); } $top += $textHeight; $gameOverFont->print ( $app, 150, $top, $m ); ad ` ] ~ a 3
w
-
m I % $ k (
h
7
O
x E v 6 z t G Y p = q 7 x u ? $x = ( 800 - $x ) / 2; my $x = $gameOverFont->width ( 0, $m ); foreach my $m ( @msg ) { my $top = ( 600 - ( ( scalar @msg ) * $textHeight ) ) / 2; my $textHeight = $gameOverFont->height ( $msg[0] ); "Press button to continue" ); my @msg = ( "GAME OVER", "Score: $score", "Level: $level", sub drawGameOver { } } ); -y => $ghosts{$ghostColors[$_]}{'pos'}{'old'}{'Y'} -x => $ghosts{$ghostColors[$_]}{'pos'}{'old'}{'X'}, -height => $ghostImages[$_][1]->height, -width => $ghostImages[$_][1]->width, $ghosts{$ghostColors[$_]}{'rectOld'} = new SDL::Rect ( ); -y => $ghosts{$ghostColors[$_]}{'pos'}{'Y'} -x => $ghosts{$ghostColors[$_]}{'pos'}{'X'}, -height => $ghostImages[$_][1]->height, -width => $ghostImages[$_][1]->width, $ghosts{$ghostColors[$_]}{'rect'} = new SDL::Rect ( $ghostImages[$_][13] = new SDL::Surface ( -name => './images/ghost-scared-2.gif' ); $ghostImages[$_][9] = new SDL::Surface ( -name => './images/ghost-scared-1.gif' ); } $ghostImages[$_][$idx] = new SDL::Surface ( -name => $filen ); my $filen = "./images/ghost-" . $ghostColors[$_] . "-" . $idx . ".gif"; for ( my $idx = 1; $idx <= 8; $idx++ ) { } case 3 { $ghosts{$ghostColors[$_]}{'direction'} = $DOWN; } case 2 { $ghosts{$ghostColors[$_]}{'direction'} = $UP; } case 1 { $ghosts{$ghostColors[$_]}{'direction'} = $UP; } case 0 { $ghosts{$ghostColors[$_]}{'direction'} = $LEFT; } switch ( $_ ) { $ghosts{$ghostColors[$_]}{'aggression'} = $ghostAggressions{$ghostColors[$_]}; $ghosts{$ghostColors[$_]}{'targetWait'} = 0; $ghosts{$ghostColors[$_]}{'target'}{'Y'} = 0; $ghosts{$ghostColors[$_]}{'target'}{'X'} = 0; $ghosts{$ghostColors[$_]}{'pos'}{'old'}{'Y'} = $ghostStart[$_]{y}; $ghosts{$ghostColors[$_]}{'pos'}{'old'}{'X'} = $ghostStart[$_]{x}; $ghosts{$ghostColors[$_]}{'pos'}{'Y'} = $ghostStart[$_]{y}; $ghosts{$ghostColors[$_]}{'pos'}{'X'} = $ghostStart[$_]{x}; $ghosts{$ghostColors[$_]}{'mode'} = $PATROL; $ghosts{$ghostColors[$_]}{'pacPos'} = $DOWN_LEFT; $ghosts{$ghostColors[$_]}{'scared'} = 0; $ghosts{$ghostColors[$_]}{'state'} = 0; $ghosts{$ghostColors[$_]}{'speed'} = 1; foreach ( 0 .. $#ghostColors ) { # which I have yet to learn how to do. # animation state, location, and whatever we need for the AI # We have four ghosts. We need to assign each ghost a graphic, sub setupGhosts { } return 0; } } return $pellets{$_}{'rect'}; $eattenPellets++; $pellets{$_}{'active'} = 0; $score += $pellets{$_}{'points'}; next if ( $leftA >= $rightB ); next if ( $rightA <= $leftB ); next if ( $topA >= $bottomB ); next if ( $bottomA <= $topB ); my $bottomA = $pellets{$_}{'rect'}->y + $pellets{$_}{'rect'}->height; my $topA = $pellets{$_}{'rect'}->y; my $rightA = $pellets{$_}{'rect'}->x + $pellets{$_}{'rect'}->width; my $leftA = $pellets{$_}{'rect'}->x; if ( $pellets{$_}{'active'} ) { foreach ( keys %pellets ) { my $bottomB = $object->y + $object->height; my $topB = $object->y; my $rightB = $object->x + $object->width; my $leftB = $object->x; my $object = shift; # must be a SDL->Rect sub pelletCollision { } &updateScores (); $smallTitleImage->blit ( 0, $app, $smallTitleRect ); -height=>$smallTitleImage->height(), -y=>4, -x=>550 ); my $smallTitleRect = new SDL::Rect ( -width=>$smallTitleImage->width(), my $smallTitleImage = new SDL::Surface ( -name=>'./images/perlman-title-small.png' ); ad C o E A > = & W
g
S
?
>
] X W 6 z x L
n
h
<
8
5
4
N ; ( '
\ 4 ~ Y T S ( j ] Y P
j f ? x U Q N M I ! n > o n sub drawStats () { ## ## Display high score, initial score, pacman lives, and level fruits ## } $gameBoardImage->blit ( 0, $app, $gameBoardRect ); -y=>$boardOffsetY, -x=>$boardOffsetX ); -height=>$gameBoardImage->height(), my $gameBoardRect = new SDL::Rect ( -width=>$gameBoardImage->width(), my $gameBoardImage = new SDL::Surface ( -name=>'./images/gameboard.png' ); sub drawGameBoard () { ## ## Display our blue game board borders ## } } if ( $pellets{$_}{'active'} ); $app->fill ( $pellets{$_}{'rect'}, $pellets{$_}{'color'} ) foreach ( keys %pellets ) { sub drawPellets () { ## ## Draw Pellets ## } $perlManAnim++; $PMSD = 1 if ( $perlManState < 2 ); $PMSD = -1 if ( $perlManState > 3 ); } $perlManAnim = 0; $perlManState += $PMSD; if ( $perlManAnim > $perlManAnimSpeed ) { sub updatePerlManState () { ## Animiation state } } return 0; $directionNext = ( $dir != $directionOld ) ? $directionOld : 0; else { } return 1; $directionOld = $dir if ( $dir != $directionOld ); $perlManPosX += $changeX; $perlManPosY += $changeY; $perlManPosOldX = $perlManPosX; $perlManPosOldY = $perlManPosY; if ( &wallCollision ( $pmRect ) == 0 ) { ); -y => $perlManRect->y + $changeY, -x => $perlManRect->x + $changeX, -width => $perlManRect->width, -height => $perlManRect->height, $pmRect = SDL::Rect->new ( } case 4 { $changeX += $speed; } #right case 3 { $changeX -= $speed; } #left case 2 { $changeY += $speed; } #down case 1 { $changeY -= $speed; } #up switch ( $dir ) { $scnt = 0 if ( $scnt >= $sleep ); $scnt++; } return 0; $scnt++; if ( $scnt < $sleep ) { my $changeY = 0; my $changeX = 0; my $sleep = 1; # wait delay to move pacman (decrease to increase speed) my $speed = 2; # number of pixels to move pacman my $dir = ( $directionNext != 0 ) ? $directionNext : shift; sub updatePerlManDirection () { } } else { $ghosts{$_}{'targetWait'} = 0; } } $ghosts{$_}{'pos'}{'X'} += $changeX; $ghosts{$_}{'pos'}{'Y'} += $changeY; $ghosts{$_}{'pos'}{'old'}{'X'} = $ghosts{$_}{'pos'}{'X'}; $ghosts{$_}{'pos'}{'old'}{'Y'} = $ghosts{$_}{'pos'}{'Y'}; if ( &wallCollision ( $gRect ) == 0 ) { ); -y => $ghosts{$_}{'rect'}->y + $changeY, -x => $ghosts{$_}{'rect'}->x + $changeX, -width => $ghosts{$_}{'rect'}->width, -height => $ghosts{$_}{'rect'}->height, my $gRect = SDL::Rect->new ( } case 4 { $changeX += $ghostSpeed; } #right case 3 { $changeX -= $ghostSpeed; } #left case 2 { $changeY += $ghostSpeed; } #down case 1 { $changeY -= $ghostSpeed; } #up switch ( $ghosts{$_}{'direction'} ) { my $changeX = 0; my $changeY = 0; foreach ( keys %ghosts ) { ## Move ghost towards target &perlManPosition (); ## Determine where to move ghost # my $speed = 1; sub updateGhostDirection () { } } $rectData[$idx + 2], $rectData[$idx + 3 ], $idx ); &drawRect ( $rectData[$idx], $rectData[$idx + 1], for ( my $idx = 0; $idx <= $size; $idx += 4 ) { # Rectangles $size--; my $size = scalar @rectData; my @rectData = @$ref; my $ref = shift; sub drawBoardPoints { } } $intersections[$idx] + 1, $intersections[$idx + 1] + 1, $idx ); &drawRectI ( $intersections[$idx], $intersections[$idx + 1], for ( my $idx = 0; $idx <= $size; $idx += 6 ) { ad ! z f b a \ u e E
{
w
Z
m i F B
0
[ 1 r y u Z k U 9 U T = ) % $ # y j [ V U 2 # x w * u t e # Rectangles $size--; my $size = scalar @intersections; sub drawIntersections { } $app->sync(); $font->print ( $app, 600, 300, $score); -bg=>$rectColor, -fg=>$fontColor ); $font = new SDL::TTFont ( -name=>"./fonts/CourierNew-Bold.ttf", -size=>16, $app->fill ( $rect, $rectColor ); ); -width => 100, -height => 26, -y => 300, -x => 600, my $rect = new SDL::Rect ( ); -b => 0x00, -g => 0x00, -r => 0x00, my $rectColor = new SDL::Color ( ); -b => 0xff, -g => 0xff, -r => 0xff, $fontColor = new SDL::Color ( my ( $fontColor, $font ); sub updateScores { } $app->update ( @modified_areas ); # # Blink power pellets # } &updateScores(); # update the scores $mixer->play_channel ( 1, $sndMunch, 0 ); # Play the munch sound push ( @modified_areas, $rect ); $app->fill ( $rect, $color ); ); -b => 0x00, -g => 0x00, -r => 0x00, my $color = new SDL::Color ( # we ate a pellet! Yum! if ( $rect != 0 ) { my $rect = &pelletCollision ( $perlManRect ); # # Did we eat a pellet? # &updatePerlManState(); } &updatePerlManDirection ( $direction ); } else { $directionNext = 0 if ( &updatePerlManDirection( $directionNext ) ); if ( $directionNext ) { # # Check direction and update # push ( @modified_areas, $perlManRect ); else { $perlManImages[$direction][$perlManState]->blit ( 0, $app, $perlManRect ); } if ( $perlManState == 1 ) { $perlManImages[0]->blit ( 0, $app, $perlManRect ); } $perlManRect->y ( $perlManPosY ); $perlManRect->x ( $perlManPosX ); # # Draw new Pacman # push ( @modified_areas, $perlManRectOld ); $app->fill ( $perlManRectOld, $bgColor ); $perlManRectOld->y ( $perlManPosOldY ); $perlManRectOld->x ( $perlManPosOldX ); # # Erase Old Pacman # &updateGhostDirection ( ); # # Determine where to move ghosts # } push ( @modified_areas, $ghosts{$ghostColors[$_]}{'rect'} ); $ghostImages[$_][$ghostImg]->blit ( 0, $app, $ghosts{$ghostColors[$_]}{'rect'} ); $ghosts{$ghostColors[$_]}{'state'} = ( $ghosts{$ghostColors[$_]}{'state'} == 4 ) ? 0 : 4; my $ghostImg = ( $ghosts{$ghostColors[$_]}{'scared'} ) ? ( 9 + $ghosts{$ghostColors[$_]}{'state'} ) : ( $ghosts{$ghostColors[$_]}{'direction'} + $ghosts{$ghostColors[$_]}{'state'} ); $ghosts{$ghostColors[$_]}{'rect'}->y ( $ghosts{$ghostColors[$_]}{'pos'}{'Y'} ); $ghosts{$ghostColors[$_]}{'rect'}->x ( $ghosts{$ghostColors[$_]}{'pos'}{'X'} ); foreach ( 0 .. $#ghostColors ) { # # draw new ghosts ###REMOVE $app->fill ( $ghosts{ $app->fill ( $ghosts{$_}{'rectOld'}, $bgColor ); $ghosts{$_}{'rectOld'}->y ( $ghosts{$_}{'pos'}{'old'}{'Y'} ); $ghosts{$_}{'rectOld'}->x ( $ghosts{$_}{'pos'}{'old'}{'X'} ); foreach ( @ghostColors ) { # # Erase old Ghosts # # } # } # } # push ( @modified_areas, $pellets{$_}{'rect'} ); # $app->fill ( $pellets{$_}{'rect'}, $pellets{$_}{'color'} ); # if ( $pellets{$_}{'active'} ) { # foreach ( keys %pellets ) { # $ptick = 0; # if ( $ptick >= 10 ) { # $ptick++; # # refresh pellets every 10th tick # my @modified_areas = (); # # redraw the pellets the ghosts go over. # We always need to modify ghosts, pacman, power pellets (blinking) and # } $redraw_all = 0; $app->sync (); &drawBoardPoints ( \@warpZoneData ) if ( $drawWarpGates && $DEBUG ); &drawGrid if ( $drawGrid && $DEBUG ); $# ad ! } p \ L I G F $ _
k
M
s p n m R Q O N K { /
|
{
v
K
F
/
y x u t \ ' { z ^ I 4 ! d b N M 7 % $ h / y B u [ U p o l k U > \ ! &drawGrid if ( @d &drawIntersections if ( $drawIntersections && $DEBUG ); &drawBoardPoints ( \@warpZones ) if ( $drawWarps && $DEBUG ); &drawBoardPoints ( \@gameBoardData ) if ( $drawPoints && $DEBUG ); &drawPellets (); &drawStats (); &drawGameBoard (); $app->fill ( 0, $bgColor ); if ( $redraw_all ) { sub drawGameScreen { } $sndMunch = new SDL::Sound ( './sounds/munch A+B.wav' ); ## Load up the music } } $perlManImages[$dir][$idx] = new SDL::Surface ( -name=>$filename ); my $filename = "./images/perlman" . $idx . "" . $d . ".gif"; } case 4 { $d = 'r'; } case 3 { $d = 'l'; } case 2 { $d = 'd'; } case 1 { $d = 'u'; } switch ( $dir ) { my $d; for ( my $idx = 2; $idx <= 4; $idx++ ) { for ( my $dir = 1; $dir <= 4; $dir++ ) { -y=>$perlManPosOldY, -x=>$perlManPosOldX ); -height=>$perlManImages[0]->height (), $perlManRectOld = new SDL::Rect ( -width=>$perlManImages[0]->width (), -y=>$perlManPosY, -x=>$perlManPosX ); -height=>$perlManImages[0]->height (), $perlManRect = new SDL::Rect ( -width=>$perlManImages[0]->width (), $perlManImages[0] = new SDL::Surface ( -name=>'./images/perlman1.gif' ); ## Load up all our perlMan images &setupGhosts (); ## Configure ghosts &setupPellets (); $perlManPosY = $perlManPosOldY = 436; $perlManPosX = $perlManPosOldX = 358; $perlManPosY = $perlManPosOldY = 436; $perlManPosX = $perlManPosOldX = 258; $direction = $LEFT; $scnt = 0; $PMSD = 1; $perlManState = 1; ## Some starting defaults -bg=>$bgColor, -fg=>$fgColor ); $gameOverFont = new SDL::TTFont ( -name=>"./fonts/crackman.ttf", -size=>20, $fgColor = new SDL::Color ( -r=>0, -g=>255, -b=>255 ); $bgColor = new SDL::Color ( -r=>0, -g=>0, -b=>0 ); sub configGameScreen { } return $nextHeartbeat; &drawGameScreen (); my $nextHeartbeat = 5; ## Will eventually speed the game up as you go on } return 500; &drawGameOver ( ); $gameOver = 1; if ( $lives <= 0 ) { ## ## Game over if player has no more lives ## &configGameScreen unless ( $bgColor ); sub updateGameState { my ( @ghostImages ); ## All ghost information is stored here. my ( $scnt, $pmRect, $sndMunch, $ptick ); my ( $perlManPosX, $perlManPosY, $perlManPosOldX, $perlManPosOldY, $PMSD); my ( @perlManImages, @perlManRects, $perlManState, $nextHeartbeat ); my ( $bgColor, $perlManRect, $perlManRectOld, $fgColor, $gameOverFont, $textHeight ); { ## ## Handling the game state (playing the game) ## } sub processEventGameOver { } } case 'g' { $lives = 0; } } } $ghosts{$_}{'scared'} = ( $ghosts{$_}{'scared'} ) ? 0 : 1; case "s" { foreach ( keys %ghosts ) { } $collisionDebugOn = 1; print "Waiting for collision...\n"; } case "c" { if ( $DEBUG ) { case "p" { &positionDebug ( ) if $DEBUG } case "right" { $directionOld = $direction; $direction = $RIGHT; } case "left" { $directionOld = $direction; $direction = $LEFT; } case "down" { $directionOld = $direction; $direction = $DOWN; } case "up" { $directionOld = $direction; $direction = $UP; } case 'f' { &setFullScreen (); } switch ( $keyName ) { my $keyName = $event->key_name (); $directionNext = 0; my $event = shift; sub processEventPlayingKeypress { } } $players = 2; $lives = $LIVES; $score = 0; $redraw_all = 1; $actions = $actions_playing; $gameOver = 0; $level = 1; $playing = 1; if ( $key_name eq '2' ) { ad G t [ B ) ( o T 9
^
E
*
u 1 v 7
[
p " I E ( t s p @ = / . k j J I r =
~ n ] I * x w Q 6 } n Z J G F } $players = 1; $lives = $LIVES; $score = 0; $redraw_all = 1; $actions = $actions_playing; $gameOver = 0; $level = 1; $playing = 1; $key_name eq '1' ) { if ( $key_name eq 'return' || } &setFullScreen ( ); if ( $key_name eq 'f' ) { my $key_name = $event->key_name ( ); my $event = shift; sub processEventIntroScreenKeypress { } return 50; } return 500; &drawIntroScreen (); } else { } return 500; &drawPauseScreen (); } else { return &updateGameState (); if ( $playing ) { if ( $level ) { sub heartbeat { } $app->delay ( 5 ); } } $next_heartbeat = $app->ticks + $n; my $n = &heartbeat () || 50; if ( $app->ticks >= $next_heartbeat ) { } } $actions->{$type}->($event); ref ( $actions->{$type} ) eq "CODE" ) { if ( exists ( $actions->{$type} ) &&