4
\$\begingroup\$

This is my main class which handles the looping and setup of the game:

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;

public class Game extends Canvas implements Runnable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Thread thread;
    private Boolean running;

    public int width;
    public int height;

    protected static Boolean p1won, p2won;

    public static boolean gameover = false;

    private Player1 p1;
    private Player2 p2;
    private Ball ball;
    private Window window;

    public static boolean playing = false;

    public Game(){
        new Window(this, width, height, running);
        width = this.getToolkit().getScreenSize().width;
        height = this.getToolkit().getScreenSize().height;

        p1 = new Player1();
        p2 = new Player2();
        ball = new Ball(width, height, p1,p2, null, window);

        start();
    }

    private synchronized void start() {
        thread = new Thread(this);
        thread.start();
        running = true;
    }

    private synchronized void stop(){
        try {
            thread.join();
            running = false;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public void run() {
        long lastTime = System.nanoTime();
        double amountOfTicks = 60.0;
        double ns = 100000000 / amountOfTicks;
        double delta = 0;
        long timer = System.currentTimeMillis();
        int frames = 0;
        while(running){
            long now = System.nanoTime();
            delta += (now - lastTime) / ns;
            lastTime = now;
            while(delta >= 1){
                update();
                delta--;
            }
            if(running)
                render();
            frames++;

            if(System.currentTimeMillis() - timer > 1000){
                timer += 1000;
                System.out.println("FPS : "+frames);
                frames = 0;
            }
        }
        stop();
    }

    private void update() {

        if(p1.score == 7){
            gameover = true;
            playing = false;
            p1.score = 0;
            p2.score = 0;
            p1won = true;
        } else if(p2.score == 7){
            gameover = true;
            playing = false;
            p1.score = 0;
            p2.score = 0;
            p2won  =true;
        }

        if(playing){
        p2.update(height);
        p1.update(height);

        ball.update(width, height);
        }
    }

    private void render() {
        BufferStrategy bs = this.getBufferStrategy();
        if(bs == null){//when a bufferedStrategy is gottn its default value is null
            this.createBufferStrategy(3);//gives the buffered strategy a value of three
            return;//returns the value so we don't create more buffered strategy's
        }
        Graphics g = bs.getDrawGraphics();

        Font f1 = new Font("Arial", 0, 150);
        Font f2 = new Font("Arial", 0, 50);

        g.setColor(Color.black);
        g.fillRect(0, 0, getToolkit().getScreenSize().width, getToolkit().getScreenSize().height);

        if(!playing && gameover == false){

        g.setColor(Color.white);

        g.setFont(f1);
        g.drawString("PONG", width/2-250, height/5);

        g.setFont(f2);
        g.drawString("(Press Enter To Start)", width/2 - 250, height/2);
        g.drawString("Press ESCAPE to exit", width/2-250, height-400);
        }else if(playing && gameover == false){
            p2.render(g,width);
            ball.render(g);  
            p1.render(g,width);
            g.fillRect(width/2, 0, 25, 150);
            g.fillRect(width/2, height/100*20-150, 25, 150);
            g.fillRect(width/2, height/100*40-150, 25, 150);
            g.fillRect(width/2, height/100*60-150, 25, 150);
            g.fillRect(width/2, height/100*80, 25, 150);

        }
        else if(gameover == true && playing == false){
            g.setFont(f2);
            g.setColor(Color.white);
            if(p1won) g.drawString("Gameover Player 1 WON!", width/2-300, height/2);
            else if(p2won) g.drawString("Gameover Player 2 WON!", width/2-300, height/2);
        }

        bs.show();

    }

    public Window getWindow(){
        return window;
    }


    public static void main(String[] args) {
        new Game();

    }

}

This handles the Ball movement and collision detection:

     import java.awt.Color;

    import java.awt.Graphics;
    import java.awt.Rectangle;

import java.util.Random;
import java.util.concurrent.TimeUnit;

public class Ball {

    private Game game;
    private Player1 p1;
    private Player2 p2;

    private Random rand;


    int x;
    int y;

    int xa ;
    int ya ;

    public Ball(int width, int height, Player1 p1, Player2 p2, Game game, Window window){
        this.game = game;
        x = width/2;
        y = height/2;

        rand= new Random();

        xa = rand.nextInt(3)+1;
        ya = rand.nextInt(3)+1;

    }

    public void update(int width, int height){

        if(y<=0 || y>= height - 25)ya = ya *-1;
        if((x + 25 >= width - 150 && x <= width - 125 ) && (y >= p2.y && y <= p2.y +150 || y + 25 >= p2.y && y + 25 <= p2.y + 150))xa =rand.nextInt(2) - 4;
        if((x >= 150 && x <= 175) && (y >= p1.y && y <= p1.y + 150 || y + 25 >= p1.y && y + 25 <= p1.y + 150 )){
            xa =rand.nextInt(4);
            ya = rand.nextInt(4);
        }

        x += xa;
        y += ya;

        checkScoreCollision(width, height);
    }

    private void checkScoreCollision(int width, int height) {
        if(x <= 5){
            p2.score++;
            ballReset(width, height);
        }
        else if(x+26 >= width-5){
            p1.score++;
            ballReset(width, height);
        }
    }

    private void ballReset(int width, int height) {

        x = width/2;
        y = height/2;

        xa = rand.nextInt(4)-2;
        ya = rand.nextInt(4)-2;

        if(xa == 0 || ya == 0)ballReset(width, height);

    }


    public void render(Graphics g){
        g.setColor(Color.white);
        g.fillRect(x, y, 25, 25);
    }

}

The Window class sets up the framing for the game:

import java.awt.Canvas;
import java.awt.Component;

import javax.swing.JFrame;

public class Window extends Canvas{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Player1 p1;

    public Window(Game game, int Height, int Width, Boolean playing){
        JFrame frame = new JFrame("Pong");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH, HEIGHT);
        frame.setResizable(false);
        frame.setUndecorated(true);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setLocationRelativeTo(null);
        frame.add(game);

        frame.addKeyListener(new KeyInput(playing));//add this shit to the frame you twat (spent 3-4 hours trying to figure thius out)
        frame.setFocusable(true);

        frame.setVisible(true);
    }

    public Player1 getPlayer1(){
        return p1;
    }

}

The KeyInput class handles all the input:

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KeyInput implements KeyListener{

    private Game game;
    private Player1 p1;
    private Player2 p2;

    public KeyInput(Boolean playing){
    }

    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();

        if(key == KeyEvent.VK_ESCAPE){
            System.exit(0);
        }
        if(key == KeyEvent.VK_R && Game.gameover == true){
            Game.playing = true;
            System.out.println(Game.playing);
            Game.gameover = false;
            Game.p1won = false;
            Game.p2won = false;  
        }
        if(key == KeyEvent.VK_SPACE && Game.playing == false && Game.gameover == false) Game.playing = true;
        else if(key == KeyEvent.VK_SPACE && Game.playing == true) Game.playing = false;


        //player ones movement
        if(key == KeyEvent.VK_W)p1.up = true;
        else if(key == KeyEvent.VK_S) p1.down = true;

        //player two's movement
                if(key == KeyEvent.VK_UP)p2.up = true;
                else if(key == KeyEvent.VK_DOWN) p2.down = true;
    }     

    public void keyReleased(KeyEvent e) {
        Player1.down = false;
        Player1.up = false; 
        Player2.down = false;
        Player2.up = false; 
    }

    public void keyTyped(KeyEvent e) {

    }

}

Player 1:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;

public class Player1 {

    public static int x = 150;
    public static int y = 500;
    public static int score = 6;
    public String scorestr;

    static Boolean up = false;
    static Boolean down = false;


    public void update(int height){
        if(y<=height  - 150)if(down)y += 2;
        if(y>= 0)if(up)y -= 2;
    }
    public void render(Graphics g, int width){
        //scoreStr = score;
        Font f1 = new Font("Arial", 0, 150);
        g.fillRect(150, y, 25, 150);
        scorestr = Integer.toString(score);
        g.setFont(f1);
        g.drawString(scorestr, width /2 -150, 150);
    }

}

Player 2:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;

public class Player2 {

    public static int y = 500;

    public static int score;
    public String scorestr;

    static Boolean up = false;
    static Boolean down = false;

    public void update(int height){
        if(y<=height  - 150)if(down)y += 3;
        if(y>= 0)if(up)y -= 3;
    }
    public void render(Graphics g, int width){
        scorestr= Integer.toString(score);
        Font f1 = new Font("Arial", 0, 150);
        g.setFont(f1);
        g.setColor(Color.white);
        g.fillRect(width- 150, y, 25, 150);
        g.drawString(scorestr, width /2 + 150, 150);
    }

}

I want to learn as much from this as I can so be brutally honest and try to highlight a few positives.

\$\endgroup\$
0
6
\$\begingroup\$

Players

Why do you have a class for Player1 and Player2. Refactor this into a Player class.

Collision Detection

Your collision detection is not a good approach. You have Ball detect collisions. I would move that logic to either Game or some other sort of class who's purpose is to detect collisions.

See this answer:

The usual approach for collision detection is to not have either A or B detect collisions on their own.

Yet you have Ball do it's own work.

Instead, you first move all objects, then have a separate collision system look for collisions between all pairs of objects, telling every object about the things that it has collided with, and then finally render all objects.

Ball could have a method like collided(who), but the point is, that Game figures out when to call this method, and Game tells the ball who. The ball should not figure any of this out.

To reiterate: The ball should not determine whether it collided or not, the game should instead tell Ball: "Hey buddy, you collided" and the Ball should respond to this.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.