I am very new to programming still but have been learning a lot. I decided to have a go at making the game Pong from scratch, and I want to know how I could have made this more simple than I wrote it. I feel like I have wayy too many unnecessary variables and some of my code needs cleaned. I am still bad at privatizing methods when I should so most of my methods may be public or static when they shouldn't be. Also the ball in this game takes very very predictable paths so I'm not sure how I could make the ball a bit trickier to get.
My main class (I named it shapes because this started as a simple project where I made a square move).
package square;
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Shapes extends JFrame {
public static int WIN_WIDTH = 700;
public static int WIN_HEIGHT = 400;
public Shapes() {
Panel panel = new Panel();
Paddle paddle = panel.paddle;
setSize(WIN_WIDTH, WIN_HEIGHT);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(panel);
panel.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_DOWN) {
paddle.p_yVelocity = 4;
}
if(keyCode == KeyEvent.VK_UP) {
paddle.p_yVelocity = -4;
}
if(keyCode == KeyEvent.VK_S) {
paddle.o_yVelocity = 4;
}
if(keyCode == KeyEvent.VK_W) {
paddle.o_yVelocity = -4;
}
if(keyCode == KeyEvent.VK_ENTER) {
paddle.start();
}
}
@Override
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_DOWN) {
paddle.p_yVelocity = 0;
System.out.println(paddle.p_yVelocity);
}
if(keyCode == KeyEvent.VK_UP) {
paddle.p_yVelocity = 0;
}
if(keyCode == KeyEvent.VK_W) {
paddle.o_yVelocity = 0;
}
if(keyCode == KeyEvent.VK_S) {
paddle.o_yVelocity = 0;
}
}
});
setVisible(true);
}
public static void main(String[] args) {
new Shapes();
}
}
My Panel class for updating and drawing objects into the frame.
package square;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Panel extends JPanel implements ActionListener {
Paddle paddle = new Paddle();
Ball ball = new Ball();
Timer timer;
public Panel() {
this.setFocusable(true);
timer = new Timer(10,this);
timer.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.fillRect(0,0, Shapes.WIN_WIDTH, Shapes.WIN_HEIGHT);
paddle.paint(g);
}
public void update() {
if(paddle.started) {
ball.update();
paddle.update();
}
}
@Override
public void actionPerformed(ActionEvent e) {
repaint();
update();
}
}
And these are my Paddle and Ball class. I think I could have written some things from the Paddle class in the Ball class but I was working to make the game function so whatever worked, I stuck with.
package square;
import java.awt.*;
public class Paddle {
public Ball ball;
public static int RECT_WIDTH = 10;
public static int RECT_HEIGHT = 70;
public static int p_x = 5;
public static int o_x = 680;
public static int p_y = Shapes.WIN_HEIGHT/2-50;
public static int o_y = Shapes.WIN_HEIGHT/2-50;
public static int xVelocity;
public static int p_yVelocity, o_yVelocity;
public static boolean started = false;
public void paint(Graphics g) {
g.setColor(Color.white);
g.fillRect(p_x, p_y, RECT_WIDTH, RECT_HEIGHT);
g.fillRect(o_x, o_y, RECT_WIDTH, RECT_HEIGHT);
g.fillRect(ball.BALL_X, ball.BALL_Y, ball.BALL_WIDTH, ball.BALL_HEIGHT);
g.setColor(Color.white);
g.setFont(new Font("Arial", 1, 25));
if (!started)
{
g.drawString("Press 'Enter' to Start", 225, 100);
}
g.drawString(Integer.toString(Ball.p_score), 315, 50);
g.drawString("-", 335, 50);
g.drawString(Integer.toString(Ball.o_score), 350, 50);
}
public void update() {
p_x += xVelocity;
p_y += p_yVelocity;
o_y += o_yVelocity;
if(p_y < 0) {
p_y = 0;
}
if(p_y > 295) {
p_y = 295;
}
if(o_y < 0) {
o_y = 0;
}
if(o_y > 295) {
o_y = 295;
}
}
public static boolean start() {
return started = true;
}
public static boolean end() {
p_x = 5;
o_x = 680;
p_y = Shapes.WIN_HEIGHT/2-50;
o_y = Shapes.WIN_HEIGHT/2-50;
Ball.newVelocity();
return started = false;
}
}
package square;
import java.util.Random;
public class Ball {
static Random ran = new Random();
public static int BALL_HEIGHT = 10;
public static int BALL_WIDTH = BALL_HEIGHT;
public static int BALL_X = Shapes.WIN_WIDTH/2 - BALL_WIDTH;
public static int BALL_Y = Shapes.WIN_HEIGHT/2 - BALL_HEIGHT;
public static int o_score = 0, p_score = 0;
public static int bxVelocity = ran.nextInt(8 - 1) - 4, byVelocity =
ran.nextInt(8 - 1) - 4;
public void update() {
BALL_X += bxVelocity;
BALL_Y += byVelocity;
while(bxVelocity == 0 || byVelocity == 0) {
bxVelocity = ran.nextInt(8 - 1) - 4;
byVelocity = ran.nextInt(8 - 1) - 4;
}
if((BALL_Y >= Paddle.p_y && BALL_Y <= Paddle.p_y + Paddle.RECT_HEIGHT)
&& (BALL_X <= Paddle.p_x + Paddle.RECT_WIDTH)) {
bxVelocity = -bxVelocity;
}
if((BALL_Y >= Paddle.o_y && BALL_Y <= Paddle.o_y + Paddle.RECT_HEIGHT)
&& (BALL_X >= Paddle.o_x - Paddle.RECT_WIDTH)) {
bxVelocity = -bxVelocity;
}
if(BALL_Y >= 355) {
byVelocity = -byVelocity;
}
if(BALL_Y <= 0) {
byVelocity = -byVelocity;
}
if(BALL_X <= 0) {
BALL_X = Shapes.WIN_WIDTH/2 - BALL_WIDTH;
BALL_Y = Shapes.WIN_HEIGHT/2 - BALL_HEIGHT;
o_score++;
Paddle.end();
}
if(BALL_X >= 700) {
BALL_X = Shapes.WIN_WIDTH/2 - BALL_WIDTH;
BALL_Y = Shapes.WIN_HEIGHT/2 - BALL_HEIGHT;
p_score++;
Paddle.end();
}
}
public static void newVelocity() {
bxVelocity = ran.nextInt(8 - 1) - 4;
byVelocity = ran.nextInt(8 - 1) - 4;
while(bxVelocity == 0 || byVelocity == 0) {
bxVelocity = ran.nextInt(8 - 1) - 4;
byVelocity = ran.nextInt(8 - 1) - 4;
}
System.out.println(bxVelocity);
}
}
I would like to change the Ball velocity to a double value so I can increment the speed by like 0.1 everytime it hits a paddle but I couldn't figure out how to make a random double value to get the initial ball velocities.
I'm not sure if this is an appropriate post for this site as it is super lengthy and asks just for review of my code, I can take it down if this isn't the place to post!
Thanks in advance