/** * @(#)pongX.java * * * @author: Michael Cecconet * @version 2.00 2007/5/16 * @ A lot of unecessary data strucutre coding as I plan to upgrade Pong into a themed version with * @ maps that dynamically change to add a new element to pong. Say, gravitaitional fields on the map anyone? *///Collision Detection needs a lot of work :(import java.applet.*;import java.awt.*;import java.awt.event.*;import java.util.Random;//import java.Math.*;public class pongX extends Applet implements Runnable, KeyListener{ //Global Declarations private Image dbImage; private Graphics dbg; private int score1, score2, WIDTH, HEIGHT; private ball[] ballArray = new ball [1];// Handle multiple ball objects, even if only 1 is used. private paddle[] player = new paddle [2];// Create two paddles for two players. private line[] walls = new line[3];//Create the top and bottom wall. public String message =""; public String collision =""; //Utility Methods //Distance method for later usage public int distance(int pointX1, int pointY1, int pointX2,int pointY2){ int temp = (int) Math.sqrt((pointX2 - pointX1)^2 + (pointY2 - pointY1)^2); return temp; } //Ball Subclass public class ball { private int x,y,size; private double angle, speed; private double deltaX, deltaY; //Ball Reset Method (true will reset the ball position to the center.) public void reset(boolean setCenter){ Random generator = new Random(); do{ angle = generator.nextInt(359); speed = generator.nextInt(5); } while(speed==0); angle += 1; if (setCenter == true){ x = WIDTH/2; y = HEIGHT/2; } } //Ball Constructor Method public ball(int setX, int setY, int setSize){ x = setX; y = setY; size = setSize; reset(false); } //Collision Handling public void collide(int getX1, int getY1, int getX2, int getY2, int getAngle, boolean modifySpeed){ int tempX, tempY; int d = distance( getX1, getY1, getX2, getY2); for(int i = 0; i < d; i++){ //Where geometry class comes in handy, parametric equations! tempX = getX1 + i*(getX2 - getX1); tempY = getY1 + i*(getY2 - getY1); if (distance( tempX, tempY, x, y) <= size*2){ //Collision! (only one change in direction and speed per line.) angle = 2*getAngle - angle; //collision = "YES A HIT!"; if (modifySpeed == true){ //The further from the center of the the two points, the more speed will be picked up. tempX = (getX1 + getX2)/2; tempY = (getY1 + getY2)/2; speed = distance(tempX,tempY,x,y); } break; } } //collision = "No hits. :("; } //Move Method public void move(){ if (speed > 10){//Deaccelerate if at max speed, or over. speed -= .1; } deltaX = speed * Math.sin(angle); deltaY = speed * Math.cos(angle); x = x + (int)Math.round(deltaX); y = y - (int)Math.round(deltaY); message = angle+" :angle "+speed+" :speed "+deltaX+" x : y "+deltaY; } //Score Method public void score(){ score2 += (x < 0) ? 1:0; score1 += (x > WIDTH) ? 1:0; if (x < 0 || x > WIDTH){ reset(true); repaint(); } } } //Paddle Subclass public class paddle { private int x,y, size, upKey, downKey, speed; //Paddle Constructor Method public paddle(int setX, int setY, int setSize, int setUpKey, int setDownKey){ x = setX; y = setY; size = setSize; upKey = setUpKey; downKey = setDownKey; } //Paddle Move Method public void move(){ if (speed > 0 && y < HEIGHT-size){//Move if going down and not over the screen limits. y += speed; }else if (speed < 0 && y > size){//Move if going up and not over the screen limits. y += speed; } } //Paddle Adjust Speed Method public void setSpeed(int getSpeed){ speed = getSpeed; } } //Line Subclass (In order to later on implement mazes and obstacles on the playing field) public class line{ private int x1,y1,x2,y2, angle; public line(int setX1, int setY1, int setX2, int setY2){ x1 = setX1; y1 = setY1; x2 = setX2; y2 = setY2; if (x2 - x1 == 0){// Don't want to be dividing by 0 if the line happens to be straight if (y2 > y1){ angle = 270; }else{ angle = 90; } }else if(y2 - y1 == 0){ if (x2 > x1){ angle = 360; }else{ angle = 180; } }else{ angle = (int)Math.atan((x2 - x1)/(y2 - y1));//Calculate the angle of the line. } } } //Graphics Handling public void paint(Graphics g){ g.setColor(Color.black); g.fillRect( 0, 0, WIDTH, HEIGHT);//Background g.setColor(Color.white) ; for(int i = 0; i < ballArray.length; i++){//Draw all balls. g.fillOval( ballArray[i].x, ballArray[i].y, ballArray[i].size, ballArray[i].size); } for(int i = 0; i < player.length; i++){// Draw all paddles. g.fillRect( player[i].x - 5, player[i].y - player[i].size, 5, player[i].size * 2); } for(int i = 0; i < walls.length; i++){// Draw all paddles. g.drawLine( walls[i].x1, walls[i].y1, walls[i].x2, walls[i].y2); } g.drawString(""+score1,WIDTH/4,HEIGHT/11); g.drawString(""+score2,WIDTH*3/4,HEIGHT/11); g.setColor(Color.red); g.drawString(message,10,HEIGHT-10); g.drawString(collision,10,10); } //Double Buffering, as provided by the JavaBoutique Tutorial. public void update (Graphics g){ // initialize buffer if (dbImage == null){ dbImage = createImage (WIDTH, HEIGHT); dbg = dbImage.getGraphics (); } // clear screen in background dbg.setColor (getBackground ()); dbg.fillRect (0, 0, WIDTH, HEIGHT); // draw elements in background dbg.setColor (getForeground()); paint (dbg); // draw image on the screen g.drawImage (dbImage, 0, 0, this); } //Keyboard Handling public void keyPressed(KeyEvent e){ int key = e.getKeyCode(); message = "Key Pressed : "+key; for (int i = 0; i < player.length; i++){ if (key == player[i].upKey){ player[i].setSpeed(-10); }else if(key == player[i].downKey){ player[i].setSpeed(10); } } } public void keyReleased(KeyEvent e){ int key =e.getKeyCode(); message = "Key Released : "+key; for (int i = 0; i < player.length; i++){ if (key == player[i].upKey || key == player[i].downKey){ player[i].setSpeed(0); } } } public void keyTyped(KeyEvent e){ //Unused } //Thread Handling public void init(){ WIDTH = getSize().width; HEIGHT = getSize().height; score1=0; score2=0; ballArray[0] = new ball(WIDTH/2,HEIGHT/2,5); player[0] = new paddle(20, HEIGHT/2, 20, 87, 83); player[1] = new paddle(WIDTH - 20, HEIGHT/2, 20, 38, 40); walls[0] = new line( 0, 0, WIDTH, 0);//Top walls[1] = new line( 0, HEIGHT, WIDTH, HEIGHT);//Bottom walls[2] = new line( 50,50,200,200);//Test //addKeyListener(this); message = "New Game"; } public void start(){ Thread game = new Thread (this); game.start(); } public void stop(){ //Unused } public void destroy(){ //Unused } public void run(){ Thread.currentThread().setPriority(Thread.MIN_PRIORITY); addKeyListener(this); while(true){ //Main Body Loop repaint(); for( int i = 0;i < player.length; i++){//Actions for all paddles player[i].move(); } for( int i = 0;i < ballArray.length; i++){//Actions for all balls //for (int j = 0; j < walls.length; j++){//Collision detection for walls // ballArray[i].collide( walls[j].x1, walls[j].y1, walls[j].x2,walls[j].y2, walls[j].angle, false); //} //for (int j = 0; j < player.length; j++){//Collision detection for paddles // ballArray[i].collide( player[j].x, player[j].y - player[j].size, player[j].x, player[j].y+ player[j].size, 90, true); //} ballArray[i].move(); ballArray[i].score(); } collision = " the a "+walls[2].angle; try { Thread.sleep(20); }catch(InterruptedException ex){ } // set ThreadPriority to maximum value Thread.currentThread().setPriority(Thread.MAX_PRIORITY); } }}