PDA

View Full Version : Break My Game! (Java Edition)



flibitijibibo
May 1st, 2009, 04:03 PM
So a friend and I have been making our own version of Pong for the final project (real original, amirite), and we're pretty much 100% finished with it. We have 2 weeks left, so what I really want to do is just test it as much as I can to make sure that everything works the way it should, because I'd also like to publish it to the interwebs if it's entertaining enough. So, because I <3 you guys so much, I'm giving you the game to play and/or test. Most of it is testing the physics, but if you play this and find any other issues (other than "it sucks"), just lemme know.

You'll also notice that there is a benchmark tool in here. If you want, you can set enableTool to true, and the goal is to have the console print "hit" once every second. If your PC gets something really different, you can modify SleepTime to get it to that rate. If you have to do this, post your specs (if it's not in your profile) and the SleepTime you had to use to get it to 1 per second.

Pong.java:

import java.applet.Applet;
import java.awt.*;
public class Pong extends Applet implements Runnable{
//Program/Window Variables
private Thread thread;
private final int SleepTime = 16;
private final int HEIGHT = 600;
private final int WIDTH = 1200;
public static boolean isInitialized;
//Gameplay Variables
private boolean play1Up, play1Down, play2Up, play2Down;
private int play1Points = 0, play2Points = 0;
private int serving;
private int gameWinner;
public static int level = 2;
public static int scoreCap;
//Physics Variables
private Box boxes[] = new Box[2];
private Box pong[] = new Box[2];
private Box ball = new Box(0, 10, 0, 10, 0, 0, "Ball");
//Graphics Variables
private Graphics nextFrame;
private Image nextImage;
//Splash Screen
private SplashScreen mainMenu = new SplashScreen("Pong!");
//Benchmark Tool Variables
private int benchmarkTool = 0;
public static boolean enableTool = false;

public void init(){
mainMenu.setVisible(true);
mainMenu.setSize(155, 220);
mainMenu.setResizable(false);
setFocusable(true);
setSize(WIDTH, HEIGHT);
boxes[0] = new Box(0, WIDTH, 550, 2000, 0, 0, "Lower Box");
boxes[1] = new Box(0, WIDTH, -1000, 50, 0, 0, "Upper Box");
pong[0] = new Box(50, 70, 250, 350, 0, 0, "Left Pong");
pong[1] = new Box(WIDTH - 70, WIDTH - 50, 250, 350, 0, 0, "Right Pong");
resetBall(1);
setBackground(Color.BLACK);
thread = new Thread(this);
thread.start();
}
public void run(){
do{
try {
if (isInitialized){
//Player Movement
if (play1Up)
pong[0].setVelY(-10);
else if (play1Down)
pong[0].setVelY(10);
else if (!play1Up || !play1Down)
pong[0].setVelY(0);
if (level == 0){
if (play2Up)
pong[1].setVelY(-10);
else if (play2Down)
pong[1].setVelY(10);
else if (!play2Up || !play2Down)
pong[1].setVelY(0);
}
else
determineComputerMove();
//Point Check
if (ball.getLeft() > WIDTH){
play1Points++;
resetBall(1);
}else if (ball.getRight() < 0){
play2Points++;
resetBall(2);
}
if (scoreCap != 0){
if (play1Points == scoreCap){
resetGame(1);
}
else if (play2Points == scoreCap){
resetGame(2);
}
}
//Physics
if (!findCollisions(ball, pong) && !findCollisions(ball, boxes))
ball.setVelY(ball.getVelY() + ball.getAngVelocity() * ball.getWidth() / 24 * Math.signum(ball.getVelX()));
findCollisions(pong[0], boxes);
findCollisions(pong[1], boxes);
findCollisions(pong[0], ball);
findCollisions(pong[1], ball);
//Serve Mechanic
if (serving != 0){
if (serving == 1)
ball.setVelY(pong[0].getVelY());
else
ball.setVelY(pong[1].getVelY());
}
//Pong/Ball Movements
for (int i = 0; i < pong.length; i++){
pong[i].addToVertical(pong[i].getVelY());
}
ball.addToHorizontal(ball.getVelX());
ball.addToVertical(ball.getVelY());
//Graphics Update
repaint();
//Benchmark Tool
if (enableTool){
benchmarkTool++;
if (benchmarkTool == 60){
benchmarkTool = 0;
System.out.println("hit");
}
}
//Thread Update
Thread.sleep(SleepTime);
}else{
//Key Lock for Menus
play1Up = false;
play2Up = false;
play1Down = false;
play2Down = false;
}
}
catch (InterruptedException e){}
}while (true);
}

//Physics Methods

private boolean findCollisions(Box object, Box[] blocker){
boolean horDetected = false, vertDetected = false;

for (int i = 0; i < blocker.length && (!horDetected || !vertDetected); i++){
double Hor = object.getVelX(), Vert = object.getVelY();
if (vertCollision(object, Vert, blocker[i]) && !vertDetected){
determineCollisionPath(object, blocker[i], true);
vertDetected = true;
}
else if (horCollision(object, Hor, blocker[i]) && !horDetected){
determineCollisionPath(object, blocker[i], false);
horDetected = true;
}
}
if (horDetected || vertDetected)
return true;
else
return false;
}
private boolean findCollisions(Box object, Box blocker){
boolean horDetected = false, vertDetected = false;
double Hor = object.getVelX(), Vert = object.getVelY();

if (vertCollision(object, Vert, blocker) && !vertDetected){
determineCollisionPath(object, blocker, true);
vertDetected = true;
}
else if (horCollision(object, Hor, blocker) && !horDetected){
determineCollisionPath(object, blocker, false);
horDetected = true;
}
if (horDetected || vertDetected)
return true;
else
return false;
}
private boolean horCollision(Box movingBox, double Hor, Box stillBox){
Box tempBox = new Box(movingBox);

tempBox.addToHorizontal(Hor);
if (isIntersecting(tempBox, stillBox, Hor, 0)){
return true;
}
return false;
}
private boolean vertCollision(Box movingBox, double Vert, Box stillBox){
Box tempBox = new Box(movingBox);

tempBox.addToVertical(Vert);
if (isIntersecting(tempBox, stillBox, 0, Vert)){
return true;
}
return false;
}
private boolean isIntersecting(Box box1, Box box2, double Hor, double Vert){
int right = box2.getRight() + box1.getWidth();
int left = box2.getLeft() - box1.getWidth();
int top = box2.getTop() - box1.getHeight();
int bottom = box2.getBottom() + box1.getHeight();
Box compositeBox = new Box(box2);

compositeBox.changeSize(left, right, top, bottom);
if (box1.getTop() > compositeBox.getTop()
&& box1.getBottom() < compositeBox.getBottom()
&& box1.getLeft() > compositeBox.getLeft()
&& box1.getRight() < compositeBox.getRight())
return true;
return false;
}
private void determineCollisionPath(Box object, Box blocker, boolean Vert){
if (Vert){
object.setVelX(object.getVelX() + object.getAngVelocity() * Math.signum(object.getVelY()));
blocker.setVelY(object.getVelY() + blocker.getVelY());
if (object.getVelY() != 0){
if (Math.abs(object.getVelY()) < 1)
object.setVelY(0);
if (blocker.getVelY() * object.getVelY() < 0)
object.setVelY(object.getVelY());
else
object.setVelY(-object.getVelY());
}
}else{
object.setVelY(object.getVelY() + object.getAngVelocity() * -Math.signum(object.getVelX()));
if (object.getVelX() != 0){
if ((blocker.getVelY() > 0 && object.getVelX() < 0) || (blocker.getVelY() < 0 && object.getVelX() > 0))
object.addAngVelocity(-Math.abs(blocker.getVelY() / object.getWidth() / 2));
else if ((blocker.getVelY() < 0 && object.getVelX() < 0) || (blocker.getVelY() > 0 && object.getVelX() > 0))
object.addAngVelocity(Math.abs(blocker.getVelY() / object.getWidth()/2));
object.setVelX(-object.getVelX());
}
}
}

//Gameplay Methods

private void determineComputerMove(){
if (serving == 2 && ball.getRight() == pong[1].getLeft()){
serving = 0;
ball.setVelX(-10);
}else{
int aiSpeed;
int aiReact;
if (level == 1){
aiSpeed = 5;
aiReact = 700;
}
else if (level == 2){
aiSpeed = 10;
aiReact = 400;
}
else{
aiSpeed = 15;
aiReact = 0;
}
if (ball.getRight() < aiReact || ball.getVelX() < 0)
pong[1].setVelY(0);
else if (ball.getTop() > (pong[1].getBottom() - pong[1].getHeight() / 2))
pong[1].setVelY(aiSpeed);
else if (ball.getBottom() < (pong[1].getBottom() - pong[1].getHeight() / 2))
pong[1].setVelY(-aiSpeed);
else
pong[1].setVelY(0);
}
}
private void resetBall(int player){
if (player == 1){
ball.setHorizontal(pong[0].getRight());
ball.setVertical(pong[0].getTop() + pong[0].getHeight() / 2 - ball.getHeight() / 2);
} else if (player == 2){
ball.setHorizontal(pong[1].getLeft() - ball.getWidth());
ball.setVertical(pong[1].getTop() + pong[1].getHeight() / 2 - ball.getHeight() / 2);
}
ball.setVelY(0);
ball.setVelX(0);
ball.setAngVelocity(0);
serving = player;
}
private void resetGame(int winner){
isInitialized = false;
gameWinner = winner;
mainMenu.setVisible(true);
pong[0].setVertical(250);
pong[1].setVertical(250);
resetBall(1);
}

//Player Control Methods

public boolean keyDown(Event evtobj, int keyPressed){
String key = "";
key += (char)keyPressed;
key = key.toLowerCase();
if (key.equals("w")){
play1Up = true;
return true;
}
if (key.equals("s")){
play1Down = true;
return true;
}
if (key.equals("d") && serving == 1){
serving = 0;
ball.setVelX(10);
ball.setVelY(ball.getVelY() / 2);
}
switch (keyPressed){
case Event.UP:
play2Up = true;
return true;
case Event.DOWN:
play2Down = true;
return true;
case Event.LEFT:
if (serving == 2){
serving = 0;
ball.setVelX(-10);
ball.setVelY(ball.getVelY() / 2);
}
}
return false;
}
public boolean keyUp(Event evtobj, int keyPressed){
String key = "";
key += (char)keyPressed;
key = key.toLowerCase();
if (key.equals("w")){
play1Up = false;
return true;
}else if (key.equals("s")){
play1Down = false;
return true;
}
switch (keyPressed){
case Event.UP:
play2Up = false;
return true;
case Event.DOWN:
play2Down = false;
return true;
}
return false;
}

//Graphics Methods

public void paint(Graphics g){
if (nextFrame != null){
g.drawImage(nextImage, 0, 0, null);
}
}
public void update(Graphics g){
Dimension dim = this.getSize();
if (nextFrame == null || nextImage.getWidth(null) != dim.width || nextImage.getHeight(null) != dim.height){
nextImage = createImage(dim.width, dim.height);
nextFrame = nextImage.getGraphics();
nextFrame.setColor(getBackground());
nextFrame.fillRect(0, 0, dim.width, dim.height);
nextFrame.setColor(Color.WHITE);
paintBoxes(nextFrame);
}
nextFrame.setColor(getBackground());
nextFrame.fillRect(0, 0, dim.width, dim.height);
paintBoxes(nextFrame);
g.drawImage(nextImage, 0, 0, null);
}
private void paintBoxes(Graphics nextFrame){
nextFrame.setColor(Color.blue);
for (int i = 0; i < boxes.length; i++)
nextFrame.fillRect(boxes[i].getLeft(), boxes[i].getTop(), boxes[i].getWidth(), boxes[i].getHeight());
nextFrame.setColor(Color.GREEN);
for (int i = 0; i < pong.length; i++)
nextFrame.fillRect(pong[i].getLeft(), pong[i].getTop(), pong[i].getWidth(), pong[i].getHeight());
nextFrame.fillOval(ball.getLeft(), ball.getTop(), ball.getWidth(), ball.getHeight());
nextFrame.setFont(new Font("Arial", Font.BOLD, 24));
nextFrame.setColor(Color.cyan);
nextFrame.drawString("Player 1: " + play1Points, 450, 100);
nextFrame.drawString("Player 2: " + play2Points, 600, 100);
if (!isInitialized){
nextFrame.drawString("Player " + gameWinner + " wins!", 510, 300);
play1Points = 0;
play2Points = 0;
}
}
}
Box.java:

public class Box {
private int left, right, top, bottom, width, height;
private double velX, velY, angVelocity;
private String name;

Box(int Left, int Right, int Top, int Bottom, double VelX, double VelY, String Name){
left = Left;
top = Top;
right = Right;
bottom = Bottom;
width = right - left;
height = bottom - top;
velX = VelX;
velY = VelY;
name = Name;
angVelocity = 0;
}
Box(Box box){
left = box.getLeft();
top = box.getTop();
right = box.getRight();
bottom = box.getBottom();
width = box.getWidth();
height = box.getHeight();
velX = box.getVelX();
velY = box.getVelY();
name = box.getName();
}
public int getLeft(){
return left;
}
public int getRight(){
return right;
}
public int getTop(){
return top;
}
public int getBottom(){
return bottom;
}
public int getHeight(){
return height;
}
public int getWidth(){
return width;
}
public String getName(){
return name;
}
public void changeSize(int Left, int Right, int Top, int Bottom){
left = Left;
top = Top;
right = Right;
bottom = Bottom;
width = right - left;
height = bottom - top;
}
public double getVelX(){
return velX;
}
public double getVelY(){
return velY;
}
public double getAngVelocity(){
return angVelocity;
}
public void setHorizontal(int deltaX){
left = deltaX;
right = left + width;
}
public void setVertical(int deltaY){
top = deltaY;
bottom = top + height;
}
public void addToHorizontal(double deltaX){
if (Math.abs(deltaX) < 1)
deltaX = 0;
left += deltaX;
right = left + width;
}
public void addToVertical(double deltaY){
if (Math.abs(deltaY) < 1)
deltaY = 0;
top += deltaY;
bottom = top + height;
}
public void addAngVelocity(double ang){
angVelocity += ang;
}
public void setVelX(double VelX){
velX = VelX;
}
public void setVelY(double VelY){
velY = VelY;
}
public void setAngVelocity(double ang){
angVelocity = ang;
}
public String display(){
return name + ": " + "Top = " + top + " Bottom = " + bottom + " Left = " + left + " Right = " + right + " VelX = " + velX + " VelY = " + velY + " angVelocity = " + angVelocity;
}
}
SplashScreen.java:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SplashScreen extends Frame{
private JButton start = new JButton("Start Game");
private JButton help = new JButton("Instructions");
private JLabel modeDirections = new JLabel("Select Mode:");
private JRadioButton easy = new JRadioButton("Easy");
private JRadioButton normal = new JRadioButton("Normal");
private JRadioButton hard = new JRadioButton("Hard");
private JRadioButton twoPlay= new JRadioButton("2 Player");
private JLabel scoreDirections = new JLabel("Score to Win:");
private JTextField scoreCapInput = new JTextField("0", 2);
private JLabel scoreNotes = new JLabel("999 = Max, 0 = No End");
private ButtonGroup group = new ButtonGroup();
private JPanel panel;
private Instructions helpMenu = new Instructions("Pong!");

SplashScreen(String title){
super(title);
panel= new JPanel();
panel.setBackground(Color.CYAN);
start.setBackground(Color.GREEN);
help.setBackground(Color.GREEN);
twoPlay.setBackground(null);
easy.setBackground(null);
normal.setBackground(Color.GREEN);
hard.setBackground(null);
normal.setSelected(true);
start.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
boolean valid;
try{
Pong.scoreCap = Integer.parseInt(scoreCapInput.getText());
if (Pong.scoreCap > 999 || Pong.scoreCap < 0)
throw new Exception();
valid = true;
}catch(Exception e){
valid = false;
scoreCapInput.setText("");
}
if (valid){
Pong.isInitialized = true;
setVisible(false);
helpMenu.setVisible(false);
}
}
});
help.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
helpMenu.setVisible(true);
helpMenu.setSize(300,155);
helpMenu.setResizable(false);
}
});
twoPlay.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Pong.level = 0;
twoPlay.setBackground(Color.GREEN);
easy.setBackground(null);
normal.setBackground(null);
hard.setBackground(null);
}
});
easy.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Pong.level = 1;
easy.setBackground(Color.GREEN);
twoPlay.setBackground(null);
normal.setBackground(null);
hard.setBackground(null);
}
});
normal.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Pong.level = 2;
normal.setBackground(Color.GREEN);
twoPlay.setBackground(null);
easy.setBackground(null);
hard.setBackground(null);
}
});
hard.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Pong.level = 3;
hard.setBackground(Color.GREEN);
twoPlay.setBackground(null);
normal.setBackground(null);
easy.setBackground(null);
}
});
group.add(twoPlay);
group.add(easy);
group.add(normal);
group.add(hard);
panel.add(start);
panel.add(help);
panel.add(modeDirections);
panel.add(twoPlay);
panel.add(easy);
panel.add(normal);
panel.add(hard);
panel.add(scoreDirections);
panel.add(scoreCapInput);
add(panel);
}
public boolean handleEvent(Event evt){
if (evt.id == Event.WINDOW_DESTROY){
System.exit(0);
return true;
}
return false;
}
}
Instructions.java:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Instructions extends Frame{
private JPanel panel = new JPanel();
private JLabel panelTitle = new JLabel("Instructions:");
private JLabel moveUp = new JLabel("Move Up: W (Player 1), Up Arrow (Player 2)");
private JLabel moveDown = new JLabel("Move Down: S (Player 1), Down Arrow (Player 2)");
private JLabel serve = new JLabel("Serve ball: D (Player 1), Left Arrow (Player 2)");
private JButton close = new JButton("OK");

Instructions(String title){
super(title);
setVisible(false);
panel.add(panelTitle);
panel.add(moveUp);
panel.add(moveDown);
panel.add(serve);
close.setBackground(Color.GREEN);
close.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
setVisible(false);
}
});
panel.setBackground(Color.CYAN);
panel.add(close);
this.add(panel);
}
public boolean handleEvent(Event evt){
if (evt.id == Event.WINDOW_DESTROY){
System.exit(0);
return true;
}
return false;
}
}