/* Program: Space Invaders Version: 0.00a Author : Mayukh Bose E-Mail: mayukh@earthlink.net Written On : 03/16/97 Source Code Released: 10/11/97 For educational purposes or amusement only. This program is *copylefted* software. Released to the public under the GNU General Public License. Contact the Free Software Foundation at: Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA or visit: http://www.gnu.ai.mit.edu/copyleft/gpl.html for details. Have fun!!!! */ import java.awt.Graphics; import java.awt.Font; import java.awt.Color; import java.awt.Image; import java.awt.Event; import java.awt.FontMetrics; public class Space extends java.applet.Applet implements Runnable { /* Declare all the constants in here */ final int rows = 5; // number of alien rows final int cols = 10; // number of alien columns final int left = 15; // num of units to move ship to left final int right = 15; // num of units to move ship to right final int up = 15; // num of units to move up final int down = 15; // num of units to move down final int DIE_SCUM = -1; // used to indicate that an alien was hit final int OUCH = -1; // used to indicate that the ship was hit /* Declare all the variables here */ Thread game; // Used for the main thread Image OffImg; // Used for double buffering the graphics Graphics OffG; // Used for double buffering the graphics Font statusmsg = new Font ("TimesRoman",Font.BOLD, 12); int dx,dy; // used to control moving the alien int xcount,ycount; // keep track of the alien int index; int maxwidth, maxheight; // used to keep track of screen coordinates int numaliens; // Max # of aliens int score; // used to keep the score int lives; // used for lives boolean moverows; // used to indicate when to move the rows down by 1 level Alien[] alien = new Alien[50]; // declare 50 aliens Ship ship; // this is our ship Shot shot; // this is our shot Shot enemy_shot; // this is the enemy's shot // Declare all the routines here // Initialization routine public void init() { maxwidth = size().width; maxheight = size().height; // now get the double buffer initialised OffImg = createImage(maxwidth,maxheight); OffG = OffImg.getGraphics(); // next set up the ship ship = new Ship(maxwidth/2, maxheight - 50); shot = new Shot(maxwidth/2, maxheight - 50,0,maxheight,-15); enemy_shot = new Shot(maxwidth/2, 0,0,maxheight,5); //init the enemy shot setup_data(); // setup other data // all set now! Let's rock } public void setup_data() { int x_pt, y_pt; Alien tempalien; // initially set up all 50 aliens for (ycount=0;ycount= (maxwidth - 30))) moverows = true; // indicate that the row should go down // now check if alien can shoot and if alien has collided with the ship if ((alien[index].x >= ship.x) && (alien[index].x <= ship.x+20)) { if (!enemy_shot.active) if (alien[index].y < maxheight-120) // don't shoot if real low enemy_shot.set(alien[index].x+10, alien[index].y+10); if ((alien[index].y >= ship.y-10)&&(alien[index].y <= ship.y+15)) message(1,g); // died } if (alien[index].y >= maxheight-50) { // If they have reached earth lives = 0; message(3,g); // end of game } } } } if (dy > 0) dy = 0; // if all rows have moved, then reset the variable if (moverows) { dx = -dx; /* reverse the direction */ dy = 10; /* move rows down by one */ moverows = false; /* reset the variable */ } if (shot.active) shot.move(); // move the shot if (enemy_shot.active) enemy_shot.move(); // move enemy shot ship.draw(OffG); // draw the ship if (shot.active) shot.draw(OffG); // draw the bullet if (enemy_shot.active) enemy_shot.draw(OffG); // draw the enemy shot OffG.setFont(statusmsg); // show the status mesg in default font OffG.drawString ("Score : " + score + " Lives : " + lives,0,maxheight-10); g.drawImage(OffImg,0,0,this); // finally display the buffer } // Event handler for the key strokes public boolean keyDown(Event ev, int key) { switch (key) { case Event.LEFT: ship.x -= left; if (ship.x < 0) ship.x = 0; break; case Event.RIGHT: ship.x += right; if (ship.x > (maxwidth-20)) ship.x = (maxwidth-20); break; case Event.UP: ship.y -= up; if (ship.y < 20) ship.y = 20; break; case Event.DOWN: ship.y += down; if (ship.y > (maxheight - 50)) ship.y = maxheight - 50; break; default: if ((char)key == ' ') { if (!shot.active) { shot.set (ship.x+10, ship.y); // activate the shot } } break; } return true; } void message(int msg, Graphics gr) { Font msgFont = new Font("TimesRoman",Font.BOLD,32); FontMetrics fm = getFontMetrics(msgFont); String mesg; gr.drawImage(OffImg,0,0,this); // redraw the image one final time gr.setFont(msgFont); switch (msg) { case 1: mesg = "OUCH!!!!!!!!!! That hurts!"; break; case 2: mesg = "Yay! I just saved the earth."; break; case 3: mesg = "Uh oh! There goes the planet!"; break; default: mesg = "Damn! I've got a wild pointer somewhere?"; break; } gr.drawString (mesg,(maxwidth-fm.stringWidth(mesg))/2 , maxheight/2); play(getCodeBase(), "that.hurts.au"); // play a sound mesg = "Please wait while game restarts...."; gr.drawString (mesg,(maxwidth-fm.stringWidth(mesg))/2 , maxheight/2 + 40); try { Thread.sleep (5000); // sleep for 5 seconds } catch(InterruptedException e) { } // default exception handler ship.x = maxwidth/2; ship.y = maxheight-50; setup_data(); /* restart the game */ } } // Class to handle the alien !! class Alien { int x,y; /* used to hold the x,y coordinates of the alien */ boolean dead; /* used to tell you if the alien is dead or alive */ Alien(int x_coord, int y_coord) { // default constructor x = x_coord; y = y_coord; dead = false; // initially the alien is alive! } void move(int dx, int dy) { // update the coordinates of the alien x += dx; y += dy; } void draw(Graphics g) { g.setColor(Color.yellow); g.fillOval(x,y,20,10); g.drawLine(x+10,y+5,x,y+10); g.drawLine(x+10,y+5,x+20,y+10); } int checkHit(int shot_x, int shot_y) { if (!dead) { if (((shot_x >= x) && (shot_x <= (x + 20))) && ((shot_y >= y) && (shot_y + 5 <= (y + 15)))) { dead = true; // This alien is dead! return (-1); // flag that this was hit } } return (0); } } // class to handle the ship class Ship { int x,y; Ship(int x_coord, int y_coord) { // default constructor x = x_coord; y = y_coord; } void draw(Graphics g) { g.setColor (Color.green); g.drawLine (x+10,y,x+10,y+3); g.drawLine (x+10,y+3,x,y+10); g.drawLine (x+10,y+3,x+20,y+10); g.drawLine (x+20,y+10,x,y+10); } int checkHit(int shot_x, int shot_y) { if (((shot_x >= x) && (shot_x <= (x + 20))) && ((shot_y >= y) && (shot_y <= (y + 15)))) return (-1); // flag that this was hit else return (0); } } class Shot { int x, y; int miny,maxy; int dy; boolean active; Shot(int x_coord, int y_coord, int y_min, int y_max, int inc) {// default constructor x = x_coord; y = y_coord; miny = y_min; maxy = y_max; dy = inc; active = false; // initially the shot is not on } void set(int x_coord, int y_coord) { x = x_coord; y = y_coord; active = true; } void move() { y += dy; if ((y < miny + 5)||(y > maxy-10)) active = false; } void draw(Graphics g) { g.drawLine (x,y,x,y+5); } }