/* * MELFBLOCK (based on Breakout) * Code Written by Melissa Fedak * October 2005 * * * THIS GAME IS ESSENTIALLY "BREAKOUT" * PLAYER TRIES TO HIT ALL THE BLOCKS WITH THE BALL * * THERE ARE FOUR CLASSES IN THIS GAME: * BLOCK - EACH RECTANGULAR BLOCK THAT THE BALL HITS * BLOCKCANVAS - THE CENTRAL AREA WHERE MOST OF THE ACTION TAKES PLACE (MOUSEEVENTS) * SCOREPANEL - WHERE THE SCORE AND SPEED ARE KEPT TRACK OF (BUTTON ACTIONEVENTS) * MELFBLOCK - THE MAIN APPLET THAT EVERYTHING ELSE IS BASED OFF OF * * * */ import java.applet.*; import java.awt.*; import java.awt.event.*; //NEEDED FOR MOUSE import java.awt.font.*; //NEEDED FOR FONT import java.awt.geom.*; //NEEDED FOR BALL import java.lang.Integer.*; //==================================================================== //==================================================================== //THIS IS A SMALL CLASS FOR THE RECTANGULAR BLOCKS PLAYER TRIED TO HIT class Block extends Rectangle { Boolean on; Boolean solid; //IF IT'S SOLID, IT CAN'T BE BROKEN Color blockColor; public Block(int xval, int yval, int w, int h) { //*NOT* VOID; CONSTRUCTOR RETURNS A BLOCK! on = true; solid = false; x = xval; y = yval; width = w; height = h; blockColor = Color.black; } public void turnOn() { on = true; } public Boolean turnOff() { if (solid == false) { //"SOLID" NOT USED YET; ALWAYS FALSE FOR NOW on = false; blockColor = Color.black; return true; } return false; } //NOT USED YET - FOR FUTURE FUNCTIONALITY public void makeSolid () { solid = true; setSpecificBlockColor(0); } //NOT USED YET - FOR FUTURE FUNCTIONALITY public void setSpecificBlockColor(int temp) { if (temp == 0) blockColor = Color.darkGray; else if (temp == 1) blockColor = new Color(64, 128, 128); else if (temp == 2) blockColor = new Color(128, 64, 64); else if (temp == 3) blockColor = new Color(128, 64, 128); else blockColor = new Color(128, 128, 64); } } //==================================================================== //==================================================================== //THIS IS THE MAIN CANVAS WHRE INPUT IS RECEIVED AND GAME TAKES PLACE class BlockCanvas extends Canvas implements MouseListener, MouseMotionListener { //VARIABLES //WIDTH AND HEIGHT OF ALL RECTANGLES IN GAME (BLOCKS AND PLAYER) int rectWidth, rectHeight; //NUMBER OF COLUMNS AND ROWS IN DOUBLE ARRAY OF BLOCKS int blockRows, blockColumns; //CURRENT X AND Y CORDINATE OF BALL (UPPER LEFT HAND CORNER) int happyBallX, happyBallY; //STATE VARIABLES FOR STATUS OF BALL AND GAME Boolean gameStarted; Boolean gameOver; Boolean ballFree; Boolean lifeOver; //KEY OBJECTS IN GAME Rectangle playerRect; Block[][] blockArray; Image happyBall; //NUMBER OF BLOCKS (SO GAME KNOWS WHEN WE'VE WON WITHOUT ITERATING) int numBlocks; //VARIABLES FOR PAINTING ONSCREEN AND OFFSCREEN (TO AVOID FLICKERING) Color currColor; //MAIN COLOR OF BORDER AND PLAYER RECTANGLE Font currFont; Image offScreenImage; Graphics offScreenGraphics; //LINK BACK TO PARENT MelfBlock theApplet; public BlockCanvas(Color c, MelfBlock parent) { playerRect = new Rectangle(rectWidth, rectHeight); theApplet = parent; numBlocks = 0; //INITIALIZE GAME STATUS gameStarted = false; gameOver = false; ballFree = false; lifeOver = false; //SET BALL IMAGES happyBall = theApplet.happyFace; //BALL LOCATION (INIT TO 0 FOR NOW) happyBallX = 0; happyBallY = 0; //SIZE OF THE MAIN PLAYER RECTANGLE (INIT TO 0 FOR NOW) rectWidth = 0; rectHeight = 0; //FOR MOUSE CLICKING AND MOVING INPUT addMouseListener(this); addMouseMotionListener(this); currColor = c; currFont = new Font("Arial", 1, 14); //INEXPLICABLY DOESN'T KNOW "BOLD" OR Color.BOLD setBackground(new Color(0,0,0)); //NOTE: CANVAS DOES NOT KNOW ITS OWN WIDTH OR HEIGHT IN THE CONSTRUCTOR //THEREFORE, MANY VARIABLES ARE INITIALIZED LATER, IN setConstants() BELOW } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //THIS FUNCTION INITIALIZES KEY VARIABLES AND OBJECTS //WHEN GAME IS STARTING AND CANVAS SIZE IS KNOWN public void setConstants() { rectWidth = (int)getWidth()/10; rectHeight = (int)getHeight()/25; blockRows = (int)getWidth()/rectWidth; blockColumns = (int)getHeight()/rectHeight/2; theApplet.statPanel.score.setText("00000"); theApplet.currFace = happyBall; blockArray = new Block[blockRows][blockColumns]; numBlocks = 0; //INITIALIZE ALL BLOCKS for (int i = 0; i < blockRows; i++) for (int j = 0; j < blockColumns; j++) { blockArray[i][j] = new Block(i*rectWidth, j*rectHeight, rectWidth, rectHeight); //if not solid: blockArray[i][j].blockColor = theApplet.chooseColor(); numBlocks++; } gameOver = false; gameStarted = true; theApplet.youWin = false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //THIS FUNCTION MOVES PLAYER RECTANGLE WHEN MOUSE IS MOVED public void mouseMoved(MouseEvent e) { if (gameStarted) { //IF MOUSE IS WITHIN CANVAS AREA, MOVE RECTANGLE, OR MOVE IT TO NEAREST EDGE if (e.getX() < rectWidth/2) { playerRect.setLocation(0, getHeight() - rectHeight*2); } else if (e.getX() > getWidth() - rectWidth/2) { playerRect.setLocation(getWidth() - rectWidth,getHeight() - rectHeight*2); } else { // if (e.getX() >= rectWidth/2 && e.getX() <= getWidth() - rectWidth/2) playerRect.setLocation(e.getX() - rectWidth/2, getHeight() - rectHeight*2); } //IF BALL ISN'T 'FREED' KEEP BALL FOLLOWING ABOVE RECTANGLE UNTIL CLICKED if (!ballFree) { happyBallX = (int)playerRect.getX() + rectWidth/2 - happyBall.getWidth(this)/2; happyBallY = (int)playerRect.getY() - happyBall.getHeight(this); } repaint(); } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //THIS FUNCTION CONTROLS WHEN A NEW GAME HAS STARTED //AND STARTS BALL MOVING ("FREES BALL") IF IT HAS NOT YET public void mouseReleased(MouseEvent e) { //IF WE ARE IN LIMBO BETWEEN THE GAME STARTING AND THE GAME ENDING if (!gameStarted || gameOver) { //RESET VARIABLES setConstants(); //SET BALL AND RECTANGLE IN INITIAL POSITIONS playerRect.setLocation(getWidth()/2 - rectWidth/2, getHeight() - rectHeight*2); happyBallX = (int)(playerRect.getX() + rectWidth/2 - happyBall.getWidth(this)/2); happyBallY = (int)playerRect.getY() - happyBall.getHeight(this); } //IF MOUSE IS CLICKED BUT GAME HAS ALREADY STARTED, FREE THE BALL else if (gameStarted && !ballFree) { ballFree = true; } //OTHERWISE, DO NOTHING; CLICKING IS IRRELEVANT DURING THE GAME repaint(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //THESE FUNCTIONS OVERRIDE ALL MOUSE EVENTS, EVEN THAT I DON'T USE, AS REQUIRED BY JAVA public void mouseClicked(MouseEvent e) { } public void mouseDragged(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //THE THREE BELOW FUNCTIONS PAINT THE CURRENT POSITION OF BLOCKS, //PLAYER RECTANGLE, AND BALL TO SCREEN USING OFFSCREEN GRAPHICS TO AVOID FLICKERING //OVERRIDING UPDATE TO AVOID FLICKERING public void update(Graphics g) { paint(g); } public void doOffScreenPainting() { if (offScreenImage == null) { // || graphicsWidth != getWidth() || graphicsHeight != getHeight()) { offScreenImage = createImage((int)getWidth(), (int)getHeight()); offScreenGraphics = offScreenImage.getGraphics(); } offScreenGraphics.setColor(Color.black); offScreenGraphics.fillRect(0, 0, getWidth(), getHeight()); offScreenGraphics.setColor(getBackground()); offScreenGraphics.fillRect(0,0,getWidth(),getHeight()); offScreenGraphics.setColor(currColor); //PAINT "ON" BLOCKS WITH BLOCK COLOR for (int i = 0; i < blockRows; i++) { for (int j = 0; j < blockColumns; j++) { if (blockArray[i][j].on) { offScreenGraphics.setColor(blockArray[i][j].blockColor); offScreenGraphics.fill3DRect(i*rectWidth, j*rectHeight, rectWidth, rectHeight, true); } } } //SET BACK TO MAIN COLOR offScreenGraphics.setColor(currColor); if (theApplet.youWin) { String s = "YOU WIN! YAY!!"; String t = "Score: "; String u = "* Click to Start Again *"; offScreenGraphics.setFont(currFont); offScreenGraphics.fillRect(getWidth()/2 - 100, getHeight()/2 - 100, 200, 200); offScreenGraphics.drawImage(happyBall, getWidth()/2 - happyBall.getWidth(this), getHeight()/2 - 100 + 40, this); offScreenGraphics.setColor(new Color(255,255,255)); offScreenGraphics.drawString(s, getWidth()/2 - 100 + 48, 200); offScreenGraphics.drawString(t, getWidth()/2 - 100 + 53, 230); offScreenGraphics.drawString(theApplet.statPanel.score.getText(), getWidth()/2 - 100 + 130, 230); offScreenGraphics.drawString(u, getWidth()/2 - 100 + 40, 260); } else if (gameOver) { String s = "GAME OVER"; String t = "Score: "; String u = "* Click to Start Again *"; offScreenGraphics.setFont(currFont); offScreenGraphics.fillRect(getWidth()/2 - 100, getHeight()/2 - 100, 200, 200); offScreenGraphics.drawImage(theApplet.currFace, getWidth()/2 - happyBall.getWidth(this)/2, getHeight()/2 - 100 + 40, this); offScreenGraphics.setColor(new Color(255,255,255)); offScreenGraphics.drawString(s, getWidth()/2 - 100 + 54, 200); offScreenGraphics.drawString(t, getWidth()/2 - 100 + 56, 230); offScreenGraphics.drawString(theApplet.statPanel.score.getText(), getWidth()/2 - 100 + 111, 230); offScreenGraphics.drawString(u, getWidth()/2 - 100 + 25, 260); } else if (gameStarted) { //PAINTS BALL AND PLAYER RECTANGLE IN THEIR CURRENT POSITONS offScreenGraphics.fill3DRect((int)playerRect.getX(), (int)playerRect.getY(), rectWidth, rectHeight, true); offScreenGraphics.drawImage(theApplet.currFace, happyBallX, happyBallY, this); } else { //IF IT IS THE FIRST SCREEN OF THE GAME String s = "Bounce the Ball"; String t = "and Break the Blocks!"; String u = "* Click to Begin *"; offScreenGraphics.setFont(currFont); offScreenGraphics.fillRect(getWidth()/2 - 100, getHeight()/2 - 100, 200, 200); offScreenGraphics.drawImage(theApplet.bounceFace, getWidth()/2- happyBall.getWidth(this)/2, getHeight()/2 - 100 + 40, this); offScreenGraphics.drawImage(theApplet.oopsFace, getWidth()/2- happyBall.getWidth(this)/2, getHeight()/2 - 100 + 40, this); offScreenGraphics.drawImage(theApplet.currFace, getWidth()/2 - happyBall.getWidth(this)/2, getHeight()/2 - 100 + 40, this); offScreenGraphics.setColor(new Color(255,255,255)); offScreenGraphics.drawString(s, getWidth()/2 - 100 + 43, 200); offScreenGraphics.drawString(t, getWidth()/2 - 100 + 22, 230); offScreenGraphics.drawString(u, getWidth()/2 - 100 + 40, 260); } } public void paint(Graphics g) { doOffScreenPainting(); g.drawImage(offScreenImage, 0, 0, this); } } //==================================================================== //==================================================================== // SCORE PANEL CLASS (THE LOWEST PANEL WHERE SCORE AND SPEED (AND LATER, TIME) ARE LOCATED class ScorePanel extends Panel implements ActionListener { Button speedUpButton; Button speedDownButton; Label scoreLabel; Label score; Label time; Label speedLabel; Label speed; int scoreInc; int pauseTime; Font mainFnt; Font smallFnt; MelfBlock theApplet; ScorePanel(MelfBlock parent, Font f) { theApplet = parent; scoreInc = 10; pauseTime = 8; //SPEED = 2; mainFnt = f; smallFnt = new Font("Arial", 0, 10); Panel p = new Panel(); p.setLayout(new FlowLayout(FlowLayout.CENTER)); /* WILL IMPLEMENT LATER time = new Label("0:00"); time.setFont(smallFnt); time.setBackground(theApplet.mainColor); p.add(time); */ Label spacer = new Label(" "); spacer.setBackground(theApplet.mainColor); p.add(spacer); scoreLabel = new Label("Score:"); scoreLabel.setFont(smallFnt); scoreLabel.setBackground(theApplet.mainColor); p.add(scoreLabel); //GET SCORE VALUE FROM VALUE SENT IN BY APPLET score = new Label("00000"); score.setFont(mainFnt); score.setBackground(theApplet.mainColor); p.add(score); Label spacer2 = new Label(" "); spacer2.setBackground(theApplet.mainColor); p.add(spacer2); speedDownButton = new Button(" - "); speedDownButton.setFont(mainFnt); p.add(speedDownButton); speedDownButton.addActionListener(this); speedUpButton = new Button(" + "); //INCREASE SPEED = DECREASE PAUSE TIME speedUpButton.setFont(mainFnt); p.add(speedUpButton); speedUpButton.addActionListener(this); Label spacer3 = new Label(" "); spacer3.setBackground(theApplet.mainColor); p.add(spacer3); speedLabel = new Label("SPEED:"); speedLabel.setFont(mainFnt); speedLabel.setBackground(theApplet.mainColor); p.add(speedLabel); speed = new Label(Integer.toString(10 - pauseTime)); speed.setFont(smallFnt); speed.setBackground(theApplet.mainColor); p.add(speed); p.add(spacer); //SPACER add(p); //Integer.parseInt(hoursWorked.getText()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //THIS STANDARD FUNCTION CATCHES WHEN THE SPEED BUTTONS ARE PRESSED public void actionPerformed(ActionEvent e) { //String arg = e.getActionCommand(); if (e.getSource() == speedUpButton) { if (pauseTime > 0) { pauseTime--; speed.setText(Integer.toString(10 - pauseTime)); speedDownButton.setEnabled(true); } else speedUpButton.setEnabled(false); } else if (e.getSource() == speedDownButton) { if (pauseTime < 10) { pauseTime++; speed.setText(Integer.toString(10 - pauseTime)); speedUpButton.setEnabled(true); } else speedDownButton.setEnabled(false); } } } //================================================================ // MAIN APPLET CLASS public class MelfBlock extends java.applet.Applet implements Runnable { private Thread runner; int xDir; //DIRECTION OF X int yDir; int xInc; //INCREMENT AMOUNT OF X int yInc; Boolean youWin; //LAYOUT Panel eastPanel; Panel westPanel; Panel topPanel; ScorePanel statPanel; //TitleCanvas topCanvas; //NOT USED AT THE MOMENT BlockCanvas mainCanvas; //FOR topPanel: Label title; Label livesLeftLabel; Label livesLeft; int maxLives; int lives; Color mainColor; Font mainFont; Image happyFace, bounceFace, oopsFace; Image currFace; public void init() { happyFace = getImage(getCodeBase(), "happyface.gif"); bounceFace = getImage(getCodeBase(), "happyfaceO.gif"); oopsFace = getImage(getCodeBase(), "happyfaceX.gif"); currFace = happyFace; youWin = false; //DIRECTION AND INCREMENTAL VALUE OF BALL xDir = 1; //RIGHT yDir = -1; //UP xInc = 1; //ALWAYS A POSITIVE INTEGER yInc = 1; //ALWAYS A POSITIVE INTEGER //score = 0; maxLives = 4; lives = maxLives; //MAKE MAIN COLOR RANDOM //mainColor = new Color((int)Math.floor(Math.random()*256),(int)Math.floor(Math.random()*256),(int)Math.floor(Math.random()*256)); mainColor = chooseColor(); mainFont = new Font("Arial", 1, 10); //CREATE MAIN CANVAS! mainCanvas = new BlockCanvas(mainColor, this); //CREATE PANEL WITH SCORE AND TIMER statPanel = new ScorePanel(this, mainFont); //CREATE TOP CANVAS WHERE TITLE AND LIVES LEFT ARE RECORDED //topCanvas = new TitleCanvas(mainColor, mainFont, happyFace); setLayout(new BorderLayout()); add(eastPanel = new Panel(), BorderLayout.EAST); add(westPanel = new Panel(), BorderLayout.WEST); add(topPanel = new Panel(), BorderLayout.NORTH); add(statPanel, BorderLayout.SOUTH); add(mainCanvas, BorderLayout.CENTER); topPanel.setBackground(mainColor); eastPanel.setBackground(mainColor); westPanel.setBackground(mainColor); statPanel.setBackground(mainColor); livesLeftLabel = new Label("Lives Left: "); livesLeftLabel.setFont(mainFont); livesLeft= new Label(Integer.toString(lives)); livesLeft.setFont(mainFont); title = new Label("WELCOME TO MELFBLOCK!"); title.setFont(mainFont); topPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 1,1)); topPanel.add(title); topPanel.add(new Label(" ")); topPanel.add(livesLeftLabel); topPanel.add(livesLeft); } public void start() { if (runner == null) { runner = new Thread(this); runner.start(); } } public void stop() { runner = null; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //THE BELOW FUNCTION ("RUN") AND ITS THREE HELPER FUNCTIONS DECIDE IF BALL NEEDS TO BOUNCE, //BOUNCE IT, CHANGE THE IMAGE TO REFLECT THAT, AND GET RID OF ANY BLOCKS IT BOUNCES AGAINST public void run() { while (true) { currFace = happyFace; //TO START //gameStarted - MOUSELISTENERS IN THE mainCanvas CLASS TAKE CARE OF THAT if (mainCanvas.ballFree == true && !youWin) { //WHILE BALL DOESN'T HIT BOTTOM while (mainCanvas.happyBallY < mainCanvas.getHeight()) { //IF NOT FALLING DOWN THE BOTTOM, MAKE IT A HAPPY FACE if (currFace != oopsFace) currFace = happyFace; //IF PLAYER RECTANGLE CATCHES BALL, BOUNCE BALL WITH BOUNCE FACE if (yDir > 0 ) { if (mainCanvas.happyBallY + happyFace.getHeight(this) == mainCanvas.getHeight() - mainCanvas.rectHeight*2) { //DO "BALL.GETHEIGHT" BECAUSE BALL'S "Y" MEASURES FROM THE TOP OF THE BALL if (ballCaughtCheck()) currFace = bounceFace; else { currFace = oopsFace; } } } //IF BALL BOUNCES AGAINST EDGE, MAKE IT A BOUNCE FACE if (ballHitsEdgeCheck()) if (currFace != oopsFace) currFace = bounceFace; //IF BALL HITS BLOCK (FUNCTION REMOVES IT AND INCREMENTS SCORE), MAKE IT A BOUNCE FACE if (ballHitsBlockCheck()) currFace = bounceFace; //UPDATE SCREEN WITH NEW BALL FACE mainCanvas.repaint(); //THE "SPEED" (AMOUNT OF PAUSE BETWEEN REPAINTS) pause(statPanel.pauseTime); //PAUSE EXTRA TO SHOW DIFF FACE if (currFace == bounceFace) pause(50); //MOVE THE BALL DIAGONALLY mainCanvas.happyBallX = mainCanvas.happyBallX + xInc*xDir; mainCanvas.happyBallY = mainCanvas.happyBallY + yInc*yDir; } //END INNER WHILE LOOP //THIS WHILE LOOP EXITS WHEN BALL HITS BOTTOM, SO BALL-LIFE IS OVER mainCanvas.lifeOver = true; lives--; livesLeft.setText(Integer.toString(lives)); if (lives < 0) gameOverReset(); else lifeOverReset(); mainCanvas.repaint(); } //END IF } //END OUTER WHILE(TRUE) LOOP } //END RUN() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //THIS HELPER FUNCTION CHECKS IF PLAYER CAUGHT BALL AS IT COMES DOWN public Boolean ballCaughtCheck() { int ballLeft = mainCanvas.happyBallX + (happyFace.getWidth(this)*3/4); int ballRight = mainCanvas.happyBallX + (happyFace.getWidth(this)/4); int rectLeft = (int)mainCanvas.playerRect.getX(); int rectRight = rectLeft + mainCanvas.rectWidth; //IF RECTANGLE 'CATCHES' BALL if (ballLeft >= rectLeft && ballRight <= rectRight) { if (yDir > 0) { //IF BALL IS GOING DOWN (IN THE POSITIVE DIRECTION), MAKE IT GO UP (IF IT IS FIRST SHOT, BALL IS ALREADY GOING UP, SO WE DON'T WANT TO MAKE IT GO DOWN) yDir = -1 * yDir; // IF EXACTLY IN CORNER AND BALL IS COMING IN AT FAR ANGLE, BOUNCE OFF OTHER SIDE if (ballLeft == rectLeft || ballLeft == rectLeft + 2 || ballLeft == rectLeft - 1) if (xDir > 0) xDir = xDir * -1; if (ballRight == rectRight || ballRight == rectRight + 1 || ballRight == rectRight - 2) if (xDir < 0) xDir = xDir * -1; return true; } } else return false; return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //THIS HELPER FUNCTION CHECKS IF BALL HAS HIT EDGE AND IF SO, BOUNCES IT public Boolean ballHitsEdgeCheck() { //IF BALL IS ON LEFT OR RIGHT SIDE, SWITCH X DIRECTION if (mainCanvas.happyBallX == mainCanvas.getWidth() - happyFace.getWidth(this) || mainCanvas.happyBallX == 0) { xDir = -1 * xDir; return true; } //IF BALL IS AT TOP, SWITCH Y DIRECTION (NOT "ELSE" IN CASE BALL IS HITTING CORNER) if (mainCanvas.happyBallY == 0) { yDir = -1 * yDir; return true; } return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //THIS HELPER FUNCTION CHECKS IF BALL HAS HIT ANY VISIBLE BLOCK FROM ABOVE OR BELOW //IF SO, IT GETS RID OF THE BLOCK (TURNS IT OFF) AND BOUNCES public Boolean ballHitsBlockCheck() { Boolean returnVal = false; String place[] = {"top", "bottom","left","right"}; int x = 0; int y = 0; //THIS FOR LOOP CHECKS WHETHER ANY OF THE FOUR POINTS ON THE SIDES OF //THE BALL CONNECT WITH ANY RECTANGLE THAT IS ON. IF SO, DELETE THAT RECTANGLE for (int i = 0; i < 4; i++) { if (place[i] == "top") { x = (int)Math.floor( (mainCanvas.happyBallX + happyFace.getWidth(this)/2) / mainCanvas.rectWidth ); y = (int)Math.floor(mainCanvas.happyBallY/mainCanvas.rectHeight); } else if (place[i] == "bottom") { x = (int)Math.floor( (mainCanvas.happyBallX + happyFace.getWidth(this)/2) / mainCanvas.rectWidth ); y = (int)Math.floor(mainCanvas.happyBallY + happyFace.getHeight(this)/mainCanvas.rectHeight); } else if (place[i] == "left") { x = (int)Math.floor( (mainCanvas.happyBallX + happyFace.getWidth(this)/2) / mainCanvas.rectWidth ); y = (int)Math.floor(mainCanvas.happyBallY + happyFace.getHeight(this)/2/mainCanvas.rectHeight); } else if (place[i] == "right") { x = (int)Math.floor( (mainCanvas.happyBallX + happyFace.getWidth(this)/2) / mainCanvas.rectWidth ); y = (int)Math.floor(mainCanvas.happyBallY + happyFace.getHeight(this)/2/mainCanvas.rectHeight); } //VALIDATE X AND Y (SO NO BAD POINTER ERRORS) if (x >= 0 && x < mainCanvas.blockRows && y >= 0 && y < mainCanvas.blockColumns) { //IF BLOCK IS ON, TURN IT OFF AND BOUNCE if (mainCanvas.blockArray[x][y].on == true) { if (mainCanvas.blockArray[x][y].turnOff()) { int temp = Integer.valueOf(statPanel.score.getText()); temp = temp + (10 - statPanel.pauseTime) * statPanel.scoreInc; statPanel.score.setText(Integer.toString(temp)); mainCanvas.numBlocks--; if (mainCanvas.numBlocks <= 0) { youWin = true; int temp2 = Integer.valueOf(statPanel.score.getText()); temp2 = temp2 + 10000; //BONUS statPanel.score.setText(Integer.toString(temp2)); gameOverReset(); } } if (place[i] == "top" || place[i] == "bottom") yDir = -1 * yDir; else xDir = -1 * xDir; returnVal = true; } else returnVal = false; } } return returnVal; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //THIS FUNCTION RESETS CERTAIN VARIABLES WHEN A BALL LIFE IS OVER public void lifeOverReset() { currFace = happyFace; mainCanvas.ballFree = false; //PUT BALL BACK INTO STARTING LOCATION mainCanvas.happyBallX = (int)mainCanvas.playerRect.getX() + mainCanvas.rectWidth/2 - happyFace.getWidth(this)/2; mainCanvas.happyBallY = (int)mainCanvas.playerRect.getY() - happyFace.getHeight(this); mainCanvas.lifeOver = false; //RESET SPEED statPanel.pauseTime = 8; statPanel.speed.setText(Integer.toString(10 - statPanel.pauseTime)); statPanel.speedUpButton.setEnabled(true); statPanel.speedDownButton.setEnabled(true); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //THIS FUNCTION RESETS CERTAIN VARIABLES WHEN THE TOTAL GAME IS OVER public void gameOverReset() { mainCanvas.gameOver = true; lives = maxLives; livesLeft.setText(Integer.toString(lives)); statPanel.pauseTime = 8; statPanel.speed.setText(Integer.toString(10 - statPanel.pauseTime)); statPanel.speedUpButton.setEnabled(true); statPanel.speedDownButton.setEnabled(true); mainCanvas.ballFree = false; mainCanvas.gameStarted = false; mainCanvas.lifeOver = false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //THIS FUNCTION IS CALLED TO GET A RANDOM COLOR FROM MY COLOR SCHEME public Color chooseColor() { //RANDOMLY PICK ONE OF FOUR COLORS int temp = (int)(Math.floor(Math.random()*4)); if (temp == 0) return new Color(64, 128, 64); else if (temp == 1) return new Color(64, 128, 128); else if (temp == 2) return new Color(128, 64, 64); else //if (temp == 3) return new Color(128, 64, 128); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //PAUSE THE THREAD public void pause(int t) { try {Thread.sleep(t); } catch (InterruptedException e) {} } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //A NECESSARY MAIN FUNCTION TO GET THE APPLET GOING? public static void main(String args[]) { MelfBlock MainMelfBlock = new MelfBlock(); MainMelfBlock.init(); MainMelfBlock.start(); //AppletFrame.startApplet("MelfBlock", "Melf Block", args); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //GET RID OF MEMORY-USING OFFSCREEN GRAPHICS public void destroy() { mainCanvas.offScreenGraphics.dispose(); } } |