/*
* Game.java
*/
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Game extends JFrame implements Runnable
{
private final int FRAME_WIDTH = 500;
private final int FRAME_HEIGHT = 500;
Launcher myLauncher;
protected Target myTarget = new Target(FRAME_WIDTH, FRAME_HEIGHT);
public Ray myRay;
//as an improvement
private Thread rayThread;//each ray will have its own thread
public Vector<Ray> myRays;
Thread targetTread;
Thread rayTread;
Thread launcherThread;
public Game(String title)
{
super(title);
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setLayout(new BorderLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myLauncher = new Launcher(FRAME_WIDTH, FRAME_HEIGHT);
addKeyListener(new myKeyListener());
add(new DrawingPanel());
myRays = new Vector<Ray>();
targetTread = new Thread(myTarget);//MAYBE I SHOULD PUT THIS
myTarget.setMeThread(targetTread);//LINES INTO run?
rayTread = new Thread(myRay);
launcherThread = new Thread(myLauncher);
}
//starts this game
public void start()
{
move();
}
// inner class on which to draw everything
private class DrawingPanel extends JPanel
{
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if (myTarget != null)
{
myTarget.paintComponent(g);
}
if (myLauncher != null)
{
myLauncher.paintComponent(g);
}
for (Ray item : myRays)
{
item.paintComponent(g);
}
}
}
private synchronized void move()
{
while (true)
{
if (myTarget != null)
{
myTarget.move();
}
//checks if there is a ray
if (myRays.size() > 0)
{
Iterator<Ray> iter = myRays.iterator();
while(iter.hasNext())
{
Ray tmp = iter.next();
if (isContact(tmp))
{
System.out.println("Hit it--------------------------");
myTarget.getThread().interrupt();
myTarget = null;
}
else
{
if (tmp.move())
{
myRays.remove(tmp);
break;
}
}
}
}
repaint();
try
{
Thread.sleep(50);
} catch (InterruptedException e)
{
System.exit(0);
}
}
}
public boolean isContact(Ray ray)
{
if (myTarget != null)
{
return myTarget.getLocation().contains(ray.getLocation().x,ray.getLocation().y);
}
return false;
}
private class myKeyListener extends KeyAdapter
{
@Override
public void keyPressed(KeyEvent ke)
{
if (ke.getKeyCode() == KeyEvent.VK_LEFT)
{
myLauncher.moveLeft();
}
if (ke.getKeyCode() == KeyEvent.VK_RIGHT)
{
myLauncher.moveRight();
}
if (ke.getKeyCode() == KeyEvent.VK_UP)// && myRay == null
{
myRay = new Ray(FRAME_WIDTH, FRAME_HEIGHT);
myRay.setPos(myLauncher.rayPosition());
rayThread = new Thread(myRay);
myRay.setMeThread(rayThread);
myRays.add(myRay);
rayThread.start();
}
}
}
@Override
public void run()
{
System.out.println("Starting Game's thread.");
targetTread.start();//IT DOESN'T MATTER IF I COMMENT THIS TWO
launcherThread.start();//LINES, GAME WORKS ANYWAY
start();
}
}
/////////////////Target class
/*
* Target.java
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.color.ColorSpace;
public class Target implements Runnable
{
private final int RADIUS; // RADIUS of circle drawn as part of spaceship
private Point pos;//position of top left hand corner of box holding whole spaceship
private final Color SPACE_SHIP_COLOUR; // colour of spaceship
private int sideChange = 20; // amount of sideways movement per step
private final int HEIGHT, WIDTH; // of frame
//as an improvement
private Thread myThread;
//TODO add constructor
public Target(int frameWidth, int frameHeight)
{
RADIUS = 10;
WIDTH = frameWidth;
HEIGHT = frameHeight;
SPACE_SHIP_COLOUR = Color.GRAY;
//creates point with random x and y coordinates
//generating pseudorandom number for target position
int X_START = 0;//start of our coordinates system
int X_END = WIDTH;
int x_range = X_END - X_START;
for (int i = 0; i < 100; ++i)
{
//just x has to be random
pos = new Point((int) (Math.random() * x_range + X_START),10);
}
//generating pseudorandom number for speed from range [-5,5]
int START = -6;
int END = 6;
int range = END - START;
sideChange = 0;
while (sideChange == 0)
{
sideChange = (int) (Math.random() * range + START);
if (sideChange == 0)//zero not allowed
{
continue;
}
}
}
public void paintComponent(Graphics g)
{
g.setColor(SPACE_SHIP_COLOUR);
g.fillOval(pos.x, pos.y, 40, 20);
g.drawOval(pos.x + 10, pos.y - 10, 20, 20);
}
public void move()
{
if ((pos.x >= 0) && ((pos.x + getLocation().width + 15) < WIDTH))
{
pos.translate(sideChange,0);
}
else
{
if (pos.x < 0)
{
pos.x = 0;
}
else
{
pos.x = pos.x - 20;
}
sideChange *= -1;
}
}
public Rectangle getLocation()
{
return new Rectangle(pos.x,pos.y - 10, 40, 30);
}
public Rectangle getMyArea()
{
return new Rectangle(new Point(getLocation().x,getLocation().y),
new Dimension(getLocation().width,getLocation().height));
}
@Override
public void run()
{
System.out.println("Starting Target's thread.");
}
public void setMeThread(Thread trd)
{
myThread = trd;
}
public Thread getThread()
{
return myThread;
}
}
/////////////////////////Launcher class
/*
* Launcher.java
*/
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
public class Launcher implements Runnable
{
private final Color LAUNCHER_COLOUR = Color.BLACK; // colour
private final int LAUNCHER_HEIGHT, LAUNCHER_WIDTH; // width and height of the base of the launcher
private int x, y; // x and y position of the top left hand corner of the base of the launcher
private final int SIDE_MOVE; // amount of sideways movement
public Launcher(int frameWidth, int frameHeight)
{
LAUNCHER_WIDTH = frameWidth/10;
LAUNCHER_HEIGHT = 10;
x = frameWidth/2-LAUNCHER_WIDTH/2; // roughly central
y = frameHeight - 100;
SIDE_MOVE = 5;
}
public void paintComponent(Graphics g)
{
g.setColor(LAUNCHER_COLOUR);
g.fillRect(x, y, LAUNCHER_WIDTH, LAUNCHER_HEIGHT);
g.fillRect(x + LAUNCHER_WIDTH/2 - 5, y - 10, LAUNCHER_HEIGHT, LAUNCHER_HEIGHT);
}
public void moveRight()
{
if (x + LAUNCHER_WIDTH + 15 < LAUNCHER_WIDTH*10)
{
x += SIDE_MOVE;
}
}
public void moveLeft()
{
if (x > 0)
{
x -= SIDE_MOVE;
}
}
public Point rayPosition()
{
return new Point(x + LAUNCHER_WIDTH/2, y + LAUNCHER_HEIGHT - 15);
}
@Override
public void run()
{
System.out.println("Starting Launcher's thread.");
}
}
/////////////////////Ray class
/*
* Ray.java
*/
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
public class Ray implements Runnable
{
private final int RAY_LENGTH;
private final Color RAY_COLOUR = Color.RED;
private int x, y;
private final int RAY_MOVE;
private Thread myThread;
public Ray(int frameWidth, int frameHeight)
{
x = frameWidth/2; // roughly central
y = frameHeight - 110;
RAY_MOVE = 5;
RAY_LENGTH = 50;
}
public void paintComponent(Graphics g)
{
g.setColor(RAY_COLOUR);
g.drawRect(x, y-RAY_LENGTH, 2, RAY_LENGTH);
}
public synchronized boolean move()
{
boolean offTopOfScreen;
y = y - RAY_MOVE;
// if ray off top of screen tell M257InvadersGame
offTopOfScreen = (y + RAY_LENGTH <= 0);
if (offTopOfScreen)
{
if (myThread != null)
{
System.out.println("Stopping thread" + myThread.getName());
myThread.interrupt();
myThread = null;
}
}
return offTopOfScreen;
}
public void setPos(Point currentPos)
{
x=currentPos.x;
y=currentPos.y;
}
public Rectangle getLocation()
{
return new Rectangle(x,y-RAY_LENGTH, 2, RAY_LENGTH);
}
@Override
public void run()
{
System.out.println("Starting Ray's thread.");
}
public Thread getMyThread()
{
return myThread;
}
public void setMeThread(Thread thrd)
{
myThread = thrd;
}
}
////////////////main
/*
* Main.java
*/
public class Main
{
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
try
{
Game myGame = new Game("Invaders!");
Thread myGameThread = new Thread(myGame);
myGame.setVisible(true);
myGameThread.start();
}
catch(Exception e)
{
System.out.println("Main error: " + e.getMessage());
}
}
} |