The Java Platform Platform: Platform Transitions

So, I'm nearing the end of creating a simple Java platform, but there is one big problem left there, when the player jumps and hits the platform from below, the player sometimes (and always if he is close to the platform) jumps over the platform and lands one higher. Here is the code:

package Main;

import java.applet.Applet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;

public class Platformer extends Applet implements Runnable, KeyListener {

    // buffering variables
    private Image dbImage;
    private Graphics dbg;

    // running boolean
    private boolean running = true;

    // Player coords
    private int rectX = 100;
    private int rectY = 420;

    // initialise dx and dy at zero
    private double dx = 0;
    private double dy = 0;

    private boolean jumping = false;

    //debug Strings
    private String inter = new String();
    private String coords = new String();
    private String debugX = "", debugY = "";

    //for moving the player
    private int worldShift = 0;

    //sprites
    Rectangle2D player = new Rectangle2D.Double();// = new Rectangle2D.Double(rectX, rectY, 10, 10);
    Rectangle2D ground = new Rectangle2D.Double(0, 420, 800, 150);
    int[][] platforms = { {300, 300, 100, 20}, { 450, 200, 100, 20 }, 
            { 500, 250, 100, 20 }, { 100, 200, 100, 20 }, { 600, 300, 100, 20 } };
    ArrayList<Rectangle2D> platformList = new ArrayList<Rectangle2D>();

    int level = 1;

    @Override
    public void init() {

        setSize(800, 480);
        setFocusable(true);
        addKeyListener(this);
        Frame frame = (Frame) this.getParent().getParent();
        frame.setTitle("Test");
        setVisible(true);

        for (int i = 0; i < platforms.length; i++){
            // platforms
            Rectangle2D platform = new Rectangle2D.Double();
            platform.setRect(platforms[i][0] + worldShift, platforms[i][1],
                    platforms[i][2], platforms[i][3]);
            platformList.add(platform);
        }
    }

    @Override
    public void start() {
        Thread thread = new Thread(this);
        thread.start();
    }

    @Override
    public void stop() {
        // TODO Auto-generated method stub
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }

    public void paint(Graphics g) {
        //Double Buffering
        Graphics2D g2 = (Graphics2D) g;
        dbImage = createImage(getWidth(), getHeight());
        dbg = dbImage.getGraphics();
        paintComponent(dbg);
        g2.drawImage(dbImage, 0, 0, this);
    }

    // Paint objects
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;

        //draw platforms
        if (level == 1) {
            g2.setColor(Color.blue);
            g2.draw(ground);
            g2.fill(ground);

            for (Rectangle2D plat : platformList){
                g2.setColor(Color.red);
                g2.draw(plat);
                g2.fill(plat);
            }

        g2.setColor(Color.red);
        //debug printouts   
        g.drawString(inter, 400, 30);
        g.drawString(coords, 20, 150);

        //draw player
        g2.setColor(Color.white);
        g2.draw(player);
        g2.fill(player);

        //print debug info to screen
        Font bold = new Font("Liberation Sans", Font.BOLD, 36);
        setFont(bold);
        g.drawString("dx, dy: (" + dx + ", " + dy + ")", 30, 30);
        g.drawString("x, y: (" + player.getX() + ", " + player.getY() + ")",
                30, 60);
        g.drawString("" + debugX + ", " + debugY + "", rectX, rectY);
        }
    }

    @Override
    public void run() {
        while (running) {

            update();
            repaint();

            try {
                Thread.sleep(17);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void update() {      
        rectX += dx;
        rectY += dy + 1;

        // stops player running off screen
        if (rectX < 1)  rectX = 0;
        if (rectX > 790) rectX = 790;

        // set sprite coords
        player.setRect(rectX, rectY, 10, 10);
        ground.setRect(0, 420, 800, 480);

        // collision detection
        if (player.intersects(ground)) {
            rectY = (int) (ground.getY() - player.getHeight());
            jumping = false;
            dy = 0;
        }

        for (int i = 0; i < platformList.size(); i++){
            Rectangle2D plat = platformList.get(i);
            //sets platform coordinates
            plat.setRect(plat.getX() + worldShift, plat.getY(), plat.getWidth(), plat.getHeight());
            //sets debug Strings
            coords = "Not on platform";
            inter = " " + platformList.get(0).getX() + worldShift + ", " + worldShift;

            debugX = "" + rectX;
            debugY = "" + rectY;

            //for scrolling the background
            if (rectX > 700 && dx == 5){
                worldShift = -5;}
            else if (rectX < 100 && dx == -5){
                worldShift = 5;}
            else worldShift = 0;

            //collision detection
            if (player.intersects(plat)) {
                jumping = false;
                dy = 0;
                coords = " " + plat.getBounds();
                //if falling
                if (rectY <= (int) (plat.getY() + (plat.getHeight()/2))){
                    rectY = (int) (plat.getY() - player.getHeight());
                //if jumping
                else if (rectY >= plat.getY() + (plat.getHeight()/2)){
                    rectY = (int) (plat.getY() + plat.getHeight());}
                break;
            }
            else if (!player.intersects(plat) && !player.intersects(ground)) {
                jumping = true;
            }
        }

        //implements falling
        if (jumping)
            dy += 1;    
    }

    //button presses
    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println("Key pressed code=" + e.getKeyCode() + ", char=" + e.getKeyChar());
        if (e.getKeyCode() == 37)
            dx -= 5; // 37 is left
        if (e.getKeyCode() == 39)
            dx += 5; // 39 is right
        // if (e.getKeyCode() == 40) dy -= 5; //40 is down
        if (e.getKeyCode() == 38 && jumping == false){
            // if on the ground,
            // i.e. only jump if on the ground
            // 38 is up
            dy -= 20;
            jumping = true;
        }
    }

    //key release
    @Override
    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == 37)
            dx = 0; // 37 is left
        if (e.getKeyCode() == 39)
            dx = 0; // 39 is right
        if (e.getKeyCode() == 40)
            dy = 0; // 40 is down
        // if (e.getKeyCode() == 38)
    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }
}

      

I'm sure there is nothing wrong with detecting "// collisions" update()

, but I don't know what the problem is. Among other things, I tried to put the jump mechanism in the update loop, but it didn't work either.

Thanks for any help.

+3


source to share


1 answer


Look at the jump size, it's 20:

public void keyPressed(KeyEvent e) {
    System.out.println("Key pressed code=" + e.getKeyCode() + ", char=" + e.getKeyChar());
    if (e.getKeyCode() == 37)
        dx -= 5; // 37 is left
    if (e.getKeyCode() == 39)
        dx += 5; // 39 is right
    // if (e.getKeyCode() == 40) dy -= 5; //40 is down
    if (e.getKeyCode() == 38 && jumping == false){
        // if on the ground,
        // i.e. only jump if on the ground
        // 38 is up
        dy -= 20; // <- jump size 20
        jumping = true;
    }
}

      

But the height of your platform is also 20

, and you decide on the center of the platform, which means it is only 10px, to get above the center, the jump size must be less than half the height of the platform.

EDIT good config:

Try this config:

Set the increment falling to +0.25

, and increase the increment to-9



removed comments to make it shorter

if (jumping)
    dy += 0.25;

      

and

public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == 37)
        dx -= 5; // 37 is left
    if (e.getKeyCode() == 39)
        dx += 5; // 39 is right
    if (e.getKeyCode() == 38 && jumping == false){
        dy -= 9; // <- jump size set to 9 (half is 10)
        jumping = true;
    }
}

      

Note: blinking horribly , I decided to rename the method paint(Graphics)

toupdate(Graphics)

+1


source







All Articles