/*
* 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();
}
}
|