Search code examples
javapong

Score not Updating in Pong


I'm very confused as to why my scoreboard isn't updating on screen. The scores are increasing (I checked with debugger, also the ball is being centered). But the scoreboard isn't updating at all it constantly says "0 : 0"

Pong Class

package com.dheraxysgames.pong;

import java.awt.Dimension;

import javax.swing.JFrame;

public class Pong extends JFrame{

    private static final long serialVersionUID = 1L;

    //Set Resolution
    public static final int width = 300, 
                            height = width / 4 * 3, 
                            scale = 3;

    public Pong() {
        Dimension size = new Dimension(width * scale, height * scale);
        setSize(size);
        setTitle("PONG");
        setResizable(false);
        setVisible(true);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(new GamePanel());
    }

    public static int getWindowWidth(){
        return width * scale;
    }

    public static int getWindowHeight(){
        return height * scale;
    }

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

}

GamePanel Class

package com.dheraxysgames.pong;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JPanel;
import javax.swing.Timer;

public class GamePanel extends JPanel implements ActionListener, KeyListener {

    private static final long serialVersionUID = 1L;

    Ball ball = new Ball();
    Player player = new Player();
    AI ai = new AI(this);

    public GamePanel(){
        Timer time = new Timer(50, this);
        time.start();

        this.addKeyListener(this);
        this.setFocusable(true);
    }

    private void update(){
        player.update();
        ai.update();
        ball.update();

        ball.checkCollision(player);
        ball.checkCollision(ai);
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);

        g.setColor(Color.BLACK);
        g.fillRect(0, 0, Pong.getWindowWidth(), Pong.getWindowHeight());

        g.setColor(Color.WHITE);
        Font font = new Font("IMMORTAL", Font.BOLD, 50);
        g.setFont(font);
        g.drawString(player.score + " : " + ai.score, Pong.getWindowWidth() / 2 - 60, 50);

        player.paint(g);
        ai.paint(g);
        ball.paint(g);
    }

    public Ball getBall(){
        return ball;
    }

    public void actionPerformed(ActionEvent e) {
        update();
        repaint();
    }

    //Keyboard
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_UP) player.setYVelocity(-10);
        if (e.getKeyCode() == KeyEvent.VK_DOWN) player.setYVelocity(10);
    }

    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_UP) player.setYVelocity(0);
        if (e.getKeyCode() == KeyEvent.VK_DOWN) player.setYVelocity(0);
    }

    public void keyTyped(KeyEvent e) {

    }

}

Player Class

package com.dheraxysgames.pong;

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

public class Player {

    public int score = 0;

    private static int width = 50,
                       height = 150;

    private int x = 800, y = (Pong.getWindowHeight() / 2) - (height / 2), 
                yV = 0;

    public Player() {

    }

    public void update(){
        y += yV;
    }

    public void paint(Graphics g){
        g.setColor(Color.GREEN);
        g.fillRect(x, y, width, height);
    }

    public int getX(){
        return x;
    }

    public int getY(){
        return y;
    }

    public int getWidth(){
        return width;
    }

    public int getHeight(){
        return height;
    }

    public void setYVelocity(int speed){
        yV = speed;
    }

}

AI Class

package com.dheraxysgames.pong;

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

public class AI {

    public int score = 0;

    private static int width = 50,
                       height = 150;

    private GamePanel field;

    private int x = 50, y = (Pong.getWindowHeight() / 2) - (height / 2), 
                yV = 0;

    public AI(GamePanel game) {
        this.field = game;
    }

    public AI(){

    }

    public void update(){
        if(field.getBall().getY() < this.y) yV = -8;
        if(field.getBall().getY() > this.y) yV = 8;
        y += yV;
    }

    public void paint(Graphics g){
        g.setColor(Color.GREEN);
        g.fillRect(x, y, width, height);
    }

    public int getX(){
        return x;
    }

    public int getY(){
        return y;
    }

    public int getWidth(){
        return width;
    }

    public int getHeight(){
        return height;
    }

    public void setYVelocity(int speed){
        yV = speed;
    }

}

Ball Class

package com.dheraxysgames.pong;

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

public class Ball {

    private int x = Pong.getWindowWidth() / 2, y = Pong.getWindowHeight() / 2, 
                xV = 10, yV = 10;

    private static int size = 40;

    Player player = new Player();
    AI ai = new AI();

    public void update() {
        x += xV;
        y += yV;

        if (x < 0){
            reverseXDirection();
            player.score++;
            x = Pong.getWindowWidth() / 2;
            y = Pong.getWindowHeight() / 2;
        }
        if (x > Pong.getWindowWidth() - size){
            reverseXDirection();
            ai.score++;
            x = Pong.getWindowWidth() / 2;
            y = Pong.getWindowHeight() / 2;
        }
        if (y < 0 || y > Pong.getWindowHeight() - size - 38) reverseYDirection();
    }

    public void paint(Graphics g){
        g.setColor(Color.GREEN);
        g.fillOval(x, y, size, size);
    }

    private void reverseXDirection(){
        xV = -xV;
    }

    private void reverseYDirection(){
        yV = -yV;
    }

    public void checkCollision(Player p) {
        if (this.x + size > p.getX() && this.x + size < p.getX() + p.getWidth()){
            if (this.y + size > p.getY() && this.y + size < p.getY() + p.getHeight()){
                reverseXDirection();
            }
        }
    }

    public void checkCollision(AI ai) {
        if (this.x > ai.getX() && this.x < ai.getX() + ai.getWidth()){
            if (this.y > ai.getY() && this.y < ai.getY() + ai.getHeight()){
                reverseXDirection();
            }
        }
    }

    public int getX(){
        return x;
    }

    public int getY(){
        return y;
    }

}

Solution

  • In you're Ball class the score you're updating is not the same score that is being checked in the GamePanel class.

    Notice how in both classes you are calling

    Player player = new Player();
    AI ai = new AI();
    

    player and ai in Ball are seperate instances from the player and ai in GamePanel.

    You will need to get the player and ai from the GamePanel class and pass them to the Ball class. The easiest way to do this would probably be to give Ball a constructor like so

    Player player;
    AI ai;
    public Ball(Player player, AI ai) {
        this.player = player;
        this.ai = ai;
    }
    

    And in your GamePanel class change:

    Ball ball = new Ball();
    Player player = new Player();
    AI ai = new AI(this);
    

    To this:

    Player player = new Player();
    AI ai = new AI(this);
    Ball ball = new Ball(player, ai);
    

    It's been a while since I've used java so I'm probably forgetting a simpler way to do this, but this should solve the problem.