Quick and dirty platformer with Physics has errors with moving platforms

Alright, so I’m trying to make a quick and dirty platformer engine, and I am having some problems with my collision detection and moving platforms. for one thing the “player” seems to bounce on top of moving platforms ever so slightly, and when he hits the right side errors happen as well. I’ll upload a jnlp demo so you can try to find more errors and see whats happening, but here is the source:


import java.awt.Rectangle;
import java.util.Vector;

import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;


public class Platformer extends BasicGame{

	boolean keys[];
	int ALL_KEYS = 0xFF;
	Player player;
	Vector<Vector<Thing> > things;
	int level = 0;
	
	public Platformer() {
		super("You've met with a terrible fate, haven't you?");
	}
	
	public void init(GameContainer gc) throws SlickException {
		keys = new boolean[ALL_KEYS];
		for(int i = 0; i < ALL_KEYS; i++){
			keys[i] = false;
		}
		
		player = new Player();
		things = new Vector<Vector<Thing> >();
		Vector<Thing> temp = new Vector<Thing>();
		temp.add(new Thing(0, 440, 640, 40, 1));
		temp.add(new Thing(200, 300, 240, 50, 1));
		temp.add(new Thing(500, 200, 240, 50, 1));
		
		things.add(temp);	
	}
	
	public void update(GameContainer gc, int delta) throws SlickException{
		if(keys[Input.KEY_UP]){
			player.velo = player.maxJump;
			keys[Input.KEY_UP] = false;
		}
		
		if(keys[Input.KEY_DOWN]){
			keys[Input.KEY_DOWN] = false;
		}
		
		if(keys[Input.KEY_LEFT]){
			player.delta -= player.speed;
			
			if(player.delta < -player.maxSpeed)
				player.delta = -player.maxSpeed;
		}
		
		else if(keys[Input.KEY_RIGHT]){
			player.delta += player.speed;
			
			if(player.delta > player.maxSpeed)
				player.delta = player.maxSpeed;
		}
		
		else{
			if(player.delta < -0.5){
				player.delta += player.speed;
			}

			else if(player.delta > 0.5){
				player.delta -= player.speed;
			}
			
			else if(player.delta > -0.5 && player.delta < 0.5){
				player.delta = 0;	
			}
		}
		
		if(player.delta < 0)
			player.moveLeft(things.get(level));
		
		else if(player.delta > 0)
			player.moveRight(things.get(level));
		
		if(player.velo < 0)
			player.moveUp(things.get(level));
		
		else
			player.moveDown(things.get(level));
		
		
		things.get(level).get(1).moveRight(player, things.get(level));
		
	}
	
	public void render(GameContainer gc, Graphics g) throws SlickException{
		g.setColor(new Color(0,55,55));
		g.fillRect(0, 0, 640, 480);
		
		g.setColor(new Color(255,0,0));
		g.fillRect(player.x, player.y, player.width, player.height);
		
		for(int i = 0; i < things.get(level).size(); i++){
			if(things.get(level).get(i).type == 1)
				g.setColor(new Color(0,100,100));
			
			g.fillRect(things.get(level).get(i).x, things.get(level).get(i).y,things.get(level).get(i).width, things.get(level).get(i).height);
		}
	}
	
	public void keyPressed(int key, char c) {
		keys[key] = true;
	}
	
	public void keyReleased(int key, char c) {
		keys[key] = false;
	}
	
	public static void main(String[] args) throws SlickException{
		 AppGameContainer app =
			new AppGameContainer( new Platformer() );
		
		 app.setShowFPS(false);
		 app.setAlwaysRender(true);
		 app.setTargetFrameRate(60);
		 app.setDisplayMode(640, 480, false);
		 app.start();
	}

	
	class Player{
		float x = 50;
		float y = 50;
		
		float delta = 0; // x momentum
		float velo = 0;
		int height = 50;
		int width = 30;
		float speed = 0.2f;
		int maxSpeed = 6;
		int maxFallSpeed = 5;
		int maxJump = -8;
		
		public void moveLeft(Vector<Thing> things){
			x += delta;
			
			if(x < 0)
				x = 0;
			
			for(int i = 0; i < things.size(); i++){
				if(new Rectangle((int) x, (int) y, width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){
					x += (things.get(i).x + things.get(i).width) - x;
					delta = 0;
				}
			}
		}
		
		public void moveRight(Vector<Thing> things){
			x += delta;
			
			if(x + width > 640)
				x = (640 - width);
			
			for(int i = 0; i < things.size(); i++){
				if(new Rectangle((int) x, (int) y, width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){
					x -= (x + width) - things.get(i).x;
					delta = 0;
				}
			}
		}
		
		public void moveLeftWithThing(Vector<Thing> things, float thingSpeed){
			x -= thingSpeed;
			
			if(x < 0)
				x = 0;
			
			for(int i = 0; i < things.size(); i++){
				if(new Rectangle((int) x, (int) y, width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){
					x += (things.get(i).x + things.get(i).width) - x;
					delta = 0;
				}
			}
		}
		
		public void moveRightWithThing(Vector<Thing> things, float thingSpeed){
			x += thingSpeed;
			
			if(x + width > 640)
				x = (640 - width);
			
			for(int i = 0; i < things.size(); i++){
				if(new Rectangle((int) x, (int) y, width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){
					x -= (x + width) - things.get(i).x;
					delta = 0;
				}
			}
		}
		
		public void moveUp(Vector<Thing> things){
			y += velo;

			velo += speed;
			
			if(velo > maxFallSpeed)
				velo = maxFallSpeed;
			
			for(int i = 0; i < things.size(); i++){
				if(new Rectangle((int) x, (int) y, width, height/2).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){
					y += (things.get(i).y + things.get(i).height) - y;
					velo = 0;
				}
			}
		}
		
		public void moveDown(Vector<Thing> things){
			y += velo;

			velo += speed;
			
			if(velo > maxFallSpeed)
				velo = maxFallSpeed;
			
			
			boolean b = false;
			for(int i = 0; i < things.size(); i++){
				if(!b && new Rectangle((int) x, (int) y + (height/2), width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){
					y -= (y + height) - things.get(i).y;
					velo = 0;
				}
			}
		}
		
	}
	
	class Thing{
		float x = 50;
		float y = 50;
		int height = 50;
		int width = 30;
		int type = -1;
		float speed = 0.5f;
		
		public Thing(float x, float y, int width, int height, int type){
			this.x = x;
			this.y = y;
			this.width = width;
			this.height = height;
			this.type = type;
		}
		
		public void moveUp(Player player){
			y -= 0.5f;
			
			if(new Rectangle((int) x,(int) y, width, height).intersects(new Rectangle((int) player.x, (int) player.y, player.width, player.height))){
				player.y -= (player.y + player.height) - y;
				player.velo = 0;
			}
		}
		
		public void moveRight(Player player, Vector<Thing> things){
			x += speed;
			
			if(new Rectangle((int) x,(int) y - 1, width, height).intersects(new Rectangle((int) player.x, (int) player.y, player.width, player.height))){
				player.moveRightWithThing(things, speed);
			}
		}
	}
	
}


And here is the demo: http://prime.programming-designs.com/java/platformer_demo/platdemo.jnlp

for(int i = 0; i < ALL_KEYS; i++){
	keys[i] = false;
}

Just wanted to point out that that loop is unnecessary. When you create a boolean-array, all values are already set to false :slight_smile:

EDIT: I also figured out why you get pushed to the left side of the static, non-moving platform if you touch both the moving and the non-moving platform at the same time.
I believe it is because when you check for collissions, the game thinks you are colliding with the right side of the top platform even though you are colliding with the moving one.
I suggest you separate the collission and moving code. First move the objects and then check for collissions and re-position the player.