// Re-write of an old, old IBM x86 game called "Space Wars" // Possibly (c) whoever the original author was, I have no idea now // This code (c) 2001 D. Clayton // Use it, don't abuse it... import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*; import java.util.*; import java.math.*; public class Space extends JFrame implements KeyListener { static final int MISSILE_LIFE = 150; // in frames static final int MISSILE_DMG = 50; static final int MAX_MISSILES = 32; // per ship static final int MISSILE_DELAY = 10; static final int LASER_DMG = 5; static final int LASER_DELAY = 4; static final int LASER_RANGE = 100; static final int EXPLODE_TIME = 50; static final double MISSILE_RELEASE = 5; // added to ship's velocity static final double MAX_DX = 20; static final double MAX_DY = 20; static final double MIN_DX = -MAX_DX; static final double MIN_DY = -MAX_DY; static final double inc = 120 * Math.PI / 180; static final double GRAVITY = 8; Game game; Ship p1, p2; PlayArea pa; int red=0, green=0; boolean gameOver = false, planet = false; Polygon plan; public static void main(String args[]) { new Space().show(); } public Space() { setSize(800,650); setResizable(false); pa = new PlayArea(); addKeyListener(this); getContentPane().add(pa); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } public void keyPressed(KeyEvent e) { // f1 = 112, etc. int key = e.getKeyCode(); if (gameOver) { if (key == 32) { pa.reset(); } else if (key == 112) { planet = true; } else if (key == 113) { planet = false; } else if (key == 27) { System.exit(0); } repaint(); return; } if (key == 155) { p1.toWpn = true; } else if (key == 127) { p1.fromWpn = true; } else if (key == 36) { p1.toSh = true; } else if (key == 35) { p1.fromSh = true; } else if (key == 51) { p2.toWpn = true; } else if (key == 69) { p2.fromWpn = true; } else if (key == 50) { p2.toSh = true; } else if (key == 87) { p2.fromSh = true; } else if (key == 37) { p1.rl = true; } else if (key == 39) { p1.rr = true; } else if (key == 90) { p2.rl = true; } else if (key == 67) { p2.rr = true; } else if (key == 38) { p1.fw = true; } else if (key == 40) { p1.bw = true; } else if (key == 83) { p2.fw = true; } else if (key == 88) { p2.bw = true; } else if (key == 33) { p1.f1 = true; } else if (key == 34) { p1.f2 = true; } else if (key == 49) { p2.f1 = true; } else if (key == 81) { p2.f2 = true; } } public void keyReleased(KeyEvent e) { int key = e.getKeyCode(); if (key == 155) { p1.toWpn = false; } else if (key == 127) { p1.fromWpn = false; } else if (key == 36) { p1.toSh = false; } else if (key == 35) { p1.fromSh = false; } else if (key == 51) { p2.toWpn = false; } else if (key == 69) { p2.fromWpn = false; } else if (key == 50) { p2.toSh = false; } else if (key == 87) { p2.fromSh = false; } else if (key == 37) { p1.rl = false; } else if (key == 39) { p1.rr = false; } else if (key == 90) { p2.rl = false; } else if (key == 67) { p2.rr = false; } else if (key == 38) { p1.fw = false; } else if (key == 40) { p1.bw = false; } else if (key == 83) { p2.fw = false; } else if (key == 88) { p2.bw = false; } else if (key == 33) { p1.f1 = false; } else if (key == 34) { p1.f2 = false; } else if (key == 49) { p2.f1 = false; } else if (key == 81) { p2.f2 = false; } } public void keyTyped(KeyEvent e) { } public class PlayArea extends JPanel { public void reset() { p1 = new Ship(200, 300, Color.red); p2 = new Ship(600, 300, Color.green); p1.setEnemy(p2); p2.setEnemy(p1); p1.mis = new Vector(); p2.mis = new Vector(); if (planet) { int i, j; plan = new Polygon(); double rads = -Math.PI, ii = inc / 5; for (int n = 0; n < 15; n++) { i = 400 + (int)(27 * Math.cos(rads)); j = 300 + (int)(27 * Math.sin(rads)); plan.addPoint(i, j); rads += ii; } } game = new Game(); game.start(); } public PlayArea() { reset(); setSize(800, 650); } public void paint(Graphics g) { g.setColor(Color.black); g.fillRect(0,0,800,650); g.setColor(Color.cyan); g.drawLine(20, 595, 20 + p1.energy, 595); g.drawLine(770, 595, 770 - p2.energy, 595); g.drawString("e", 5, 597); g.drawString("e", 780, 597); g.setColor(Color.green); g.drawLine(20, 605, 20 + p1.shield, 605); g.drawLine(770, 605, 770 - p2.shield, 605); g.drawString("s", 5, 608); g.drawString("s", 780, 608); g.setColor(Color.red); g.drawLine(20, 615, 20 + p1.weapon, 615); g.drawLine(770, 615, 770 - p2.weapon, 615); g.drawString("w", 5, 619); g.drawString("w", 780, 619); g.drawString(""+red, 265, 605); g.setColor(Color.green); g.drawString(""+green, 520, 605); if (planet) { g.setColor(new Color(0, 0, 120)); g.fillOval(380, 280, 40, 40); g.setColor(new Color(0, 0, 160)); g.fillOval(385, 282, 33, 33); g.setColor(new Color(0, 0, 200)); g.fillOval(392, 284, 24, 24); g.setColor(new Color(0, 0, 240)); g.fillOval(398, 287, 16, 16); } p1.paint(g); p2.paint(g); if (gameOver) { g.setColor(Color.black); g.fillRect(340, 380, 120, 130); g.setColor(Color.red); g.drawRect(340, 380, 120, 130); g.drawString("GAME OVER", 366, 400); g.drawString("f1 - planet on", 366, 420); g.drawString("f2 - planet off", 366, 440); g.drawString("space - play again", 351, 460); g.drawString("esc - quit", 375, 480); g.drawString("[planet is: "+(planet ? "on" : "off")+"]", 365, 500); } } } public class Game extends Thread { public Game() { } public void run() { int mspframe = 40; int tik = 0; gameOver = false; while (!gameOver) { try { sleep(mspframe); } catch (Exception e) {}; tik++; if (tik == 15) { tick(); tik = 0; } p1.move(); p2.move(); repaint(); } } public void tick() { p1.regen(); p2.regen(); } } public class Ship { protected int x, y, energy, shield, weapon, lastFired=0, lastFiredM=0, exploding=0; double dir, dx, dy, speed; Color col; boolean laser = false, missile = false, dead = false; Ship enemy; Polygon p, q, r; Vector mis; boolean fw=false, bw=false, rl=false, rr=false, f1=false, f2=false, toSh=false, toWpn=false, fromSh=false, fromWpn=false; public void setEnemy(Ship e) { enemy = e; } public Ship(int xx, int yy, Color c) { x = xx; y = yy; col = c; energy = 200; shield = 200; weapon = 200; speed = 0; dir = -90; } public void fire(int wpn) { if (wpn == 0) { // laser laser = true; } else if (wpn == 1) { // missile missile = true; } } public void regen() { if (energy < 200) { energy++; } } public void explode() { p = new Polygon(); q = new Polygon(); r = new Polygon(); x += (int)dx; y += (int)dy; if (x > 800) x = 0; if (x < 0) x = 800; if (y > 600) y = 0; if (y < 0) y = 600; p.addPoint(x - exploding, y - exploding); p.addPoint((x - exploding) - 6, (y - exploding) - 7); p.addPoint((x - exploding) - 15, (y - exploding) + 8); q.addPoint(x + exploding, y - exploding); q.addPoint(x + exploding + 8, (y - exploding) - 8); q.addPoint((x + exploding) - 12, (y - exploding) - 4); r.addPoint(x + exploding, y + exploding); r.addPoint(x + exploding + 18, y + exploding + 1); r.addPoint(x + exploding + 6, y + exploding + 11); exploding++; if (exploding > EXPLODE_TIME) { gameOver = true; if (p1.dead && !p2.dead) { green++; } if (p2.dead && !p1.dead) { red++; } } } public void dmg(int amt) { shield -= amt; if (shield <= 0) { dead = true; } } public void move() { boolean chVel = false; if (dead) { explode(); return; } if (!(rl && rr)) { if (rl) { dir -= 15; if (dir < -180) dir += 360; } else if (rr) { dir += 15; if (dir > 180) dir -= 360; } } if (!(fw && bw)) { if (fw && energy > 0) { speed = 1; chVel=true; } else if (bw && energy > 0) { speed = -1; chVel=true; } } if (f1 && weapon > 1 && lastFired == 0) { weapon-=2; lastFired+=LASER_DELAY; fire(0); } if (f2 && weapon > 10 && lastFiredM == 0) { weapon-=10; lastFiredM+=MISSILE_DELAY; fire(1); } if (toWpn && energy > 2 && weapon < 199) { energy-=2; weapon+=2; } if (fromWpn && energy < 199 && weapon > 2) { energy+=2; weapon-=2; } if (toSh && energy > 2 && shield < 199) { energy-=2; shield+=2; } if (fromSh && energy < 199 && shield > 2) { energy+=2; shield-=2; } if (lastFired > 0) lastFired--; if (lastFiredM > 0) lastFiredM--; if (chVel) { double radsDir = dir * Math.PI / 180; dx += speed * Math.cos(radsDir); dy += speed * Math.sin(radsDir); energy--; } if (planet) { double gx, gy, xd, yd, dd; xd = 400 - x; yd = 300 - y; dd = (xd * xd) + (yd * yd); // pythag gx = xd / dd * GRAVITY; gy = yd / dd * GRAVITY; dx += gx; dy += gy; } if (dx > MAX_DX) dx = MAX_DX; if (dx < MIN_DX) dx = MIN_DX; if (dy > MAX_DY) dy = MAX_DY; if (dy < MIN_DY) dy = MIN_DY; x += (int)dx; y += (int)dy; if (x > 800) x = 0; if (x < 0) x = 800; if (y > 600) y = 0; if (y < 0) y = 600; if (planet) { if (plan.contains(x, y)) { dmg(100); } } for (int i = 0; i < mis.size(); i++) { Missile m = (Missile)mis.elementAt(i); int stat = m.move(); if (stat == 1) { // finished mis.removeElementAt(i); } } } public void paint(Graphics g) { int px, py, fx, fy; if (dead) { g.setColor(col); g.fillPolygon(p); if (q != null) { g.fillPolygon(q); } if (r != null) { g.fillPolygon(r); } return; } double radsDir = dir * Math.PI / 180; p = new Polygon(); fx = x + (int)(21 * Math.cos(radsDir)); fy = y + (int)(21 * Math.sin(radsDir)); p.addPoint(fx, fy); if (laser) { laser = false; g.setColor(Color.red); int x2, y2, x3, y3, x4, y4, x5, y5; x5 = (int)(LASER_RANGE * Math.cos(radsDir)); y5 = (int)(LASER_RANGE * Math.sin(radsDir)); x3 = x5 / 2; y3 = y5 / 2; x2 = x3 / 2; y2 = y3 / 2; x4 = x3 + x2; y4 = y3 + y2; x2 += x; x3 += x; x4 += x; x5 += x; y2 += y; y3 += y; y4 += y; y5 += y; g.drawLine(fx, fy, x5, y5); if (enemy.p != null) { if (enemy.p.contains(x2, y2) || enemy.p.contains(x3, y3) || enemy.p.contains(x4, y4) || enemy.p.contains(x5, y5)) { enemy.dmg(LASER_DMG); } } } if (missile) { missile = false; if (mis.size() < MAX_MISSILES) mis.addElement(new Missile(fx, fy, dx, dy, radsDir)); } radsDir += inc; px = x + (int)(15 * Math.cos(radsDir)); py = y + (int)(15 * Math.sin(radsDir)); p.addPoint(px, py); radsDir += inc; px = x + (int)(15 * Math.cos(radsDir)); py = y + (int)(15 * Math.sin(radsDir)); p.addPoint(px, py); g.setColor(col); g.fillPolygon(p); for (int i = 0; i < mis.size(); i++) { ((Missile)mis.elementAt(i)).paint(g); } } } public class Missile { int x, y; double dx, dy, dir; long life; Polygon p; public Missile(int ox, int oy, double i, double j, double d) { int f, g; life = MISSILE_LIFE; x = ox; y = oy; dx = i + MISSILE_RELEASE * Math.cos(d); dy = j + MISSILE_RELEASE * Math.sin(d); dir = d; p = new Polygon(); f = x + (int)(5 * Math.cos(d)); g = y + (int)(5 * Math.sin(d)); p.addPoint(f, g); d += inc; f = x + (int)(3 * Math.cos(d)); g = y + (int)(3 * Math.sin(d)); p.addPoint(f, g); d += inc; f = x + (int)(3 * Math.cos(d)); g = y + (int)(3 * Math.sin(d)); p.addPoint(f, g); } public int move() { int f, g; double d = dir; x += dx; y += dy; if (x > 800) x = 0; if (x < 0) x = 800; if (y > 600) y = 0; if (y < 0) y = 600; p = new Polygon(); f = x + (int)(5 * Math.cos(d)); g = y + (int)(5 * Math.sin(d)); p.addPoint(f, g); d += inc; f = x + (int)(3 * Math.cos(d)); g = y + (int)(3 * Math.sin(d)); p.addPoint(f, g); d += inc; f = x + (int)(3 * Math.cos(d)); g = y + (int)(3 * Math.sin(d)); p.addPoint(f, g); life--; if (p1.p.contains(x, y)) { p1.dmg(MISSILE_DMG); life = 0; } if (p2.p.contains(x, y)) { p2.dmg(MISSILE_DMG); life = 0; } return (life > 0 ? 0 : 1); } public void paint(Graphics g) { g.setColor(Color.lightGray); g.drawPolygon(p); } } }