0

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).

hwhap
  • 90
  • 8
  • You either then a `Thread` of some kind which waits a "random" period of time before injecting a new object into the object list OR you can use a `Random` to generate a `boolean` value on each loop of the main loop and make a determination then. You could also generate a random "time" value, zero out a counter at the same time, on each loop, calculate the amount of time since the "time" value was generated and when that amount of time has passed, add another object to the queue – MadProgrammer Nov 04 '17 at 10:30
  • @MadProgrammer Thanks.It helped me fix it and now the code is working just as expected. I would really be grateful if you could also specify how to check if the ball and obstacle are intersecting.This would mean game over. – hwhap Nov 04 '17 at 18:49
  • Take a look at the Graphics 2D shape API, it already contains collision detection – MadProgrammer Nov 04 '17 at 21:06
  • See [Collision detection with complex shapes](http://stackoverflow.com/a/14575043/418556) for a working example. – Andrew Thompson Nov 05 '17 at 00:58
  • 1
    Thank you for taking time to guide me to appropriate references. If not for you guys I wouldn't have done it.@MadProgrammer @Andrew Thompson – hwhap Nov 06 '17 at 17:23

0 Answers0