/** * Created by: Joey Brunner * Jeff Bush * * GravityWorm.java * base on the GameTemplate class * developed by Mr Ruth 03/22/03 * * It's a really fun game! * make sure you tell it the dimensions in the HTML file */ import java.awt.*; import java.applet.Applet; import java.awt.event.*; /** * GravityWorm is set up to be 400 x 300 (width x height) * these values come from the tag in the .html file */ public class GravityWorm extends Applet implements Runnable, MouseListener, KeyListener { //constants: // == YOUR CODE GOES HERE == create any necessary constants private final int NUMLINES = 100; //number of lines on horizontal axis private final int LINEWIDTH = 4; //line width horizontally private final int HEADLINEINDEX = 30; //the index where the head of the snake is private final int MAXVELOCITY = 5; //top falling/rising speed //fields: private Thread thread;//acts as a 'timer' private Image imageBuffer;//image gets painted to Applet in update() private Graphics panel;//draw primatives to panel private boolean started,finished;//keep track of the status of the game //three game states: before start, running, game over private boolean mousePushed;//handle mouse events private int count;//master count of how many times the 'timer' fires private int DELAY = 45;//delay in milliseconds // == YOUR CODE GOES HERE == create any necessary fields private int score; //the curret score private int hiscore; //the best score this session private int tunnelTop[]; //array of tunnel top positions private int tunnelBottom[]; //array of bottom top positions private int wormPos[]; //array of positions private int block[]; //if -1, then there is no block at that line private int bonusLoc[]; private int bonusType[]; private int blockHeight; private int velocity; private int changeTop; //length of top slope private int goingUpTop; //if slope is up private int changeBottom; //length of bottom slope private int goingUpBottom; //if slope is up private int level; //methods: //----------------------------------------------------------------------------- public void init() { //initialize imageBuffer and panel to the size of the Applet // note: size of Applet determined in tag in .html file imageBuffer = createImage(400,300);//must be changed if the tag changes panel = imageBuffer.getGraphics(); count = 0;//actual number of DELAYs in time started = finished = false; mousePushed = false; // == YOUR CODE GOES HERE == initialize your fields //setup variables tunnelTop = new int[NUMLINES]; tunnelBottom = new int[NUMLINES]; wormPos = new int[HEADLINEINDEX + 1]; block = new int[NUMLINES]; bonusLoc = new int[NUMLINES]; bonusType = new int[NUMLINES]; hiscore = 0; addMouseListener(this);//needed to handle mouse events }//end init() /** handles the double buffering rendering of the Applet * ... draws the panel to the Applet */ public void update(Graphics g) { if (!started) gameStart(); else move(); g.drawImage(imageBuffer,0,0,this);//flush the imageBuffer to the Applet } //----------------------------------------------------------------------------- /** handles the initialization of fields * that might need to be reinitialized after the game * has been played once, but will be played again * without the Applet being reloaded * (i.e. set score to 0 but leave hiScore alone, etc.) * it also handles drawing any instructions for * game play to the user */ public void gameStart() { started = finished = mousePushed = false; //game has not started, it is not finished, //and the mouse has not been pushed count = 0;//init master count to 0 to start game... // == YOUR CODE GOES HERE == initialize your fields score = 0; //reset score for (int i = 0; i < NUMLINES; i++) { tunnelTop[i] = 20; //create tunnel for beginning of game tunnelBottom[i] = 180; block[i] = -blockHeight; bonusLoc[i] = -1; //create bonus (none) for beginning of game bonusType[i] = 0; } for (int i = 0; i <= HEADLINEINDEX; i++) wormPos[i] = 98; //create worm for beginning of game velocity = 0; //going striaght blockHeight = 40; //starting height DELAY = 50; //default delay changeTop = 5; //length of slope of top at beginning of game goingUpTop = -1; //slope is down changeBottom = 5; //length of slope of bottom at beginning of game goingUpBottom = -1; //slope is down level = 1; //starting level draw();//draw the initial scene ( values are set in init() ) panel.setColor(Color.blue); panel.drawString("CLICK MOUSE TO START!" , 50, 50); repaint(); //updates } //----------------------------------------------------------------------------- /** handles the mouse events.... * at every increment... if the mouse is pressed * then the mousePushed field are set to true.. * ( it also starts the game by setting started to true ) */ public void mousePressed(MouseEvent e) { started = true; mousePushed=true; } //----------------------------------------------------------------------------- /** handles the mouse events.... * at every increment... if the mouse has been released * then the mousePushed field is set to false.. */ public void mouseReleased(MouseEvent e) { mousePushed=false; } //----------------------------------------------------------------------------- /** * checks the game state.. * if not finished means game is running... * then update all necessary fields for the move * else the game is over... then it can be started again) * move checks to see if the mouse has been pushed * then updates all the appropriate data accordingly * move() is only called if the game has started ( see update() ) */ public void move() { if ( !finished) //game is running { // == YOUR CODE GOES HERE == update all fields accordingly for (int i = 0; i < NUMLINES - 1; i++) { tunnelTop[i] = tunnelTop[i+1]; //move all arrays down by one tunnelBottom[i] = tunnelBottom[i+1]; block[i] = block[i+1]; bonusLoc[i] = bonusLoc[i+1]; bonusType[i] = bonusType[i+1]; } for (int i = 0; i < HEADLINEINDEX; i++) wormPos[i] = wormPos[i+1]; //move worm down by one //Get falling rraising speed if (mousePushed) // if mouse is pushed, going up velocity += 1; else // otherwise falling velocity -= 1; if (velocity < -MAXVELOCITY) //if we are falling faster then max, readjust velocity = -MAXVELOCITY; if (velocity > MAXVELOCITY)//if we are raising faster then max, readjust velocity = MAXVELOCITY; //New tunnel space: //New tunnel top if (goingUpTop == 1) //if going up tunnelTop[NUMLINES - 1] += 1; //tunnel top goes up else //if going down tunnelTop[NUMLINES - 1] -= 1; //tuneel top goes down changeTop--; //length of slope decreases by one if (changeTop <= 0 || tunnelTop[NUMLINES - 1] <= 1) { //if slope is done or if tunnel is off-screen changeTop = (int)(8.0*Math.random()) + 2; //new slope length goingUpTop *= -1; //switch directions } //New tunnel bottom if (goingUpBottom == 1) //if going up tunnelBottom[NUMLINES - 1] += 1; //tunnel bottom goes up else //if going down tunnelBottom[NUMLINES - 1] -= 1; //tunnel bottom goes down changeBottom--; //length of slope decreases by one if (changeBottom <= 00 || tunnelBottom[NUMLINES - 1] >= 199) { //if slope is done or if tunnel is off-screen changeBottom = (int)(8.0*Math.random()) + 2; //new slope length goingUpBottom *= -1; //switch directions } //New block space if (Math.random() <= .1) //probability of a new block is 1/10 block[NUMLINES - 1] = (int)(200.0 * Math.random()); //make the new block else block[NUMLINES - 1] = -blockHeight; //make off-screen block //New bonus space if (Math.random() <= .05) { //probability of a new bonus is 5/100 bonusLoc[NUMLINES - 1] = (int)(200.0 * Math.random()); //new bonus bonusType[NUMLINES - 1] = (int)(5.0 * Math.random()) + 1; //bonus type } else { bonusLoc[NUMLINES - 1] = -1; //turn off bonus bonusType[NUMLINES - 1] = 0; } //New worm space wormPos[HEADLINEINDEX] -= velocity; //adjust for the velocity int head = wormPos[HEADLINEINDEX]; //get the head position if (head >= bonusLoc[HEADLINEINDEX] - LINEWIDTH //if head is at bonus && head <= bonusLoc[HEADLINEINDEX] + LINEWIDTH * 3) { score += 15; //add to score switch (bonusType[HEADLINEINDEX]) { //which type of bonus? case 1: DELAY += 5; break; //Slower case 2: DELAY -= 10; break; //Faster case 3: //Bomb for (int i = 0; i < NUMLINES; i++) block[i] = -blockHeight; break; case 4: blockHeight -= 5; break; //Shrink case 5: blockHeight += 5; break; //Grow } bonusType[HEADLINEINDEX] = 0; //erase bonus bonusLoc[HEADLINEINDEX] = -1; } if (head <= tunnelTop[HEADLINEINDEX] //hit the roof || head >= tunnelBottom[HEADLINEINDEX] //hit the floor || (head >= block[HEADLINEINDEX] && //hit block head <= (block[HEADLINEINDEX] + blockHeight))) { finished = true; //GAME OVER score += count; //add the count to score count = 0; //reset count } //New level if (count > (100 * level)) { //every 100 increase level level++; //increase level DELAY -= 5; //make it faster blockHeight += 5; //make them longer score += 50 * level; //add to score } draw(); //draw } else //finished .. (i.e. GAME OVER) { panel.setColor(Color.red); panel.drawString("GAME OVER" , 200, 240); if (score > hiscore) hiscore = score; //wait until user clicks mouse or 100 DELAY's, then reset game if ((mousePushed && count > 25) || count > 200) gameStart(); } }//end move() //----------------------------------------------------------------------------- /** * draws all necessary game elements to the panel */ public void draw() { //draw black background rect for game grid (full width, 2/3 of height) panel.setColor(Color.black); panel.fillRect(0,0,400,200); // == YOUR CODE GOES HERE == draw all necessary items.. // remove the count if necessary for (int i = 0; i < NUMLINES; i++) { //check for all bonuses if (bonusLoc[i] != -1) { switch (bonusType[i]) { //select type case 1: panel.setColor(Color.blue); break; //Slower case 2: panel.setColor(Color.red); break; //Faster case 3: panel.setColor(Color.orange); break; //Bomb case 4: panel.setColor(Color.yellow); break; //Shrink case 5: panel.setColor(Color.lightGray); break; //Grow } panel.fillRoundRect(i*LINEWIDTH-LINEWIDTH/2, //draw little sausage thingy bonusLoc[i]-LINEWIDTH/2, 2*LINEWIDTH,4*LINEWIDTH,5,5); } } if (level == 1) panel.setColor(Color.green); //level one is green else if (level == 2) panel.setColor(new Color(50,200,50)); //2 is faded green else if (level == 3) panel.setColor(Color.lightGray); //3 is light gray else if (level == 4) panel.setColor(Color.darkGray); //4 is dark gray //levels 5-9 are multicolor bases on last bonus else if (level >= 10 && finished) panel.setColor(Color.white);//level 10+ is white after dead else if (level >= 10) panel.setColor(Color.black);//otherwise black for (int i = 0; i < NUMLINES; i++) { //draws the scene (blocks, roof, floor) panel.fillRect(i*LINEWIDTH,0,LINEWIDTH,tunnelTop[i]); //roof panel.fillRect(i*LINEWIDTH,tunnelBottom[i],LINEWIDTH,200); //floor if (block[i] >= 0) //if the block exsists... panel.fillRect(i*LINEWIDTH,block[i],LINEWIDTH,blockHeight); //draw block } if (!finished) panel.setColor(Color.green); //head color normally green else panel.setColor(Color.red); //when dead, turns read panel.fillRoundRect(HEADLINEINDEX*LINEWIDTH, //draws the circle head wormPos[HEADLINEINDEX]-(int)(.5*LINEWIDTH), 2*LINEWIDTH,2*LINEWIDTH,5,5); int green = 0; //green starts black for (int i = 0; i < HEADLINEINDEX; i++) { panel.setColor(new Color(0,green,0)); //new shade of green green = (255 / (HEADLINEINDEX)) * i; //green goes toward 255 panel.drawLine(i*LINEWIDTH,wormPos[i],(i+1)*LINEWIDTH,wormPos[i+1]); //snake is made of four lines panel.drawLine(i*LINEWIDTH,wormPos[i]+1,(i+1)*LINEWIDTH,wormPos[i+1]+1); //each one under the other panel.drawLine(i*LINEWIDTH,wormPos[i]+2,(i+1)*LINEWIDTH,wormPos[i+1]+2); panel.drawLine(i*LINEWIDTH,wormPos[i]+3,(i+1)*LINEWIDTH,wormPos[i+1]+3); } //draw text items on score board panel.setColor(Color.cyan); panel.drawString("Count: " + count, 0,280); panel.drawString("Score: " + (score + count), 0,240); panel.drawString("Level: " + level, 0,230); panel.drawString("Hi-Score: " + hiscore, 0,250); }//end draw() //----------------------------------------------------------------------------- // | | // | do not modify this code | // v v /** these methods handles the so called 'timer' ... * and is needed to implement the Runnable interface */ public void start() { thread = new Thread(this); thread.start(); } public void stop() { thread.stop(); thread=null; return; } public void run() { while(true) { try { Thread.currentThread().sleep(DELAY); } catch(InterruptedException e) { thread.stop(); thread=null; return; } Thread.currentThread().yield(); count++;//keeps track of how many times the 'timer' fires repaint(); } } //empty methods needed to implement MouseListener public void mouseClicked(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} //empty methods needed to implement KeyListener public void keyPressed(KeyEvent e){} public void keyReleased(KeyEvent e){} public void keyTyped(KeyEvent e){} // ^ ^ // | do not modify this code | // | | //----------------------------------------------------------------------------- }//end of GravityWorm