/** * @author Kaushik Raj * @see http://www.cis.syr.edu/~kraj/java/ * @email kraj@syr.edu * * (c) copyright-98 Kaushik Raj * All Rights Reserved. * * This source code is free for all non-commercial purposes, as long as the name * and the url address given above is written with the modified program. The author does not gives * the permission to publish the source code in any book or any other publishing media. * * * The author doesnot takes any responsibility for the software/hardware damages * that may occur due to this program. */ /** * Part of this program has been taken from MazeGen.java * * @see http://www.mazeworks.com/mazegen/mazegen.htm */ /** * File : MazeGame.java * Last update : 10 July,1998 */ import java.applet.* ; import java.awt.* ; import java.util.* ; import HungryRat; import MazeCanvas; import Maze; import MazeDFS; import ControlPanel; /** * MazeGame */ public class MazeGame extends Applet implements Runnable { /** all the colors that are going to be used in the program */ static final Color wallColor=Color.white, pathColor=Color.yellow, backColor=Color.lightGray, startColor=Color.green, endColor=Color.red, frameColor=Color.gray, bkgrndColor=Color.darkGray, panelColor=Color.lightGray, appletColor=Color.black ; /** height and the width of the drawing maze canvas */ static final int mcWidth=410, mcHeight=310 ; /** height and the width of the control panel canvas */ static final int pcWidth=150,pcHeight=80; /** height and width of Control Panel */ static final int cpWidth=pcWidth,cpHeight=mcHeight-pcHeight-20; /** parameters for checking if new game has to be played and/or game still going */ private boolean playNewGame=true; private boolean gameOver=false; /** amount of the foodleft for the rat */ private int foodLeft=100; /** images for the mouse and other stuff */ private Image food,time,home,cheese,ratImage; /** maze of the game */ private Maze mz ; /** canvas where the maze and rat and other stuffs are drwan */ private MazeCanvas mc ; /** canvas where the control panel's graphics are drawn */ private PanelCanvas pc; /** Control Panel */ private ControlPanel cp; /** to handle the input by mouse */ private Thread mazeThread ; /** controls the rat independently of the maze thread */ private HungryRat rat; /** no of rows that are there in the maze */ private int noOfRows; /** making the maze as a square maze */ private int noOfCols; /** the sensing power of the mouse */ private int noOfSmellBlocks; /** itialize applet layout and load graphics */ public void init() { setLayout(null); setBackground(appletColor) ; mc = new MazeCanvas(mcWidth,mcHeight) ; mc.resize(mcWidth,mcHeight) ; pc=new PanelCanvas(pcWidth,pcHeight); pc.resize(pcWidth,pcHeight); mc.move(0,0); pc.move(mcWidth+10,0); cp=new ControlPanel(this); cp.resize(cpWidth,cpHeight); cp.move(mcWidth+10+10,pcHeight+10); add(mc) ; add(pc); add(cp); validate() ; boolean loadedImage=false; pc.init(); mc.init(); /* display the image that images are being loaded */ mc.loadingImages(); /* download all the image files necessary for the game before starting */ MediaTracker tracker = new MediaTracker(this); food=getImage(getDocumentBase(),"food.gif"); time=getImage(getDocumentBase(),"time.gif"); home=getImage(getDocumentBase(),"home.gif"); cheese=getImage(getDocumentBase(),"nuts.gif"); ratImage=getImage(getDocumentBase(),"rat.gif"); tracker.addImage(food,0); tracker.addImage(time,1); tracker.addImage(home,2); tracker.addImage(cheese,3); tracker.addImage(ratImage,4); try{ tracker.waitForAll(); loadedImage=!tracker.isErrorAny(); }catch (InterruptedException e) { System.out.println("Unable to get all the images"); return; } /* get the level of the game */ noOfCols=noOfRows=cp.getGameLevel(); /* intialize the panel canvas */ //pc.init(); pc.drawStaticImage(food,time); } /** intializes the thread */ public void start() { /* if the thread is not intialise start it */ if (mazeThread == null) { mazeThread = new Thread(this) ; mazeThread.start() ; } } /** kill all the thread associated with the game as the user has left the page */ public void stop() { if (mazeThread != null) { mazeThread.stop() ; mazeThread = null ; } if (rat!=null) rat.stop(); } /** * runs the program in loop till the game is over and then wait for the user * if he wants to play again. */ public void run() { while(true){ if (playNewGame) { startNewGame(); } // for the thread not to go in infinite loop sleep(500); } } /** * generates the maze with the given rows,cols */ void generate() { //draw the maze mz = new MazeDFS(new Dimension(noOfRows,noOfCols),mc,this) ; mc.drawFresh(mz,home); /* intialise the rat and the thread associated with it */ rat=new HungryRat(mz.getStart().x,mz.getStart().y,mc,mz,cp.getSensingPower(),this); //initialise the thread of the rat rat.init(); } /** * keep the thread ramson for some time. */ void sleep(int ms) { try { Thread.currentThread().sleep(ms) ; } catch (InterruptedException e) {} } /** returns true when the game is over */ public boolean isGameOver(){ return gameOver; } /** * when the mouse is clicked by user that means he is keeping the food over there. */ public boolean mouseDown(java.awt.Event evt, int x, int y) { if (isGameOver()) { return false; }else{ /* get the dimension from the maze canvas */ Dimension d=mc.blockClicked(x,y); int i=d.width; int j=d.height; // if the user has kept the food someplace else just ignore it if ((j>=noOfCols)||(i>=noOfRows)) return false; if ((i<0)||(j<0)) return false; rat.putFoodAt(new Point(i,j)); //decrease the amount of food left foodLeft-=(int)20*noOfSmellBlocks/noOfRows; //update the graphics updateGraphics(); if (foodLeft<=0) { gameLost(); } //pc.drawFoodBar(foodLeft); return true; } } /** update all the graphics */ public void updateGraphics(){ pc.drawTimeBar(rat.getEnergy()); pc.drawFoodBar(foodLeft); mc.drawAllRatAndFood(mz,home,rat.getRatPosition(),ratImage,rat.getFoodPosition(),cheese); } /** stop all the thread and display the game over graphics */ private void gameOver(){ gameOver=true; foodLeft=100; if (rat!=null){ rat.gameOver(); rat=null; } } /** this will display the user about his winning the game */ public void gameWon(){ gameOver(); mc.gameWon(); } /** displayed when the user has lost the game */ public void gameLost(){ gameOver(); mc.gameLost(); } /** this method when called the old game starts again from fresh */ public void makePlayAgain(){ gameOver=true; playNewGame=true; } /** starts a new game from scartch */ public void startNewGame(){ /* if the threads are not there initialise them */ if (rat!=null) { rat.gameOver(); rat=null;} if (mazeThread==null) start(); noOfCols=noOfRows=cp.getGameLevel(); noOfSmellBlocks=cp.getSensingPower(); /* generate the maze and draw the static diagrams */ generate(); /* assume that the player doesnot want to play this shit game again */ playNewGame=false; /* get the energy of the rat */ int lastEnergy=rat.getEnergy(); /* draw the colour ful bars */ pc.drawTimeBar(rat.getEnergy()); pc.drawFoodBar(foodLeft); mc.drawAllRatAndFood(mz,home,rat.getRatPosition(),ratImage,rat.getFoodPosition(),cheese); gameOver=false; while(!gameOver){ /* sleep for some time before moving to next block, gives better look at game */ sleep(200); if (rat==null) break; /* look that the energy of that rat has not decreasded in the mean time */ if (lastEnergy!=rat.getEnergy()){ lastEnergy=rat.getEnergy(); pc.drawTimeBar(lastEnergy); if (lastEnergy<=0) { gameLost(); break; } } /* see if there is any food to be eaten by the rat */ if(rat.anyFoodNearBy(rat.getRatPosition(),noOfSmellBlocks).x!=-1){ Point p=new Point(rat.anyFoodNearBy(rat.getRatPosition(),noOfSmellBlocks).x,rat.anyFoodNearBy(rat.getRatPosition(),noOfSmellBlocks).y); rat.moveRatAt(p.x,p.y); rat.increaseEnergy(); updateGraphics(); } /* if the rat has come to the last position the game has been won */ if ((rat.getRatPosition().x==mz.getEnd().x)&&((rat.getRatPosition().y==mz.getEnd().y))){ gameWon(); gameOver=true; break; } } }//:~startNewGame } /** * PanelCanvas takes care of the image display of the food and time left for the player. */ class PanelCanvas extends Canvas{ private int width,height; Image bufferImage; Image time,food; Graphics buffer; /** * height and width of the panel */ PanelCanvas(int pcw,int pch){ width=pcw; height=pch; } /** initialization of the panel */ public void init(){ if (buffer==null){ bufferImage=createImage(width,height); buffer=bufferImage.getGraphics(); } //assign the back ground black buffer.setColor(Color.black); buffer.fillRect(0,0,width,height); } /** draw the two images of hour clock and glass with water */ public void drawStaticImage(Image time,Image food){ this.time=time; this.food=food; if (buffer==null) init(); buffer.drawImage(food,0,20,this); buffer.drawImage(time,0,50,this); repaint(); } /** draw the bar associated with the food; * integer parameter specifies the percent of the food left */ synchronized public void drawFoodBar(int foodLeft){ int barwidth=75,barheight=24; int timewidth=20; int startHeight=50+7; buffer.setColor(Color.white); buffer.draw3DRect(timewidth+10,startHeight,barwidth+timewidth+10,barheight,false); buffer.setColor(Color.black); buffer.fillRect(timewidth+10+2,startHeight+2,barwidth+timewidth+10-2,barheight-2); buffer.setColor(Color.red); buffer.fillRect(timewidth+10+2,startHeight+2,(int)((barwidth+timewidth+10-2)*foodLeft/100),barheight-2); repaint(); } /** draw the bar associated with the time * the interger parameter represents the percent of time left */ synchronized public void drawTimeBar(int timeLeft){ int barwidth=75,barheight=24; int timewidth=20; int startHeight=20; buffer.setColor(Color.white); buffer.draw3DRect(timewidth+10,startHeight,barwidth+timewidth+10,barheight,false); buffer.setColor(Color.black); buffer.fillRect(timewidth+10+2,startHeight+2,barwidth+timewidth+10-2,barheight-2); buffer.setColor(Color.red); buffer.fillRect(timewidth+10+2,startHeight+2,(int)(((barwidth+timewidth+10-2)*timeLeft)/100),barheight-2); repaint(); } /** use of double buffering to avoid flicker */ public void paint(Graphics g){ update(g);} public void update(Graphics g){ if (bufferImage!=null) g.drawImage(bufferImage,0,0,this); } }