#!/usr/bin/perl -w # Astral Trespassers # An example using the Ming library to generate a # complete SWF application use strict; # Import all of the Ming modules, since we'll end up using most of them. use SWF qw(:ALL); # This script uses some Flash 5 ActionScript. SWF::useSWFVersion(5); # Set the scale. 20 is the default, which means that # all scalar values representing coordinates or dimensions will # be indicated in twips (1/20th of a pixel). SWF::setScale(20); # Step 1: create the shapes that make up the Sprites. # The player's gun consists of two red rectangles. The origin of the # gun will be centered on the barrel. my $s = new SWF::Shape(); $s->setLeftFill($s->addFill(255, 0, 0)); # Red # The drawRect() fuction is defined at the end of this script. # It adds a rectangular path to the shape. The arguments are # shape, width, height, dx, dy. The upper left-hand corner of the # rectangle is draw shifted by (dx, dy) from the origin of the shape. drawRect($s, 10, 10, -5, 0); drawRect($s, 40, 10, -20, 10); # An Alien. The origin of each alien is centered between its legs. my $s2 = new SWF::Shape(); $s2->setLeftFill($s2->addFill(0, 0, 255)); # Blue drawRect($s2, 20, 15, -10, -15); # The body drawRect($s2, 5, 5, -10, 0); # Left leg drawRect($s2, 5, 5, 5, 0); # Right leg drawRect($s2, 3, 5, -5, -10); # Left eye drawRect($s2, 3, 5, 2, -10); # Right eye # An alien Sprite will consist of two frames to simulate the # movement of its legs. my $s3 = new SWF::Shape(); $s3->setLeftFill($s3->addFill(0, 0, 255)); # Blue drawRect($s3, 20, 15, -10, -15); # Body drawRect($s3, 5, 5, -7, 0); # Left leg drawRect($s3, 5, 5, 2, 0); # Right leg drawRect($s3, 3, 5, -5, -10); # Left eye drawRect($s3, 3, 5, 2, -10); # Right eye # A Photon Bullet. A simple white rectangle. my $s4 = new SWF::Shape(); $s4->setLeftFill($s4->addFill(255, 255, 255)); drawRect($s4, 5, 10, -3, -10); # A button of the same dimensions as the final movie collects # the player's mouse clicks. This shape will define the bounds of the button. my $s5 = new SWF::Shape(); $s5->setRightFill($s5->addFill(0, 0, 0)); drawRect($s5, 400, 400, 0, 0); # Step 2. Create the individual sprites/movie clips # The player's gun. This Sprite is one frame long. my $gun = new SWF::Sprite(); $gun->add($s); $gun->nextFrame(); # An Alien. An alien is an animated Sprite with four frames; # Two with shape $s2 and two with shape $s3. The $item object # is of type SWF::DisplayItem, returned when the sprite is added # to the movie clip's timeline. my $alien = new SWF::Sprite(); my $item = $alien->add($s2); $alien->nextFrame(); $alien->nextFrame(); $alien->remove($item); $alien->add($s3); $alien->nextFrame(); $alien->nextFrame(); # A photon bullet. A single-frame Sprite. my $bullet = new SWF::Sprite(); $bullet->add($s4); $bullet->nextFrame(); # Create the TextField object that will be used for the # "Game Over" message. Note that font definition file called # astralfont.fdb must be in the same directory as this script. my $f = new SWF::Font("astralfont.fdb"); my $tf = new SWF::TextField(); $tf->setFont($f); $tf->setColor(255,255,255); # white $tf->setName("message"); $tf->setHeight(50); $tf->setBounds(300,50); # Step 3. Create the Movie object representing the main timeline. my $m = new SWF::Movie; $m->setDimension(400, 400); $m->setBackground(0, 0, 0); $m->setRate(16); # Frames per second. Faster rates # will be unplayable on fast machines. # Assemble the frames of the movie timeline. # Frame 1. Initialize variables. # The first frame is a keyframe that initializes two variables. # The direction array keeps track of whether each alien # is moving left (-1), right (1), or not moving (0, after it has # been shot). onScreenBullet is a boolean inidcating whether the # bullet is on the screen. $m->add(new SWF::Action(<nextFrame(); # Frame 2. Add the Sprites to the Stage. # First we add the button that acts as a 'hot spot' for collecting # mouse clicks. The user must click in the area defined by the # shape $s5. Note that the first click will get the button's focus, and # subsequent clicks will fire bullets. my $b = new SWF::Button(); $b->addShape($s5, SWF::Button::SWFBUTTON_HIT); # Add Actionscript that is activated when the mouse button is pressed. $b->addAction(new SWF::Action(<add($b); # Add the button to the Stage $item = $m->add($tf); # Add the "Game Over" text field # Initially it will be empty $item->moveTo(75, 100); $item = $m->add($gun); # Add the gun to the Gtage $item->setName("gun"); # Label the gun for use in later Actionscripts $item->moveTo(200, 380); # Position the gun at the bottom of the screen # Add a phalanx of aliens foreach my $row (1..5) { foreach my $col (1..8) { $item = $m->add($alien); # Add alien $item->moveTo(40*$col, 40*$row); # Position alien $item->setName("alien". # Label alien (e.g. 'alien1') (($row-1)*8+$col-1)); } } # Add an offscreen bullet $item = $m->add($bullet); # Add bullet to stage $item->moveTo(-10, -10); # Position it off screen $item->setName("bullet"); # Label it $m->nextFrame(); # Frame 3. Add Actionscript for event loop. # The movement of the gun, aliens, and bullet are all controlled # by the following bit of Actionscript that is executed every # time Frame 3 is executed. $m->add(new SWF::Action(< 0) && (xPos < 400)) { _root["gun"]._x += dx; } /* Move each of the aliens */ for (i=0; i<40; i++) { /* If an alien reaches the bottom, end the game */ if (_root["alien"+i]._y > 380) { message = "Game Over"; stop(); } /* If an alien hits one of the margins, reverse direction */ if (_root["alien"+i]._x > 380) { direction[i] = -1; _root["alien"+i]._y += 20; } if (_root["alien"+i]._x < 20) { direction[i] = 1; _root["alien"+i]._y += 20; } /* Move the alien */ _root["alien"+i]._x += direction[i] * 5; /* Check to see if the bullet has collided with the alien */ if (onScreenBullet & _root["bullet"].hitTest(_root["alien"+i])) { /* If so, move the bullet and alien off screen */ _root["bullet"]._y = -10; _root["alien"+i]._y = -10; onScreenBullet = 0; direction[i] = 0; } } /* If the bullet is on the screen, move it upward. */ if (onScreenBullet) { _root["bullet"]._y -= 10; if (_root["bullet"]._y < 0) { onScreenBullet = 0; } } ENDSCRIPT )); # Frame 4. Create the event loop by looping Frame 3. $m->nextFrame(); $m->add(new SWF::Action(<nextFrame(); # Write to a file. $m->save("astral_trespassers.swf"); exit(); # drawRect() is a helper procedure used to draw rectangles # a shape. sub drawRect { my $shape = shift; my ($w, $h, $dx, $dy) = @_; $shape->movePenTo($dx, $dy); $shape->drawLine($w, 0); $shape->drawLine(0, $h); $shape->drawLine(-$w, 0); $shape->drawLine(0, -$h); }