I would like to thank the stackoverflow community for taking time to look into my question and helping me out in this project(some snippets have been taken from the community questions).I am a beginner so sorry if any information is vague or insufficient.
I am trying to create a 2D game in which a ball jumps(on pressing space bar) over obstacles that approach it at random intervals. But I am not able to figure out the reason as to why the obstacles fail to appear on execution. Any insight into the problem would be valuable.
For simplicity I have considered that there can only be one obstacle at a time on the screen. I have added comments to enhance the readability of the code.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BallTrial {
public static void main(String[] args) {
BallTrial b = new BallTrial();
}
public BallTrial() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException ex) {
}
//Creates the Game Frame
JFrame frame = new JFrame("Ball Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(new BallObstacle());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class BallObstacle extends JPanel {
//Features of the Ball
protected static final int ballh = 20; //Height of ball
protected static final int ballw = 20; //Width of Ball
private float jumpvelocity;
private int yPos;
//Action of gravity while jumping to reduce jumpvelocity
private float gravity;
private boolean bounce = false;
private Timer GameBegins;
//Features of the obstacle
protected static final int obstacleh = 35; //Obstacle Height
protected static final int obstaclew = 10; //Obstacle Width
private float approachvelocity;
private int xPos;
private int obstacleProb; //Probability of obstacle apperance
private boolean charge = false;
public BallObstacle() {
yPos = getPreferredSize().height - ballh;
jumpvelocity = 0;
gravity = 0.5f;
xPos = getPreferredSize().width + obstaclew;
approachvelocity = 0;
//generates probablity only if there is no obstacle on the screen
if(obstacleProb !=1)
obstacleProb = (int)(2 * Math.random());
//obstacle emerges depending on probability
if((obstacleProb == 1)&&(xPos - obstaclew == getWidth())){
approachvelocity = 30;
charge = true;
}
//to make ball jump on pressing space
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "Jump");
am.put("Jump", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
// Can only bound when we're on the ground
if (yPos + ballh == getHeight()) {
jumpvelocity = -7;
bounce = true;
}
}
});
GameBegins = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int width = getWidth();
if (xPos + 10 > 0) {
if (charge) {
//Subtract approach velocity from xPos to
//make the obstacle approach the ball
xPos -= approachvelocity;
}
}
else{
//Once obstacle crosses the ball reset the
//obstacle to its initial position until next occurance
xPos = width + obstaclew;
charge = false;
}
int height = getHeight();
if (height > 0) {
if (bounce) {
// Add the jumpvelocity to the yPos
// jumpvelocity may be postive or negative, allowing
// for both up and down movement
yPos += jumpvelocity;
// Add the gravity to the jumpvelocity, this will slow down
// the upward movement and speed up the downward movement
jumpvelocity += gravity;
if (yPos + ballh >= height) {
// Seat the sprite on the ground
yPos = height - ballh;
//Stop bouncing
bounce = false;
}
}
}
repaint();
}
});
GameBegins.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D ball = (Graphics2D) g.create();
Graphics2D floor = (Graphics2D) g.create();
Graphics2D wall = (Graphics2D) g.create();
Graphics2D obstacle = (Graphics2D) g.create();
obstacle.setColor(Color.GREEN);
obstacle.fillRect(xPos,75,10,35);
wall.setColor(Color.WHITE);
wall.fillRect(0,0,500,200);
floor.setColor(Color.BLACK);
floor.fillRect(0,110,500,200);
ball.setColor(Color.RED);
ball.fillOval(30,yPos-90,20,20);
obstacle.dispose();
ball.dispose();
wall.dispose();
floor.dispose();
}
}
}
After implementing this I am planning to use the intersect method to terminate the program when the ball collides with obstacle and display the score(Score = Distance traveled along x-axis / 20).