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)



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;
}
}
