0

I have been making a scrolling background game but now I am trying to make my character jump, but I cannot seem to make the player smoothly jump up then fall back to the ground. My player jumps up, but immediately teleports back to the ground, making it impossible for it to jump over obstacles. Any help would be appreciated. Thanks!

Here is the code.

   /*
     * To change this license header, choose License Headers in Project Properties.
     * To change this template file, choose Tools | Templates
     * and open the template in the editor.
     */
     import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Container;
    import java.awt.FlowLayout;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.awt.geom.Rectangle2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.JButton;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;



    /**
     *
     * @author kids
     */
    public class game extends javax.swing.JFrame {
    private PaintSurface canvas;
        int x_position = 0;
        int y_position = 580;
        int x_speed = 7;

    int x_pos = 0;
    int y_pos = 0;
    int x_pos2 = -1200;
    int x_position2 = -1200;

    int cloudOnex = 30;
    int cloudOney = 70;
    int cloud2x = -1150;
    int cloud2y = 70;
    int cloud3x = 700;
    int cloud3y = 70;
    int cloud4x = -600;
    int cloud4y = 70;
    int cloud5x = 450;
    int cloud5y = 70;
    int playerx =400;
    int playery = 540;
    int enemy_posX = 500;
    int enemy_posY = 540;
    private BufferedImage image;
    int defaultPosition = 540;


        /**
         * Creates new form game
         */
        public game() {

              JPanel btnPanel = new JPanel(new FlowLayout());

            JButton btnUp = new JButton("Move Up ");
            btnPanel.add(btnUp);
            btnUp.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    playery += 10;

                    canvas.repaint();
                    requestFocus(); // change the focus to JFrame to receive KeyEvent
                }
            });


            Container cp = getContentPane();

            cp.setLayout(new BorderLayout());

            // "super" JFrame fires KeyEvent
            addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent evt) {

                    switch (evt.getKeyCode()) {

                        case KeyEvent.VK_UP:
                            playery -= 90;

                            repaint();
                            break;
                        case KeyEvent.VK_DOWN:
                            playery += 22;
                            repaint();
                            break;

                    }
                }
            });

     this.setTitle("Scrolling Game");
            this.setSize(1200, 650);
            // super.setBackground(Color.YELLOW);
            this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
            this.add(new PaintSurface(), BorderLayout.CENTER);
            this.setVisible(true);
            canvas = new PaintSurface();
            this.add(canvas, BorderLayout.CENTER);




            //settings for the form, handling things such as exiting and size
            Timer timer = new Timer(10, e -> {
                canvas.movement();
                 canvas.falling();
               canvas.check();

                canvas.repaint();
            });
            timer.start();
        }

        /**
         * This method is called from within the constructor to initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is always
         * regenerated by the Form Editor.
         */
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
        private void initComponents() {

            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 400, Short.MAX_VALUE)
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 300, Short.MAX_VALUE)
            );

            pack();
        }// </editor-fold>                        



         class PaintSurface extends JComponent {

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

                Graphics2D g2 = (Graphics2D) g;

                Rectangle2D background = new Rectangle2D.Float(x_pos, y_pos, 1200, 650);
                g2.setColor(Color.GRAY);
                g2.fill(background);

                Rectangle2D ground = new Rectangle2D.Float(x_position, y_position, 1200, 30);
                g2.setColor(Color.darkGray);
                g2.fill(ground);

                Rectangle2D cloudOne = new Rectangle2D.Float(cloudOnex, cloudOney, 70, 70);
                g2.setColor(Color.WHITE);
                g2.fill(cloudOne);

                 Rectangle2D cloudThree = new Rectangle2D.Float(cloud3x, cloud3y, 70, 70);
                g2.setColor(Color.WHITE);
                g2.fill(cloudThree);

               Rectangle2D enemy = new Rectangle2D.Float(enemy_posX, enemy_posY, 40,40);
                g2.setColor(Color.PINK);
                g2.fill(enemy);



                Rectangle2D background2 = new Rectangle2D.Float(x_pos2, y_pos, 1200, 650);
                g2.setColor(Color.CYAN);
                g2.fill(background2);

                Rectangle2D ground2 = new Rectangle2D.Float(x_position2, y_position, 1200, 30);
                g2.setColor(Color.GREEN);
                g2.fill(ground2);

               Rectangle2D cloudTwo = new Rectangle2D.Float(cloud2x, cloud2y, 70, 70);
                g2.setColor(Color.WHITE);
                g2.fill(cloudTwo);

                 Rectangle2D cloudFour = new Rectangle2D.Float(cloud4x, cloud4y, 70, 70);
                g2.setColor(Color.WHITE);
                g2.fill(cloudFour);

                Rectangle2D player = new Rectangle2D.Float(playerx, playery,40,40);
                g2.setColor(Color.red);
                g2.fill(player);





                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            /**
             * @param args the command line arguments
             */
        }

          public void movement(){
                        enemy_posX +=10;

              cloudOnex += 10;
              cloud2x += 10;
              cloud3x += 10;
              cloud4x += 10;
              x_position += 10;
              x_pos += 10;
              x_position2 += 10;
              x_pos2 += 10;




                     try { Thread.sleep(20); }   /* this will pause for 50 milliseconds */
                     catch (InterruptedException e) { System.err.println("sleep exception"); }


            }
          public void falling(){


                 while (playery != defaultPosition) {
//it adds  90 because that is the distance it goes up every jump
//default position is the spot where it rests when it is not jumping
                      playery += 90;
                      repaint();

                 } 
             // }

              } 

             public void check() {
                 if (x_pos == 1200) {
                     x_pos = -1200;
                     //x_position = -1200;
                     repaint();
                 }
                 if (x_pos2 == 1200) {
                     x_pos2 = -1200;
                     // x_position2 = -1200;
                     repaint();

                 }
                 if (x_position == 1200) {
                     x_position = -1200;
                     repaint();
                 }
                 if (x_position2 == 1200) {
                     x_position2 = -1200;
                     repaint();

                 }
                 if (cloudOnex == 1200) {
                     cloudOnex = -1150;
                     repaint();

                 }
                 if (cloud2x == 1200) {
                     cloud2x = -1150;
                     repaint();

                 }
                 if (cloud3x == 1200) {
                     cloud3x = -200;
                     repaint();

                 }
                 if (cloud4x == 1200) {
                     cloud4x = 0;
                     repaint();

                 }

         if (enemy_posX == 1200){
                  enemy_posX = 0;
                  repaint();
         }
            }



         }

        /**
         * @param args the command line arguments
         */
        public static void main(String args[]) {
            /* Set the Nimbus look and feel */
            //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
            /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
             * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
             */
            try {
                for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                    if ("Nimbus".equals(info.getName())) {
                        javax.swing.UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            } catch (ClassNotFoundException ex) {
                java.util.logging.Logger.getLogger(game.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (InstantiationException ex) {
                java.util.logging.Logger.getLogger(game.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                java.util.logging.Logger.getLogger(game.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (javax.swing.UnsupportedLookAndFeelException ex) {
                java.util.logging.Logger.getLogger(game.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            }
            //</editor-fold>

            /* Create and display the form */
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new game().setVisible(true);
                }
            });
        }

        // Variables declaration - do not modify                     
        // End of variables declaration                   
    }

The place that handles the going back down for the player is this:

while (playery != defaultPosition) {
//it adds  90 because that is the distance it goes up every jump
//default position is the spot where it rests when it is not jumping
                      playery += 90;
                      repaint();

                 } 

I suspect that it immediately jumps back because it sets it back 90, like I set it to, instead of incrementally increasing the player y, but when I did that it froze.

Sam Kin
  • 11
  • 5
  • For [example](https://stackoverflow.com/questions/16493809/how-to-make-sprite-jump-in-java/16494178#16494178) and [example](https://stackoverflow.com/questions/19626338/japplet-creates-a-ball-that-bounces-and-gets-progressively-less-high-in-java/19626396#19626396) – MadProgrammer Jan 21 '19 at 04:19
  • I am having trouble interpreting the first example, is the entire thing existing just for a jumping mechanism, or is there a specific part for it? – Sam Kin Jan 21 '19 at 04:21
  • I also encourage a redesign. You need a concept of a "master" loop. This is responsible for updating the state of the game (ie process inputs, update state based on existing deltas, etc) and the scheduling the rendering. You seem to have a series of otherwise disconnected and, in most cases, blocking process which is going to make it difficult to expand the functionality – MadProgrammer Jan 21 '19 at 04:22
  • *"is the entire thing existing just for a jumping mechanism, or is there a specific part for it? "* - Yes, all it does is demonstrate how you might perform a "jump". You code is violating the single threaded nature of the Swing API, the `while-loop` isn't going to work, instead, on each cycle, you need to adjust the y position by a given delta until the user reaches the desired location – MadProgrammer Jan 21 '19 at 04:24
  • So use a loop for updating instead of all of the different functions being called in the timer? – Sam Kin Jan 21 '19 at 04:25
  • The `Timer` is fine, it's already a pseudo loop, you need to get rid of the `while-loop` and repeated `repaints`, just do that as the last command in the `Timer` – MadProgrammer Jan 21 '19 at 04:26
  • "instead, on each cycle, you need to adjust the y position by a given delta until the user reaches the desired location" - What other ways to achieve that are there other than for loops and while-loops? Wouldnt that work considering that when the player's y pos isnt the same as the default pos, it would player++; until the playery equals the default position? – Sam Kin Jan 21 '19 at 04:27
  • Sam, please understand, the `Timer` IS a pseudo loop, it's going to be called, repeatedly, at a give rate. Each time is called, you change the vertical position by a specific delta, which the two examples I linked already do – MadProgrammer Jan 21 '19 at 04:29
  • That really depends, you might consider doing it as part of the movement functionality, `if jumping ...`. I really depends on how you want to control it, for example, do you want to allow the user to change direction in the air or not!? – MadProgrammer Jan 21 '19 at 04:35
  • No, I would only want the user to be able to jump up. And by "if jumping..." do you mean if the KeyEvent vk_up happens? – Sam Kin Jan 21 '19 at 04:38
  • I was thinking more along the lines of turning left or right, but what ever. Doing all the movement functionality from a root method (ie `move`), which might call sub methods, is probably a good place to start, as you can make determinations about which actions can be carried out based on the current state of the model – MadProgrammer Jan 21 '19 at 04:39
  • You already have a `movement` class, but it doesn't need to be made up of a bunch of really long `if-else` statements, it could delegate the functionality to the methods, so, if it determines the player is currently jumping it could call a `jump` method, for example ... also, you need to get rid of the `Thread.sleep`s – MadProgrammer Jan 21 '19 at 04:45
  • And what would be inside of the jump method then? Because I can detect if they are jumping if the playery is less than the default position, but I don't know the rest. – Sam Kin Jan 21 '19 at 04:52
  • So, as I said in your previous question, you have a vertical delta (amount of change), this is applied to the player's `y` position on each loop. Each loop would also decrease this delta by a given amount. When the delta changes so the player moves down, it should either reach a terminal velocity (no more changes are applied to it) or the hit the ground – MadProgrammer Jan 21 '19 at 05:19

0 Answers0