Jump to content

  • Log In with Google      Sign In   
  • Create Account


Java: Looking for tips on Square to Square stationary collision response.


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 tom_mai78101   Members   -  Reputation: 568

Like
0Likes
Like

Posted 19 August 2012 - 06:54 AM

DISCLAIMER: WALL OF TEXT!!

Here's a diagram:

Posted Image

I'll give out a little more information about the diagram. The bend I designed is basically squares within squares. The green ball you see above is controlled by an accelerometer, which it's not like Pong or Breakout (where an object moves in a straight line until it hits an obstacle.) This means that a different type of collision response is needed.

You can also see that I treat the green ball as a green box. At the bottom-most, right-most corner, I put a red square underneath the green object. It means when the green object touches the blue obstacle, it stops entering. This is my ultimate goal.

I do not want the object to bounce off the obstacle, as it's not my main intention. Rather, I want to stop the object from entering the obstacle, or as in other words, "stay outside of the obstacle, but the object can move alongside the obstacle wall".

And here's the code I came up with:

public void collideInner(Ball b) {
  // width and height of the inner square is PIPE_SIZE *4
 
  // Inner box
  float width = PIPE_SIZE*4;
  float height = PIPE_SIZE*4;
  float left = dstRect.left;
  float top = dstRect.top;
  float tempX = b.position[0];
  float tempY = b.position[1];
 
  if (top + height > b.position[1] - b.radius){
   if (left + width > b.position[0] - b.radius){
    //b.position[0] = left + width + b.radius;
    //b.position[1] = top + height + b.radius;
    if (left + width <= b.position[0] - b.radius - b.speed[0]){
	 b.position[0] = left + width + b.radius;
	 b.position[1] = tempY;
    }
    Log.d("Corner", "Phase 2");
    return;
   }
   else {
    b.position[0] = left + width + b.radius;
    b.position[1] = tempY;
    Log.d("Corner", "Phase 1");
    return;
   }
  }
  else {
   if (left + width > b.position[0] - b.radius){
    //b.position[0] = tempX;
    //b.position[1] = top + height + b.radius;
    Log.d("Corner", "Phase 3");
    return;
   }
   else {
    //b.position[0] = tempX;
    //b.position[1] = tempY;
    Log.d("Corner", "Phase 4");
    return;
   }
  }
 
}

dstRect is a class that contains the margin size from all 4 sides of the monitor screen. The members are type float, each named as top, bottom, left, and right. When top = 4, it means that the distance from the top of the monitor screen is 4.0 pixels away. And so forth for the rest of the members.

I split the logic up into 4 equal parts, Phase 1 through 4, each symbolizing the respective quadrants, I, II, III, and IV. From there, I used the design where the obstacle is located in the quadrant II portion of the bend.

The main problem in my code, is that I am unable to keep the object outside of the obstacle. It either moves freely into the obstacle, or it jumps top to down, or left to right. It will never ceases to jump around.

Therefore, I'm looking for tips/hints. If anyone has finished reading this sentence, you are god among many other gods! I'm sorry for the wall of text. Thanks in advance.

Sponsor:

#2 thok   Members   -  Reputation: 688

Like
1Likes
Like

Posted 27 August 2012 - 07:45 AM

I'm not sure if I understanding entirely the game mechanics you are going for, so forgive me. It seems like you're struggling with basic concepts of movement and collision response, and I think there is a much simpler (and more stable) way of handling this. Below is what I've implemented in my simple 2D game project. It's pretty straightforward. It may not work so well in more complex physics simulations, but for simple stuff it's okay.
  • Instead of trying to prevent two objects from overlapping, let them. This overlap is your collision area. The area has a size and shape (which is, in this case, just another rectangle). I'll explain below how to deal with this.
  • When your ball moves through 2D space, it should have an X velocity and a Y velocity. These values indicate how far (in pixels, for example) your ball needs to move on a given axis per update. Various forces (gravity, user input, etc.) can change these values.
  • When you do a game update, move one axis at a time. Check for collisions on that axis, respond to any that occurred, and do the next axis. (It's doesn't really matter which axis you do first, except in some extreme cases. For now, don't worry about it.)
  • When you move on a given axis, the moving object has either a positive or negative velocity on that axis. The sign of this values tells you which direction the object is moving (up vs. down on the Y axis, left vs. right on the X axis).
  • For each object that your moving object could possibly collide with, check for an intersection. Hint: If you don't want to code this yourself, have a look at http://docs.oracle.com/javase/6/docs/api/java/awt/geom/Rectangle2D.Double.html#createIntersection(java.awt.geom.Rectangle2D).
  • As I mentioned before, each intersection has a size. This tells you how much your moving object is overlapping with the object it hit.
  • Given this size, you know exactly how far you need to move (in the opposite direction) to get out of the intersection. Again, the axis is relevant.
This method of responding to collisions (called "projection") is briefly mentioned in this article: http://www.metanetsoftware.com/technique/tutorialA.html#section0

Projection [Jakobsen] is one physically-plausible method for dealing with overlapping ("penetrating") objects. The basic idea is to move the objects out of penetration using the smallest possible displacement. Solving the collision then becomes equivalent to finding the vector v which moves the two objects out of penetration by the shortest distance possible.


Hope that helps.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS