// Warp // By Karl Hornell, June 10, 1996 // Last modified June 27 import java.awt.*; import java.awt.image.*; import java.applet.AudioClip; import java.net.*; import java.awt.Font; import java.util.Random; public final class Anirak extends java.applet.Applet implements Runnable { int runMode; // Detemines if we are playing the game or waiting or dying, etc. int level = 0; int lives = 0; Image offImage; // This is where we draw the graphics. Graphics offGraphics; // Also used for drawing double-buffered graphics Thread updateThread; // Thread in which the game runs. long startTime; // Used to keep track of timing so the game doesn't run too fast long score= 0; public void init() { resize(MAX_X,600); getMainGraphics(); random = new Random(System.currentTimeMillis()); System.gc(); //Main fighter yPos = 520; xPos = (500 - 64) / 2; // formation fighters initializeFormation(); setBackground(Color.black); offImage=createImage(MAX_X,600); offGraphics=offImage.getGraphics(); initializeStars(); requestFocus(); } public void getMainGraphics() // Load and process the most common graphics { MediaTracker tracker; int i = 0; tracker = new MediaTracker(this); title = getImage(getCodeBase(), "title.gif"); tracker.addImage(title, i); i++; for (int type = 0; type < numGoodShipTypes; type++) { ship[type] = getImage(getCodeBase(), "newship"+type+".gif"); tracker.addImage(ship[type], i); i++; } for (int type = 0; type < numShipTypes; type++) { for (int anim = 0; anim < numShipAnims; anim++) { fighterImages[type][anim] = getImage(getCodeBase(), "fighter" + type + "_" + anim + ".gif"); tracker.addImage(fighterImages[type][anim], i++); } } try { tracker.waitForAll(); } catch (InterruptedException e) { } } public void drawObjects() // Draw each object onto offImage { } public void run() { while (updateThread != null) { try { long sleepTime = Math.max(startTime - System.currentTimeMillis(), 20); // System.out.println(sleepTime); updateThread.sleep(sleepTime); } catch (InterruptedException e) { } startTime = System.currentTimeMillis() + 40; // Drawing stuff offGraphics.clearRect(0, 0, MAX_X, 600); offGraphics.setColor(Color.gray); offGraphics.drawRect(0, 0, MAX_X-2, 598); // stars processStars(); switch (runMode) { case GAME_OVER : offGraphics.drawImage(title, 70, 70, this); offGraphics.setColor(Color.yellow); offGraphics.drawString("A GAME BY JOHN AND X5K MaStEr X5K", 145, 200); offGraphics.drawString("Use the arrow keys to move.", 175, 360); offGraphics.drawString("Use the space bar to fire.", 182, 380); offGraphics.drawString("Press the space bar to begin.", 173, 420); offGraphics.setColor(Color.yellow); offGraphics.drawString("Score: " + score, 20, 20); offGraphics.drawString("Level: " + level, 425, 20); offGraphics.setColor(Color.green); offGraphics.fillRect(350, 560, hitpoints, 10); offGraphics.setColor(Color.yellow); offGraphics.drawRect(350, 560, 100, 10); break; case FORMATION_WAVE : // Main ship processMainShip(); // Glob Fighter processFormation(); // Shots processShots(); processEnemyShots(); // Hits processHits(); offGraphics.setColor(Color.yellow); offGraphics.drawString("Score: " + score, 20, 20); offGraphics.drawString("Level: " + level, 425, 20); offGraphics.setColor(Color.green); offGraphics.fillRect(350, 560, hitpoints, 10); offGraphics.setColor(Color.yellow); offGraphics.drawRect(350, 560, 100, 10); for (int i = 0; i < lives -1; i++) { offGraphics.drawImage(ship[0],20 + i*35,555,this); } break; case END_GAME : countdown--; if (countdown <= 0) runMode = GAME_OVER; // Glob Fighter processFormation(); // Shots processShots(); processEnemyShots(); // Hits processHits(); offGraphics.setColor(Color.yellow); offGraphics.drawString("Score: " + score, 20, 20); offGraphics.drawString("Level: " + level, 425, 20); offGraphics.setColor(Color.green); offGraphics.fillRect(350, 560, hitpoints, 10); offGraphics.setColor(Color.yellow); offGraphics.drawRect(350, 560, 100, 10); for (int i = 0; i < lives -1; i++) { offGraphics.drawImage(ship[0],20 + i*35,550,this); } break; } // // Presentation loop //break; //case 2: // Main game loop //drawObjects(); //case 3: // Prepare for playing, clear screen slowly //break; //case 4: // Finish level //break; //case 5: // Clear up and start again, possibly on new level //break; //case 6: // Game over message //break; //case 7: // Scroll in highscore table //break; //default: //break; //} repaint(); } } public void start() { if (updateThread==null) { updateThread=new Thread(this,"Game"); updateThread.start(); startTime=System.currentTimeMillis(); } } public void stop() { if ((updateThread!=null)&&(updateThread.isAlive())) { updateThread.stop(); } updateThread=null; } public boolean keyDown(java.awt.Event e, int key) { System.out.println(key); switch (runMode) { case GAME_OVER : if (key == 32 && countdown <= 0) { initializeGame(); return false; } break; case FORMATION_WAVE : if (key == 106 || key == 1006) { dx = -7; return false; } if (key == 108 || key == 1007) { dx = 7; return false; } if (key == 1004) { dy = -7; return false; } if (key == 1005) { dy = 7; return false; } if (key == 32 || key == 109) { firing = true; return false; } ///////////////// player 2 if (key == 115) { dx2 = -7; return false; } if (key == 102) { dx2 = 7; return false; } if (key == 101) { dy2 = -7; return false; } if (key == 100) { dy2 = 7; return false; } if (key == 97) { firing2 = true; return false; } break; default: } return false; } public boolean keyUp(java.awt.Event e, int key) { if (key == 106 || key == 1006 || key == 1007 || key == 108) { dx = 0; return false; } if (key == 1004 || key == 1005) { dy = 0; return false; } if (key == 32 || key == 109) { firing = false; return false; } ///// if (key == 115) { dx2 = 0; return false; } if (key == 102) { dx2 = 0; return false; } if (key == 101) { dy2 = 0; return false; } if (key == 100) { dy2 = 0; return false; } if (key == 97) { firing2 = false; return false; } return false; } // To ensure Java 1.1 compatibility, request focus on mouseDown public boolean mouseDown(java.awt.Event e,int x, int y) { requestFocus(); return false; } public void paint(Graphics g) // Draw the control panel and stuff { update(g); } public void update(Graphics g) { g.drawImage(offImage,0,0,this); } final static int BOSS_WAVE = 2; int countdown=0; int dx = 0; int dx2 = 0; int dy = 0; int dy2 = 0; final static int END_GAME = 3; int enemyShotDY = 8; int[][] enemyShots = new int[maxEnemyShots][2]; int enemyShotsIndex = 0; Image[][] fighterImages = new Image[numShipTypes][numShipAnims]; boolean firing = false; boolean firing2 = false; int[][][] formation = new int[formationRows][formationColumns][2]; final static int FORMATION_WAVE = 1; static final int formationColumns = 7; int formationDX; int formationDY; static final int formationRows = 4; static final int formationTargetY = 50; int formationX; int formationY; final static int GAME_OVER = 0; int hitpoints = 0; int hitpoints2 = 0; int[][] hits = new int[maxHits][3]; int hitsIndex = 0; static final int[][] initialFormation = { { -1, 0, 0, 0, 0, 0, -1 }, { -1, 1, 1, -1, 1, 1, -1 }, { -1, 2, -1, 2, -1, 2, -1 }, { -1, -1, 3, -1, 3, -1, -1 } }; static final int MAX_X = 1000; static final int maxEnemyShots = 32; static final int maxHits = 32; // keeps track of which slot in the shot array we are using static final int maxShots = 50; static final int MAY_Y = 700; final static int NUM_LIVES = 3; final static int numGoodShipTypes = 3; static final int numShipAnims = 4; static final int numShipTypes = 4; static final int numStars = 100; int previousCount =20; Random random; Image ship[] = new Image[numGoodShipTypes]; // graphics for our ship int shipAnimsCounter = 0; int shipType = 0; int shotCounter = 0; int shotDY = -30; // detemines how quicikly our shots move. boolean shotFired; boolean shotFired2 = false; // determines how many shots we can have on the screen at once. int[][] shots = new int[maxShots][4]; // array to keep track of our shots. boolean speedDoubled = false; int[][] stars = new int[numStars][3]; Image title; int xPos = 5; // coordinates for our ship int xPos2 = 300; int yPos = 400; int yPos2 = 400; public void initializeFormation() { formationDX = 2; formationX = 50; formationY = -300; formationDY= 10; for (int col = 0; col < formationColumns; col++) { for (int row = 0; row < formationRows; row++) { formation[row][col][0] = initialFormation[row][col]; if (initialFormation[row][col] >=0) { formation[row][col][1] = 5-initialFormation[row][col]; } } } } public void initializeGame() { System.gc(); //Main fighter yPos = 520; xPos = 520; yPos2 = 520; xPos2 = 50; // formation fighters initializeFormation(); runMode = FORMATION_WAVE; hitpoints = 100; lives = NUM_LIVES; score = 0; level = 0; shipType = 0; } public void initializeStars() { int i; for (i = 0; i < numStars; i++) { stars[i][0] = (int) (Math.random() * MAX_X); stars[i][1] = (int) (Math.random() * 600); stars[i][2] = (int) (Math.random() * 5 + 2); } } public void processEnemyShots() { offGraphics.setColor(Color.green); for (int i = 0; i < maxEnemyShots; i++) { if (enemyShots[i][1] > 0) { enemyShots[i][1] += enemyShotDY; offGraphics.fillRect(enemyShots[i][0] - 2, enemyShots[i][1], 4, 7); if (runMode == FORMATION_WAVE && enemyShots[i][1] < yPos + 32 && enemyShots[i][1] > yPos && enemyShots[i][0] > xPos && enemyShots[i][0] < xPos + 32) { hits[hitsIndex][0] = enemyShots[i][0]; hits[hitsIndex][1] = enemyShots[i][1]; hits[hitsIndex][2] = 8; hitsIndex++; hitsIndex = hitsIndex % maxHits; hitpoints -= 25; // Check for death if (hitpoints < 0) { lives--; if (lives <= 0) { runMode = END_GAME; countdown = 60; } else { shipType = 0; hitpoints = 100; } } enemyShots[i][1] = -1; } } } } public void processFormation() { shipAnimsCounter++; formationY += formationDY; if (formationY > formationTargetY) formationDY = 0; formationX += formationDX; if (speedDoubled) { formationX += formationDX*2; shipAnimsCounter++; } shipAnimsCounter = shipAnimsCounter%(numShipAnims*7); int imageNum; int x; int y; int count=0; for (int col = 0; col < formationColumns; col++) { for (int row = 0; row < formationRows; row++) { imageNum = formation[row][col][0]; if (imageNum >= 0) { x = formationX + 70 * col; y = formationY + 90 * row; offGraphics.drawImage(fighterImages[imageNum][shipAnimsCounter/7], x, y, this); if (x > MAX_X - 70) formationDX = -2; if (x < 10) formationDX = 2; count++; if (Math.random() * 1000 < 40 - previousCount*2) { enemyShots[enemyShotsIndex][0]=x + 32; enemyShots[enemyShotsIndex][1]=y + 64; enemyShotsIndex++; enemyShotsIndex = enemyShotsIndex % maxEnemyShots; } } } } speedDoubled = (count<5); if (count == 0) { initializeFormation(); shipType++; level++; if (shipType >= numGoodShipTypes) shipType = numGoodShipTypes-1; } previousCount = count; } public void processHits() { offGraphics.setColor(Color.yellow); for (int i = 0; i < maxHits; i++) { if (hits[i][2] > 0) { offGraphics.drawArc(hits[i][0],hits[i][1],hits[i][2],hits[i][2],0,360); hits[i][2]--; } } } public void processMainShip() { xPos += dx; yPos += dy; if (xPos > MAX_X) { xPos = MAX_X; dx = 0; } if (xPos < 1) { xPos = 1; dx = 0; } if (yPos > 520) { yPos = 520; dy = 0; } if (yPos < 180) { yPos = 180; dy = 0; } offGraphics.drawImage(ship[shipType], xPos, yPos, this); xPos2 += dx2; yPos2 += dy2; if (xPos2 > MAX_X) { xPos2 = MAX_X; dx2 = 0; } if (xPos2 < 1) { xPos2 = 1; dx2 = 0; } if (yPos2 > 520) { yPos2 = 520; dy2 = 0; } if (yPos2 < 180) { yPos2 = 180; dy2 = 0; } offGraphics.drawImage(ship[shipType], xPos2, yPos2, this); } public void processShots() { int imageNum; int x; int y; if (!shotFired && firing && shots[shotCounter][0] <= 0) { shotFired = true; switch (shipType) { case 0 : shots[shotCounter][0] = xPos + 14; shots[shotCounter][1] = yPos + 7 - shotDY; shots[shotCounter][2] = 0; shots[shotCounter][3] = shotDY; shotCounter++; shotCounter = shotCounter % maxShots; break; case 1 : shots[shotCounter][0] = xPos + 6; shots[shotCounter][1] = yPos + 7 - shotDY; shots[shotCounter][2] = 0; shots[shotCounter][3] = shotDY; shotCounter++; shotCounter = shotCounter % maxShots; shots[shotCounter][0] = xPos + 22; shots[shotCounter][1] = yPos + 7 - shotDY; shots[shotCounter][2] = 0; shots[shotCounter][3] = shotDY; shotCounter++; shotCounter = shotCounter % maxShots; shotFired = true; break; case 2 : shots[shotCounter][0] = xPos + 6; shots[shotCounter][1] = yPos + 7 - shotDY; shots[shotCounter][2] = 0; shots[shotCounter][3] = shotDY; shotCounter++; shotCounter = shotCounter % maxShots; shots[shotCounter][0] = xPos + 22; shots[shotCounter][1] = yPos + 7 - shotDY; shots[shotCounter][2] = 0; shots[shotCounter][3] = shotDY; shotCounter++; shotCounter = shotCounter % maxShots; shots[shotCounter][0] = xPos + 1; shots[shotCounter][1] = yPos + 10 - shotDY; shots[shotCounter][2] = -2; shots[shotCounter][3] = shotDY+2; shotCounter++; shotCounter = shotCounter % maxShots; shots[shotCounter][0] = xPos + 27; shots[shotCounter][1] = yPos + 10 - shotDY; shots[shotCounter][2] = 2; shots[shotCounter][3] = shotDY+2; shotCounter++; shotCounter = shotCounter % maxShots; shotFired = true; break; } } else { shotFired = false; } if (!shotFired2 && firing2 && shots[shotCounter][0] <= 0) { shotFired2 = true; switch (shipType) { case 0 : shots[shotCounter][0] = xPos2 + 14; shots[shotCounter][1] = yPos2 + 7 - shotDY; shots[shotCounter][2] = 0; shots[shotCounter][3] = shotDY; shotCounter++; shotCounter = shotCounter % maxShots; break; case 1 : shots[shotCounter][0] = xPos2 + 6; shots[shotCounter][1] = yPos2 + 7 - shotDY; shots[shotCounter][2] = 0; shots[shotCounter][3] = shotDY; shotCounter++; shotCounter = shotCounter % maxShots; shots[shotCounter][0] = xPos2 + 22; shots[shotCounter][1] = yPos2 + 7 - shotDY; shots[shotCounter][2] = 0; shots[shotCounter][3] = shotDY; shotCounter++; shotCounter = shotCounter % maxShots; shotFired = true; break; case 2 : shots[shotCounter][0] = xPos2 + 6; shots[shotCounter][1] = yPos2 + 7 - shotDY; shots[shotCounter][2] = 0; shots[shotCounter][3] = shotDY; shotCounter++; shotCounter = shotCounter % maxShots; shots[shotCounter][0] = xPos2 + 22; shots[shotCounter][1] = yPos2 + 7 - shotDY; shots[shotCounter][2] = 0; shots[shotCounter][3] = shotDY; shotCounter++; shotCounter = shotCounter % maxShots; shots[shotCounter][0] = xPos2 + 1; shots[shotCounter][1] = yPos2 + 10 - shotDY; shots[shotCounter][2] = -2; shots[shotCounter][3] = shotDY+2; shotCounter++; shotCounter = shotCounter % maxShots; shots[shotCounter][0] = xPos2 + 27; shots[shotCounter][1] = yPos2 + 10 - shotDY; shots[shotCounter][2] = 2; shots[shotCounter][3] = shotDY+2; shotCounter++; shotCounter = shotCounter % maxShots; shotFired = true; break; } } else { shotFired2 = false; } offGraphics.setColor(Color.red); for (int i = 0; i < maxShots; i++) { if (shots[i][1] < 0) shots[i][0] = -1; if (shots[i][0] > 0) { shots[i][1] += shots[i][3]; shots[i][0] += shots[i][2]; offGraphics.drawRect(shots[i][0], shots[i][1], 1, 3); // Collision detection for (int col = 0; col < formationColumns; col++) { for (int row = 0; row < formationRows; row++) { imageNum = formation[row][col][0]; if (imageNum >= 0) { x = formationX + 70 * col; y = formationY + 90 * row; if (shots[i][1] < y + 64 && shots[i][1] > y && shots[i][0] > x && shots[i][0] < x + 64) { formation[row][col][1]--; hits[hitsIndex][0] = shots[i][0]; hits[hitsIndex][1] = shots[i][1]; hits[hitsIndex][2] = 8; hitsIndex++; hitsIndex = hitsIndex % maxHits; if (formation[row][col][1] < 1) { score+= (5-formation[row][col][0])*1000; formation[row][col][0] = -1; // explosion code goes here } shots[i][0] = -1; } } } } } } } public void processStars() { offGraphics.setColor(Color.white); for (int i = 0; i < numStars; i++) { offGraphics.drawLine(stars[i][0], stars[i][1], stars[i][0], stars[i][1]); stars[i][1] += stars[i][2]; if (stars[i][1] > 600) { stars[i][0] = (int) (Math.random() * MAX_X); stars[i][1] = -2; stars[i][2] = (int) (Math.random() * 5 + 2); } } } }