[Movement problem Java2D If and Else statements]

Hey JGO.

I was implementing a collision detection system today for my 2D game’s entity system, and I came across a issue regarding If and Else statements and how they’re executed.

The issue I’m having:
How my collision movement is handled.
Since Java executes methods in a code block by the order they were written in, my method is choosing to favor 1 or the other of the If and Else statements that are used to handle my players movement.

Result on game play:
If the statement for handling left/right collision is put before handling up/down collision, the player when colliding with a entity’s top or bottom is not able to press left or right and be able to slide along the entity’s X axis.

This is vice versa for putting the up/down collision if and else statement before the left/right if and else collision statement, the player cannot slide up/down along the players Y axis.

(The entity in this case is a rock)

Here are the 2 If and Else statements:


/* Statement Number 1 handles moving Left and Right */
if (mapMovingLeft) {
	if (!rightCollision) { 
			setMap1X(getMap1X() + map1VelX);
	}
	leftCollision = downCollision = upCollision = false;
} else if (mapMovingRight) {
	if (!leftCollision) {
		setMap1X(getMap1X() - map1VelX);
	}
	rightCollision = downCollision = upCollision = false;
}

/* Statement Number 2 handles moving Up and Down */				
if (mapMovingUp) {
	if (!downCollision) {
			setMap1Y(getMap1Y() + map1VelY);
	}
	leftCollision = rightCollision = upCollision = false;
} else if (mapMovingDown) {
	if (!upCollision) {
			setMap1Y(getMap1Y() - map1VelY);
	}
	leftCollision = rightCollision = downCollision = false;
}

If anyone is thinking the issue I’m having is related to how I wrote my collision, here is 1 / 4 methods implemented in Paste Bin:
http://pastebin.com/yYBrvtnq

Hope somebody can help / understand thanks.

I had that problem one time, too. You can reverse the order of your code by using constructs like this:

do
{
  // ...
} while(expression);

{
  // stuff
} if(otherExpression);

If statements work exactly the way they are supposed to. Same for while loops. (Didn’t you make a topic about those, too?) You need to learn to debug your own code. Use debuggers and System.out.println(), debug graphics, or logs to diagnose problems.

That doesn’t reverse the order of your code.

Also, your if statement is bizarre. Please note this is valid syntax:


{
   // do something
}

And this is also valid syntax:


if ( condition );

Putting one on the same line of the other doesn’t do anything.

Also note that your if doesn’t do anything, it checks for condition and then no-ops. These are all equivalent:


if ( condition );

if ( condition )
   ;

if ( condition ) {

}

Now that we have that cleared up, to the question at hand!

Given your experience I’ll explain a simple solution, because in reality collision detection/resolution is a fairly complicated problem, and difficult to get right.

If you have two entities that intersect, find the “penetration” distance for all sides (TBRL). Find the smallest positive penetration distance and adjust that side only, this will correct the positions.

There are tons of problems with this method of course, the entities could be moving too fast and pass through each other. Not only that, if they’re moving fast enough the one entity could appear on the other side of an entity due to its quick speed and the opposite adjustment will occur. You could avoid this problem by taking velocity into account (only check for bottom collisions if the entity is moving down, etc). You could avoid all of these problems by choosing smart fixed time steps and maximum velocities.

I hope this helps.

Indeed! Very good points, ClickerMonkey.

I use a variable timeStep, and for fast-moving objects like projectiles, I usually just make a loop around my update methods, and divide the deltaTime I give it with some divisor like 3, and make it go until the deltaTime has been reached; with a limit, obviously, to ensure that it doesn’t loop more than three times because of some float-bug. Then I can easily adjust the divisor, until I’m satisfied with the performance and precision.

EDIT: And for better understanding 2D collisions, you should read my article on 2D platformer collisions. Just read until Step 1, and you’ll get an idea of how things could work. Although…just use libgdx :slight_smile:

@ClickerMonkey:
My collision detection/resolution is flawless ATM :point:
No sliding through entity’s, I correct that before it has a chance to happen.
I Implemented a fixed time step.
My velocity at the moment is either going to be 2 (walking) or 3 (sprinting).

@Best Username Ever:
I actually do debug my programs :smiley:
If you haven’t noticed every WIP I post has tons of variables rendered to the screen for that purpose.

My only problem is the order of which my if and else statements are being executed.


Type #1
/* Which ever statement is put first is favored */
if (left) {
} else if (right) {
}

if (up) {
} else if (down) {
}

Type #2
/* Player can only move 1 direction */
if (left) {
} else if (right) {
} else if (up) {
} else if (down) {

Type #3
/* Still favors the first 2 statements */
if (left) {
}
if (right) {
}
if (up) {
}
if (down) {
}

Any feedback is welcome guys.

The only thing that makes sense in there is the do { } while(condition); statement lol.

Adding a bracket after the while expression, but before the if statement wont change anything o.O.

That’s basically like doing:


do {
	// ...
} while(expression);

{ // <-- Simply decoration, doesn't matter how many are present as long as each starting bracket has a corresponding ending bracket.
	execute(); // stuff
{ // <-- Simply decoration, doesn't matter how many are present as long as each starting bracket has a corresponding ending bracket.
		
if (otherExpression) { }

The ‘stuff’ will get executed regardless o.O

A bare block has its own lexical scope, so you can declare locals inside it that are only visible to that block. It’s not a very common idiom in java code though.

Let’s just agree to disagree. :slight_smile: I have plenty of experience that says otherwise. It compiles so there must be no problem except for the occasional problem you can blame on the compiler or the programming language. Let’s talk about fl esie statements and lhewi loops. You can use these keywords to totally randomize the order of statements execute within a fl, esie, or lhewi block. It is quite a useful language construct, is it not?

You are a dirty dirty troll :stuck_out_tongue:

I never knew that until last night LOL.


public class DISCOVERY {
	
	public static void main(final String[] args) {
		new DISCOVERY();
	}
	
	{
		System.out.println("This gets printed.");
		{
			System.out.println("Before this gets printed.");
			{
				System.out.println("<( <>..<> )>");
			}
		}
	}
	
	// Discovery Made 1/21/2013. XD
}

It prints them in orderly fashion 8)

Takes a bow I almost included the lhewi loop in my first post, but I thought it would be too subtle.

static
{
  Blocks.areVeryUseful = true;
}

Well, I’ll be closing this thread soon, feedback on the issue at hand has halted o.O

I’m pretty sure I know what I have to do to fix my issue.
Just adjust the current collision mode to FAVOR_X_AXIS / FAVOR_Y_AXIS depending on how the player’s currently colliding with the entity, also some tricky variable resetting/enabling D:

Thanks for all the feedback so far guys ;D

@Best Username Ever:
I did know about using brackets with a static context for initialization of a classes variables. :emo:

Ever have a person that doesn’t have much computer knowledge ask you for computer help try explain the problem without explaining crucial details or showing you the computer itself? There is a joke where the a person asking for computer help says something like this: “Help me. My computer stopped working after I deleted all my old Excel files.”
Other person: “What is the problem?”
First person: “It doesn’t work.”
Other person: “Explain what happened before that.”
First person: “I deleted my Excel files.”
Other person: “How did you do that?”
First person: “I put all my Excel files in the trash.”
Other person: “Explain it step by step.”
First person: “I just did a search for all .exe files and deleted them all.”

Your questions will keep going unanswered unless you give important background information. If you don’t have more information, then you need to spend more time isolating the problem first. Your first post does not tell anyone anything they can use to help you.

I explained my problem fine IMO.
Well explained diagram + multiple direct code snippets.

I said. :-
“I believe I know what I need to do here”.
If it’s choosing to favor one or the other (up/down or right/left), all I have to do (implemented it on one side) is check the ‘Collision Type’ and toggle it to the current axis.