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.
source to share
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)
source to share