This is my first application in Java, it imitates the world-known Ping Pong Game. I have a lot of questions in my mind...
I read that the class Timer
is not recommended with multiple timers so I use ScheduledThreadPoolExecutor
which probably does the same? Is there something better than that?
The collision detection in the Ball
class includes a lot of else if
statements but I don't have any idea how to improve that...
KeyInput
- there was a problem with multiple using keys so I uses a idea from this website, simply "try" to adopt to my code, it works but is it OK?
RandomGenerator
class contains several switch-statement, how to make this cleaner? Is there any more sophisticated way than switch?
Every opinion is really appreciated. In case someone wants to play the game I can send .jar
file :)
GameFrame
class
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
public class GameFrame extends JFrame
{
public static int WIDTH_GAME_FRAME = 800;
public static int HEIGHT_GAME_FRAME = 700;
GamePanel gamePanel;
public GameFrame()
{
this.setTitle("Game");
this.setLayout(new BorderLayout());
this.setSize(WIDTH_GAME_FRAME, HEIGHT_GAME_FRAME);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
gamePanel = new GamePanel();
this.add(gamePanel);
this.setResizable(false);
this.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run()
{
GameFrame ex = new GameFrame();
}
});
}}
GamePanel
class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class GamePanel extends JPanel
{
public static enum PaddleDirection {LEFT, RIGHT};
public static enum State {MENU, GAME};
public static enum Winner {FIRSTPLAYER, SECONDPLAYER};
public Paddle firstPaddle, secondPaddle;
public Ball firstBall, secondBall;
public static State stateOfGame = State.MENU;
private final Menu menu;
private final KeyInput keyInput;
private String winnerInfo, firstPlayerName, secondPlayerName;
private final RandomGenerator randomGenerator;
private final Obstacle obstacle;
private BufferedImage backgroundImage;
public GamePanel()
{
try
{
backgroundImage = ImageIO.read(getClass().getResource
("/images/bitmap.png"));
}
catch (IOException e)
{
System.exit(0);
}
menu = new Menu();
firstPaddle = new Paddle(300, 600);
secondPaddle = new Paddle(300, 42);
firstBall = new Ball(this, firstPaddle, secondPaddle, true);
secondBall = new Ball(this, firstPaddle, secondPaddle, false);
obstacle = new Obstacle(150, 345 , firstBall);
this.addMouseListener(new MouseInput(this));
randomGenerator = new RandomGenerator(firstBall, firstPaddle, secondPaddle);
keyInput = new KeyInput
(this, firstPaddle, secondPaddle, firstBall, secondBall, obstacle);
ScheduledThreadPoolExecutor executor, keyExecutor;
executor = new ScheduledThreadPoolExecutor(10);
keyExecutor = new ScheduledThreadPoolExecutor(10);
executor.scheduleAtFixedRate
(randomGenerator, 0L, 3L, TimeUnit.SECONDS);
keyExecutor.scheduleAtFixedRate
(keyInput, 0L, 13L, TimeUnit.MILLISECONDS);
this.setBackground(Color.LIGHT_GRAY);
setFocusable(true);
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(backgroundImage, 0, 0, null);
if (stateOfGame == State.GAME)
{
firstPaddle.paint(g);
secondPaddle.paint(g);
if (randomGenerator.freeSlot)
randomGenerator.paint(g);
if (!RandomGenerator.invisibleBallActive)
firstBall.paint(g);
if (RandomGenerator.secondBallActive)
secondBall.paint(g);
if (RandomGenerator.obstacleActive)
obstacle.paint(g);
}
if(stateOfGame == State.MENU)
{
menu.paint(g);
keyInput.resetKeyInput();
}
}
public void endOfGame(GamePanel.Winner win)
{
if (Winner.FIRSTPLAYER == win)
{
winnerInfo = "" + firstPlayerName + " wins";
JOptionPane.showMessageDialog(this, winnerInfo,
"End of game", JOptionPane.INFORMATION_MESSAGE);
}
else if (Winner.SECONDPLAYER == win)
{
winnerInfo = "" + secondPlayerName + " wins";
JOptionPane.showMessageDialog(this, winnerInfo,
"End of game", JOptionPane.INFORMATION_MESSAGE);
}
resetSettings();
GamePanel.stateOfGame = GamePanel.State.MENU;
}
public void setName(String firstPlayerName, String secondPlayerName)
{
this.firstPlayerName = firstPlayerName;
this.secondPlayerName = secondPlayerName;
}
public void resetSettings()
{
firstBall.resetBallPosition();
secondBall.resetBallPosition();
firstPaddle.resetSlowPaddle();
secondPaddle.resetSlowPaddle();
firstPaddle.resetPaddlePosition();
secondPaddle.resetPaddlePosition();
if (RandomGenerator.speedBallActive)
firstBall.resetBallSpeed();
RandomGenerator.secondBallActive = false;
RandomGenerator.slowPaddleActive = false;
RandomGenerator.obstacleActive = false;
RandomGenerator.speedBallActive = false;
RandomGenerator.invisibleBallActive = false;
randomGenerator.freeSlot = true;
obstacle.resetObstaclePosition();
}
}
Paddle
class
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Paddle
{
public int widthPaddle;
public static final int HEIGHT_PADDLE = 18;
private static int PADDLE_MOVE = 5;
private static final int ARC_PADDLE_WIDTH = 12;
private static final int ARC_PADDLE_HEIGHT = 12;
private final int START_X_PADDLE_POSITION;
public int xPaddlePosition;
public int yPaddlePosition;
public int yDownPaddle;
public int xPaddleEnd;
private BufferedImage paddleImage;
public Paddle(int xPaddlePosition, int yPaddlePosition)
{
this.widthPaddle = 120;
this.xPaddlePosition = xPaddlePosition;
this.yPaddlePosition = yPaddlePosition;
START_X_PADDLE_POSITION = xPaddlePosition;
yDownPaddle = yPaddlePosition + HEIGHT_PADDLE;
xPaddleEnd = xPaddlePosition + widthPaddle;
try
{
paddleImage = ImageIO.read(getClass().getResource
("/images/yellow.png"));
}
catch (IOException e)
{
System.exit(0);
}
}
public void move(GamePanel.PaddleDirection dir)
{
if (GamePanel.PaddleDirection.LEFT == dir)
{
if (xPaddlePosition >= 6)
xPaddlePosition -= PADDLE_MOVE;
}
else
{
if (xPaddlePosition + widthPaddle <= 792)
xPaddlePosition += PADDLE_MOVE;
}
xPaddleEnd = xPaddlePosition + widthPaddle;
}
public void resetPaddlePosition()
{
xPaddlePosition = START_X_PADDLE_POSITION;
}
public void slowPaddle()
{
PADDLE_MOVE = 2;
}
public void resetSlowPaddle()
{
PADDLE_MOVE = 6;
}
public void paint(Graphics g)
{
g.drawImage(paddleImage,xPaddlePosition, yPaddlePosition, null);
}
}
Ball
class
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Ball
{
public int xBallPosition = (int) (Math.random() * 200 + 33) * 3;
public int yBallPosition = (int) (Math.random() * 33 + 100) * 3;
private int xBallDirection = -3;
private int yBallDirection = -3;
private static final int DIAMETER = 15;
private final GamePanel gPanel;
private final Paddle firstPaddle, secondPaddle;
public static boolean firstBallImage ,firstBounce = false;
private BufferedImage ball;
public int xCenterBall = xBallPosition + DIAMETER/2;
public int yCenterBall = yBallPosition + DIAMETER/2;
public int yDownBall = yBallPosition + DIAMETER;
public Ball(GamePanel gPanel, Paddle firstPaddle, Paddle secondPaddle, boolean firstBallImage)
{
Ball.firstBallImage = firstBallImage;
this.gPanel = gPanel;
this.firstPaddle = firstPaddle;
this.secondPaddle = secondPaddle;
try
{
if (firstBallImage)
ball = ImageIO.read(getClass().getResource
("/images/football18.png"));
else
ball = ImageIO.read(getClass().getResource
("/images/basketball18.png"));
}
catch (IOException e)
{
System.exit(0);
}
}
public void move()
{
if ((xBallPosition == 0 || xBallPosition == 783 ||
xBallPosition + xBallDirection < 0 ||
xBallPosition + xBallDirection > 783) &&
(yBallPosition < 700 && yBallPosition > 0))
{
xBallDirection = -xBallDirection;
}
xBallPosition += xBallDirection;
yBallPosition += yBallDirection;
}
public void checkBounce(Paddle fPaddle, Paddle sPaddle, GamePanel g, Obstacle ob)
{
yDownBall = yBallPosition + DIAMETER;
xCenterBall = xBallPosition + DIAMETER/2;
yCenterBall = yBallPosition + DIAMETER/2;
if (yDownBall == fPaddle.yPaddlePosition &&
xCenterBall >= fPaddle.xPaddlePosition &&
xCenterBall <= fPaddle.xPaddleEnd)
{
yBallDirection = -yBallDirection;
firstBounce = true;
}
else if (yDownBall + yBallDirection/2 == fPaddle.yPaddlePosition &&
xCenterBall >= fPaddle.xPaddlePosition + xBallDirection/2 &&
xCenterBall <= fPaddle.xPaddleEnd + xBallDirection/2)
{
yBallDirection = -yBallDirection;
firstBounce = true;
}
else if (yBallPosition == sPaddle.yDownPaddle &&
xCenterBall >= sPaddle.xPaddlePosition &&
xCenterBall <= sPaddle.xPaddleEnd)
{
yBallDirection = -yBallDirection;
firstBounce = false;
}
else if (yBallPosition + yBallDirection/2 == sPaddle.yDownPaddle &&
xCenterBall >= sPaddle.xPaddlePosition + xBallDirection/2 &&
xCenterBall <= sPaddle.xPaddleEnd + xBallDirection/2)
{
yBallDirection = -yBallDirection;
firstBounce = false;
}
else if (RandomGenerator.obstacleActive &&
yBallPosition == ob.yDownObstacle &&
xCenterBall <= ob.xObstacleEnd &&
xCenterBall >= ob.xObstaclePosition &&
yBallDirection < 0)
{
yBallDirection = -yBallDirection;
firstBounce = true;
}
else if (RandomGenerator.obstacleActive &&
yDownBall == ob.yObstaclePosition &&
xCenterBall <= ob.xObstacleEnd &&
xCenterBall >= ob.xObstaclePosition &&
yBallDirection > 0)
{
yBallDirection = -yBallDirection;
firstBounce = true;
}
else if (yBallPosition < -20 || yBallPosition > 670)
{
if (yBallPosition < -20)
{gPanel.endOfGame(GamePanel.Winner.FIRSTPLAYER);}
else if (yBallPosition > 670)
{gPanel.endOfGame(GamePanel.Winner.SECONDPLAYER);}
}
}
public void resetBallPosition()
{
xBallPosition = (int) (Math.random() * 200 + 33) * 3;
yBallPosition = (int) (Math.random() * 33 + 100) * 3;
}
public void changeBallSpeed()
{
xBallDirection = 2*xBallDirection;
yBallDirection = 2*yBallDirection;
}
public void resetBallSpeed()
{
xBallDirection = xBallDirection/2;
yBallDirection = yBallDirection/2;
}
public void paint(Graphics g)
{
g.drawImage(ball, xBallPosition, yBallPosition, null);
}
}
Menu
class
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Menu
{
private BufferedImage playImage, helpImage, exitImage, backgroundImage;
private BufferedImage titleImage;
public static final int X_IMAGE_POSITION = 251;
public Menu()
{
try
{
playImage = ImageIO.read(getClass().getResource
("/images/play.png"));
helpImage = ImageIO.read(getClass().getResource
("/images/help.png"));
exitImage = ImageIO.read(getClass().getResource
("/images/exit.png"));
backgroundImage = ImageIO.read(getClass().getResource
("/images/bitmap.png"));
titleImage = ImageIO.read(getClass().getResource
("/images/title220.png"));
}
catch (IOException e)
{
System.exit(0);
}
}
public void paint(Graphics g)
{
g.drawImage(backgroundImage, 0, 0, null);
g.drawImage(titleImage, 280, 25, null);
g.drawImage(playImage, X_IMAGE_POSITION, 280, null);
g.drawImage(helpImage, X_IMAGE_POSITION, 400, null);
g.drawImage(exitImage, X_IMAGE_POSITION, 520, null);
}
}
MouseInput
class
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class MouseInput extends MouseAdapter
{
JTextField firstPlayerName = new JTextField();
JTextField secondPlayerName = new JTextField();
Object[] message = {"First player : ", firstPlayerName,
"Second player : ", secondPlayerName};
private final GamePanel gPanel;
private final String helpInfo = "This is a very simple game which imitates"
+ " world-known game Ping Pong \n\n First player uses arrows to"
+ " move the paddle, second player uses keys A and D";
public MouseInput(GamePanel gPanel)
{
this.gPanel = gPanel;
}
@Override
public void mousePressed(MouseEvent e)
{
int xMousePosition = e.getX();
int yMousePosition = e.getY();
if (xMousePosition > Menu.X_IMAGE_POSITION && xMousePosition < 551)
{
if (yMousePosition > 280 && yMousePosition < 350)
{
int option = JOptionPane.showConfirmDialog(null, message,
"Name of players", JOptionPane.OK_CANCEL_OPTION);
if (option == JOptionPane.OK_OPTION &&
!firstPlayerName.getText().isEmpty() &&
!secondPlayerName.getText().isEmpty())
{
gPanel.setName
(firstPlayerName.getText(), secondPlayerName.getText());
GamePanel.stateOfGame = GamePanel.State.GAME;
}
}
else if (yMousePosition > 400 && yMousePosition < 470)
{
JOptionPane.showMessageDialog(gPanel, helpInfo,
"Help information", JOptionPane.INFORMATION_MESSAGE);
}
else if (yMousePosition > 520 && yMousePosition < 590)
{
System.exit(0);
}
}
}
}
KeyInput
class
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import java.util.EnumMap;
public final class KeyInput implements Runnable
{
private static final String PRESSED = "pressed";
private static final String RELEASED = "released";
private final EnumMap<Key, Boolean> keyMap;
private final GamePanel gPanel;
private final Paddle firstPaddle, secondPaddle;
private final Ball firstBall, secondBall;
private final Obstacle obstacle;
public KeyInput(GamePanel gPanel, Paddle firstPaddle, Paddle secondPaddle,
Ball firstBall, Ball secondBall, Obstacle obstacle)
{
this.keyMap = new EnumMap<>(Key.class);
this.gPanel = gPanel;
this.firstPaddle = firstPaddle;
this.secondPaddle = secondPaddle;
this.firstBall = firstBall;
this.secondBall = secondBall;
this.obstacle = obstacle;
resetKeyInput();
ActionMap actionMap = gPanel.getActionMap();
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = gPanel.getInputMap(condition);
for (Key key : Key.values())
{
KeyStroke pressedKeyStroke = KeyStroke.getKeyStroke
(key.getKeyCode(), 0, false);
KeyStroke releasedKeyStroke = KeyStroke.getKeyStroke
(key.getKeyCode(), 0, true);
inputMap.put(pressedKeyStroke, key.getText() + PRESSED);
inputMap.put(releasedKeyStroke, key.getText() + RELEASED);
actionMap.put(key.getText() + PRESSED, new MyArrowBinding(key, false));
actionMap.put(key.getText() + RELEASED, new MyArrowBinding(key, true));
}
}
@Override
public void run()
{
if (GamePanel.stateOfGame == GamePanel.State.GAME)
{
int order = 1;
firstBall.checkBounce(firstPaddle, secondPaddle, gPanel, obstacle);
firstBall.move();
if (RandomGenerator.secondBallActive)
{
secondBall.checkBounce(firstPaddle, secondPaddle, gPanel, obstacle);
secondBall.move();
}
if (RandomGenerator.obstacleActive)
obstacle.followBall();
gPanel.repaint();
for (Key key : keyMap.keySet())
{
if (keyMap.get(key) && order == 1)
{
secondPaddle.move(GamePanel.PaddleDirection.LEFT);
gPanel.repaint();
}
else if (keyMap.get(key) && order == 2)
{
secondPaddle.move(GamePanel.PaddleDirection.RIGHT);
gPanel.repaint();
}
else if (keyMap.get(key) && order == 3)
{
firstPaddle.move(GamePanel.PaddleDirection.LEFT);
gPanel.repaint();
}
else if (keyMap.get(key) && order == 4)
{
firstPaddle.move(GamePanel.PaddleDirection.RIGHT);
gPanel.repaint();
}
order++;
}
}
}
public void resetKeyInput()
{
keyMap.put(Key.A, false);
keyMap.put(Key.D, false);
keyMap.put(Key.LEFT, false);
keyMap.put(Key.RIGHT, false);
}
private class MyArrowBinding extends AbstractAction
{
private final Key key;
private final boolean released;
public MyArrowBinding(Key key, boolean released)
{
this.key = key;
this.released = released;
}
@Override
public void actionPerformed(ActionEvent aEvt)
{
keyMap.put(key, !released);
}
}
enum Direction
{
LEFT("Left"), RIGHT("Right"), NEUTRAL("Neutral");
private final String text;
private Direction(String text)
{
this.text = text;
}
public String getText()
{
return text;
}
}
enum Key
{
A("A", Direction.LEFT, KeyEvent.VK_A),
D("D", Direction.RIGHT, KeyEvent.VK_D),
LEFT("Left", Direction.LEFT, KeyEvent.VK_LEFT),
RIGHT("Right", Direction.RIGHT, KeyEvent.VK_RIGHT);
private final String text;
private final Direction direction;
private final int keyCode;
private Key(String text, Direction direction, int keyCode)
{
this.text = text;
this.direction = direction;
this.keyCode = keyCode;
}
public String getText()
{
return text;
}
public Direction getDirection()
{
return direction;
}
public int getKeyCode()
{
return keyCode;
}
}
}
RandomGenerator
class
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class RandomGenerator implements Runnable
{
public static boolean secondBallActive = false;
public static boolean obstacleActive = false;
public static boolean speedBallActive = false;
public static boolean slowPaddleActive = false;
public static boolean invisibleBallActive = false;
public boolean freeSlot = true;
public Ball ball;
private static final int IMAGE_WIDTH = 64;
private int xImagePosition;
private int yImagePosition;
private BufferedImage secondBallImage, speedBallImage, slowPaddleImage;
private BufferedImage invisibleBallImage, obstacleImage;
private Integer numberFromGenerator;
private Paddle firstPaddle, secondPaddle;
private Ball secondBall;
public RandomElement choice;
byte paintCounter = 0;
byte randomEventCounter = 0;
public enum RandomElement {SECOND_BALL, SPEED_BALL, SLOW_PADDLE,
INVISIBLE_BALL, OBSTACLE, SMALL_PADDLE};
public RandomGenerator(Ball ball, Paddle firstPaddle, Paddle secondPaddle)
{
this.ball = ball;
this.firstPaddle = firstPaddle;
this.secondPaddle = secondPaddle;
try
{
secondBallImage = ImageIO.read(getClass().getResource
("/images/two.png"));
speedBallImage = ImageIO.read(getClass().getResource
("/images/speed.png"));
slowPaddleImage = ImageIO.read(getClass().getResource
("/images/slow.png"));
invisibleBallImage = ImageIO.read(getClass().getResource
("/images/invisible.png"));
obstacleImage = ImageIO.read(getClass().getResource
("/images/stop.png"));
}
catch (IOException e)
{
System.exit(0);
}
}
@Override
public void run()
{
if (secondBallActive || obstacleActive || speedBallActive ||
slowPaddleActive || invisibleBallActive)
endRandomEvent();
if(freeSlot && paintCounter++ == 2)
{
numberFromGenerator = (int) (Math.random() * 5 + 1);
xImagePosition = (int) (Math.random() * 650 + 50);
yImagePosition = (int) (Math.random() * 200 + 250);
paintCounter = 0;
switch(numberFromGenerator)
{
case 1: choice = RandomElement.SECOND_BALL;
break;
case 2: choice = RandomElement.SPEED_BALL;
break;
case 3: choice = RandomElement.SLOW_PADDLE;
break;
case 4: choice = RandomElement.INVISIBLE_BALL;
break;
case 5: choice = RandomElement.OBSTACLE;
break;
}
}
}
public void paint(Graphics g)
{
if (choice != null && freeSlot)
{
checkBallPosition();
switch(choice)
{
case SECOND_BALL: g.drawImage(secondBallImage,
xImagePosition, yImagePosition, null);
break;
case SPEED_BALL: g.drawImage(speedBallImage,
xImagePosition, yImagePosition, null);
break;
case SLOW_PADDLE: g.drawImage(slowPaddleImage,
xImagePosition, yImagePosition, null);
break;
case INVISIBLE_BALL: g.drawImage(invisibleBallImage,
xImagePosition, yImagePosition, null);
break;
case OBSTACLE: g.drawImage(obstacleImage,
xImagePosition, yImagePosition, null);
break;
}
}
}
public void checkBallPosition()
{
if (ball.xCenterBall >= xImagePosition &&
ball.xCenterBall <= xImagePosition + IMAGE_WIDTH &&
ball.yCenterBall >= yImagePosition &&
ball.yCenterBall <= yImagePosition + IMAGE_WIDTH)
{
freeSlot = false;
if (null != choice)
switch (choice) {
case SECOND_BALL:
secondBallActive = true;
break;
case OBSTACLE: obstacleActive = true;
break;
case SPEED_BALL: speedBallActive = true;
ball.changeBallSpeed();
break;
case SLOW_PADDLE: slowPaddleActive = true;
secondPaddle.slowPaddle();
firstPaddle.slowPaddle();
break;
case INVISIBLE_BALL: invisibleBallActive = true;
break;
}
}
}
public void endRandomEvent()
{
if (invisibleBallActive == true)
{
invisibleBallActive = false;
freeSlot = true;
}
if (randomEventCounter++ == 5)
{
randomEventCounter = 0;
switch(choice)
{
case SECOND_BALL: secondBallActive = false;
freeSlot = true;
break;
case SPEED_BALL: speedBallActive = false;
ball.resetBallSpeed();
freeSlot = true;
break;
case SLOW_PADDLE: slowPaddleActive = false;
firstPaddle.resetSlowPaddle();
secondPaddle.resetSlowPaddle();
freeSlot = true;
break;
case OBSTACLE: obstacleActive = false;
freeSlot = true;
break;
}
}
}
}
Obstacle
class
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Obstacle
{
public int WIDTH_OBSTACLE = 200;
public int HEIGHT_OBSTACLE = 18;
private final int OBSTACLE_MOVE = 3;
private final Ball ball;
public int xObstaclePosition, yObstaclePosition;
private final int START_X_OBSTACLE_POSITION;
public int yDownObstacle;
public int xObstacleEnd = xObstaclePosition + WIDTH_OBSTACLE;
private BufferedImage obstacleImage;
public Obstacle(int xObstaclePosition, int yObstaclePosition, Ball ball)
{
this.xObstaclePosition = xObstaclePosition;
this.yObstaclePosition = yObstaclePosition;
this.ball = ball;
START_X_OBSTACLE_POSITION = xObstaclePosition;
yDownObstacle = yObstaclePosition + HEIGHT_OBSTACLE;
try
{
obstacleImage = ImageIO.read(getClass().getResource
("/images/obstacle.png"));
}
catch (IOException e)
{
System.exit(0);
}
}
public void followBall()
{
if (ball.xBallPosition > xObstaclePosition + WIDTH_OBSTACLE/2)
{
if (xObstaclePosition < GameFrame.WIDTH_GAME_FRAME - WIDTH_OBSTACLE)
{
xObstaclePosition += OBSTACLE_MOVE;
xObstacleEnd = xObstaclePosition + WIDTH_OBSTACLE;
}
}
else
{
if (xObstaclePosition > 2)
{
xObstaclePosition -= OBSTACLE_MOVE;
xObstacleEnd = xObstaclePosition + WIDTH_OBSTACLE;
}
}
}
public void resetObstaclePosition()
{
xObstaclePosition = START_X_OBSTACLE_POSITION;
}
public void paint(Graphics g)
{
g.drawImage(obstacleImage, xObstaclePosition, yObstaclePosition, null);
}
}
`
[BACKTICK] around your inline code so that it appears monospaced and looks like code to differentiate from text. I'm sure you'll enjoy your stay here :) \$\endgroup\$