Matthews Final Project

<< Joseph's Final Project | OldProjectsTrailIndex | Russell's Final Project >>

Hi Matt-- I have added a simple block you may wish to change, and added code for detecting hits and misses, and decided to also make the stealth go in and out with the Q and Z keys, so its easier to avoid the blocks. Maybe you can change the scoring to add a bonus the larger the plane is. Next feature to consider is adding a thud sound on impact. Another enhancement to consider is changing the img of the blockade to a puff of smoke after a hit rather than just removing it.

Click here to see a running version

You can attach the graphics files like this: (click to upload)

thud.wav

CanyonCruzer.java

import java.awt.event.*; 
import java.awt.image.BufferedImage;
import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class CanyonCruzer<leftWall> extends Applet implements ActionListener, KeyListener
{
    Stealth stealth;
    int amount;
	Timer timer;
    int frame, lastFrame;
    Image virtualMem;
    BufferedImage img, stealthImg, wallImage, blockImage;
    Graphics gBuffer;
    Button startButton;
    DirectionlessWall leftWall,rtWall,bottom,bottomRt,top;
    ArrayList<Blockade> blocks;
    int hits,miss;

    ArrayList<Integer> keys;
	public void init(){
		keys = new ArrayList<Integer>(); 
		blocks = new ArrayList<Blockade>();
		hits=0;
		miss=0;
		try {
				stealthImg = ImageIO.read( getClass().getResource("/Stealth.gif"));
				wallImage = ImageIO.read( getClass().getResource("/rockroad.GIF"));
				blockImage = ImageIO.read( getClass().getResource("/block.GIF"));
	        } catch (IOException e) {
				e.printStackTrace();
			}
		stealth = new Stealth( 20, 100, stealthImg);
		this.addKeyListener(this);
		int width=getWidth();
		int height=getHeight();
		timer = new Timer(1, this);
		frame=0;
		lastFrame=100;
		amount= 5;
		virtualMem = createImage(width,height);
        gBuffer = virtualMem.getGraphics();
        startButton= new Button("Engage in Mission");
        startButton.addActionListener (this);
        add(startButton);   

        this.setFocusable(true);

        //Audio
       //racingSound = getAudioClip(getDocumentBase(), "racing.wav");
        //Initialize side polygons
        leftWall=new DirectionlessWall(wallImage, -15, DirectionlessWall.LEFT);
		leftWall.addPoint(0,0);
		leftWall.addPoint(300, 100);
		leftWall.addPoint(300, 500);
		leftWall.addPoint(0, 600);
		rtWall=new DirectionlessWall(wallImage, 15, DirectionlessWall.RIGHT);
		rtWall.addPoint(800,0);
		rtWall.addPoint(500, 100);
		rtWall.addPoint(500, 500);
		rtWall.addPoint(800, 600);
		lastFrame=rtWall.getWidth();
		top=new DirectionlessWall(wallImage, -10, DirectionlessWall.UP);
		top.addPoint(800,0);
		top.addPoint(0,0);
		top.addPoint(300,100);
		top.addPoint(500,100);
		bottom=new DirectionlessWall(wallImage, 10, DirectionlessWall.DOWN);
		bottom.addPoint(0,600);
		bottom.addPoint(300,400);
		bottom.addPoint(500, 400);
		bottom.addPoint(800, 600);
		//middle=new DirectionlessWall("DownCave.gif", 10, 0);
		//middle.addPoint(300,100);
		//middle.addPoint(300, 500);
		//middle.addPoint(500, 500);
		//middle.addPoint(500,100);


	}
	public void paint(Graphics g){
		int width=getWidth();
		int height=getHeight();
        gBuffer.setColor(Color.BLACK);
        gBuffer.fillRect(0,0,width,height); 
        leftWall.draw(gBuffer, frame);
        rtWall.draw(gBuffer, frame);
        bottom.draw(gBuffer, frame);
        top.draw(gBuffer, frame);
        //middle.draw(gBuffer, frame);

       gBuffer.setColor(Color.RED);
       gBuffer.drawString("Location: ("+stealth.getX()+", "+stealth.getY()+")", 305, 150);
       gBuffer.drawString("frame "+frame, 305, 170);
       int percent=0;
       if (hits+miss>0)
    	   		percent=100*hits/(hits+miss);
       gBuffer.drawString("hits: "+hits+" ("+percent+"%)", 305, 190);
       gBuffer.drawString("misses: "+miss, 305, 210);

       for (Blockade b:blocks)
    	   		b.draw(gBuffer);
       stealth.draw(gBuffer); 
       g.drawImage(virtualMem,0,0,this);

	}
	public void keyTyped(KeyEvent arg0) {}

    public void keyPressed(KeyEvent e){
        if(!keys.contains(e.getKeyCode()))
            keys.add(e.getKeyCode());
    }
    public void keyReleased(KeyEvent e){
        keys.remove(new Integer(e.getKeyCode()));
    }

	@Override
	public void actionPerformed(ActionEvent e) {

		Object source = e.getSource();
        if (source == timer) 
        {
            if (frame < lastFrame) {
                frame++;
            }
            else {
                frame=0;
            }
            if (frame % 25 == 0)
            {
            		blocks.add(new Blockade (blockImage));
            }
            int u = 0;
            while (u<blocks.size())
            {
            		Blockade b= blocks.get(u);
            		b.move();
            		if (b.offScreen()){
            			blocks.remove(b);
            			miss++;
            		}else if(b.touches(stealth.getSize())){
            			hits++;
            			blocks.remove(b);
            		}else{
            			u++;
            		}
            }
            processKeyPresses();
        }
        else {
              frame=0;
              if (timer.isRunning()) {
                  timer.stop();
                  startButton.setLabel("Start");
               }
               else {
                   timer.start();
                   startButton.setLabel("Stop");  
                   requestFocusInWindow();
                }
        }
        repaint();	
	}	

	public void update(Graphics g){
		paint(g);
	}
	public void processKeyPresses(){
		if(keys.contains(KeyEvent.VK_A)||keys.contains(KeyEvent.VK_LEFT))
            stealth.moveLeft(amount);  //tells ship to move left when a or left is held
        if(keys.contains(KeyEvent.VK_D)||keys.contains(KeyEvent.VK_RIGHT))
            stealth.moveRight(amount);  //tells ship to move right when d or right is held
        if(keys.contains(KeyEvent.VK_W)||keys.contains(KeyEvent.VK_UP))
            stealth.moveUp(amount);  //tells ship to move up when w or up is held
        if(keys.contains(KeyEvent.VK_S)||keys.contains(KeyEvent.VK_DOWN))
            stealth.moveDown(amount);  //tells ship to move down when s or down is held
        if(keys.contains(KeyEvent.VK_Q))
            stealth.moveIn(amount); 
        if(keys.contains(KeyEvent.VK_Z))
            stealth.moveOut(amount); 
	}
}

DIRECTIONLESSWALL

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.TexturePaint;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;


public class DirectionlessWall{
	public static final int UP=1;
	public static final int DOWN=1;
	public static final int LEFT=2;
	public static final int RIGHT=2;
	private Polygon p;
	private int speed,direction;
	private BufferedImage img; 
	public DirectionlessWall(BufferedImage image,int speed, int direction){
		this.p=new Polygon();
		this.direction=direction;	
		this.speed=speed;
		this.img = image;

	}
    public void addPoint(int x, int y){
    		p.addPoint(x, y);
    }
    public int getWidth(){ return img.getWidth();}
    public int getHeight(){ return img.getHeight();}
	/**
	 * 
	 * @param g the Graphics object to draw on
	 * @param f the frame number used to animate img on the polygon
	 */
	public void draw(Graphics g, int f){
		Graphics2D g2=(Graphics2D)g;
		int height=img.getHeight();
		int width=img.getWidth();
		int i= speed*f % width;// presume right 
		Rectangle2D tr=new Rectangle2D.Double(i,0,width, height);
		//now check:
		if (direction==LEFT){
			i= width-(speed*f % width);
		} else if (direction==DOWN){
			i= speed*f % img.getHeight();
			tr=new Rectangle2D.Double(0,i,width, height);
		} else if (direction==UP){
			i= height-(speed*f % height);
			tr=new Rectangle2D.Double(0,i,width, height);
		}		
		TexturePaint tp=new TexturePaint(img,tr);
		g2.setPaint(tp);		
		g2.fill(p);
	}

}


Stealth.java

import java.awt.Graphics;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

public class Stealth
{
	private int x,w;
	private int y,h;
	private double ratio;
	private BufferedImage image;
	public static int deltaZ=20;

	public Stealth(int x, int y, BufferedImage image){
		this.x=x;
		this.y=y;
		ratio=(double)image.getHeight()/image.getWidth();
		w=300;
		h=(int)(300.0*ratio);
		this.image=image;
	}

	public int getX() {return x;}
	public int getY() {return y;}
	public void setX(int x){ 
		this.x=x;
	}

	public void setY(int y){ this.y=y;}

	public void draw(Graphics g){
		g.drawImage(image, x, y, x+w, y+h, 0, 0, image.getWidth(), image.getHeight(), null);

	}

	public void moveLeft(int amount) {
		this.x-=amount;
	}
	public void moveRight(int amount) {
		this.x+=amount;
	}
	public void moveUp(int amount) {
		this.y-=amount;
	}
	public void moveDown(int amount) {
		this.y+=amount;
	}
	public void moveIn(int amount) {
		w=w-deltaZ;
		if (w<50){
			w=50;
		}else{
			x+=deltaZ/2;
		}
		h=(int)(ratio*w);
	}
	public void moveOut(int amount) {
		w=w+deltaZ;
		if (w>700){
			w=700;
		}else{
			x-=deltaZ/2;
		}
		h=(int)(ratio*w);
	}

	public Rectangle2D getSize() {
		return new Rectangle2D.Double(x,y,w,h);
	}

}

Blockade.java

import java.awt.Graphics;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

public class Blockade 
{
	private BufferedImage img;
	private int x,y,w,h, deltaX, deltaY;
	private int speed;
	public Blockade(BufferedImage img){
		this.img=img;
		x=400;
		y=300;
		w=30;
		h=(int)(30.0*img.getHeight()/img.getWidth());
		deltaX=randomInt(-6,6);
		deltaY=randomInt(-6,6);
		speed=randomInt(1,5);
		if (deltaX==0 && deltaY==0){//make sure it moves somewhere!
			deltaY=-2;
		}
	}
	public boolean touches(Rectangle2D object){
		boolean bigEnough = w>=object.getWidth();
		if(deltaX>0)
			return bigEnough && object.intersects(x-w, y, w, h);
		return bigEnough && object.intersects(x, y, w, h);
	}
	public int randomInt(int min, int max){
		return min+(int)((max-min)*Math.random());
	}
	public void move(){
		x+=speed*deltaX;
		y+=speed*deltaY;
	}
	public void draw(Graphics g){
		w=105*w/100;
		h=105*h/100;
		int rightSide=x-w;
		if (deltaX*deltaY<0)
			rightSide=x+w;		
		g.drawImage(img, x, y, rightSide, y+h, 0, 0, img.getWidth(), img.getHeight(), null);
	}
	public int getSpeed(){
		return Math.abs(deltaX);
	}
	public boolean offScreen() {
		return x+w<0||x-w>800||y>600||y+h<0;
	}
}