Be a Supporter!

Mario like collision detection

  • 1,075 Views
  • 3 Replies
New Topic Respond to this Topic
raidthewood
raidthewood
  • Member since: Apr. 7, 2010
  • Offline.
Forum Stats
Member
Level 04
Blank Slate
Mario like collision detection 2012-03-29 21:44:16 Reply

Hey all! I've been having troubles with my current project, been trying to solve it for MONTHS! I cannot figure out how to get that mario style of collision detection into my game! The project generates each chunk of screen with bunches of blocks.

My failure of a method consists of checking each block in a forloop for detection, then deciding via distance which side the character is closest to and taking the appropriate action. Its so sloppy, jittery, and glitchy, I need something SOLID! Any ideas im desperate here. For all the experience I have this seems insane how I cannot figure this out.

A list of things I'd like to accomplish:

Solid character landing, he falls through the ground on occasion.

Solid wall collision, he walks through them sometimes as well.

The character for some reason flies up to the top of every section of blocks no matter what for some reason, I'd like to eliminate this.

The character needs to bounce off the bottom of the platforms.

Heres my code:

for (var i:int = 0; i < specBlockArray.length; i++) {
					
					if(char.hitTestObject(specBlockArray[i][0]) && specBlockArray[i] !== null){
						var specX:Number = specBlockArray[i][0].x;
						var specY:Number = specBlockArray[i][0].y;
						
						var lDist:Number = specX - (char.x + 9);
						var rDist:Number = (char.x - 9) - (specX + 20);
						var tDist:Number = (specY) - (char.y);
						var bDist:Number = (char.y - 32) - (specY + 20);
						
						prevBlock = specBlockArray[i][0];
						
						
						if(!lDist <= 0 && !rDist <= 0){
							if (tDist > bDist) {
								trace("Top");
								char.y = specY;
								velY = 0;
								alreadyHit = true;
								
							}else{
								trace("Bottom");
								char.y = specY + 54;
								velY = 0;
								falling = true;
								alreadyHit = true;
								
							}
						}
						if(!tDist <= 0 && !bDist <= 0){
							if (lDist > rDist) {
								trace("Left");
								char.x = specX - 9;
								velX = 0;
								alreadyHit = true;
								
							}else if(rDist > lDist){
								trace("Right");
								char.x = specX + 29;
								velX = 0;
								alreadyHit = true;
								
							}
						}
						
					}

Heres what this absurd method produces:

http://www.newgrounds.com/dump/item/1a5ea42fc7707c585f76aa68 f90e2a1e

All in all, any ideas or links to tutorials or related threads would be awesome, and much appreciated! Hope someone can help! Thanks!

4urentertainment
4urentertainment
  • Member since: Aug. 1, 2008
  • Offline.
Forum Stats
Moderator
Level 13
Game Developer
Response to Mario like collision detection 2012-03-30 05:00:38 Reply

While it's nice you're trying to come up with your own collision algorithm, it would be much easier for you to choose and implement an already made collision algorithm, engine or simply make use of flash's built in functions which should suffice in this case.

AS3 has two good functions for this, hitTestObject and hitTestPoint.

Simply put, hitTestObject tests for overlap of the bounding boxes between two movieclips, and returns true if there is an overlap.

if(MC1.hitTestObject(MC2)){
//COllision!
}

While this is nice, it doesn't really tell you where the point of collision is. hitTestPoint can be more accurate. hitTestPoint checks for collision between a point and a movieclip.

So if you do:

if(MC1.hitTestPoint(100,100,true)){
//Collision!
}

The code in the if statement will work as long as the point (100,100) is touching anything on the shape of the movieclip, not the bounding box. So even if your character isn't rectangular, this will only return true as long as it's hitting the actual character. So how do you use this for your character collision? Simply replace (100,100) with a point on your character that you wish to test.

if(Ground.hitTestPoint(player.x,player.y + 50,true)){
//collision
}

Assuming the player's registration point is in the center, and the height is 100. The point (player.x,player.y+50) will be a point on the bottom of the player. So what you want to do when reaching this point is colliding is push the player up. For it to look good, one way to do it would be to place this condition in a while loop, such that as long as the player is colliding, the loop will keep running until he is no longer colliding.

Now just do the same for all four sides, placing one point on each side (or more if you want more accuracy) and you get mostly perfect collisions.

Hope this helped and feel free to ask again if anything is unclear or if you need anymore help!

raidthewood
raidthewood
  • Member since: Apr. 7, 2010
  • Offline.
Forum Stats
Member
Level 04
Blank Slate
Response to Mario like collision detection 2012-03-30 15:45:49 Reply

Wow thats brilliant XD! I've never actually given hitTestPoint any thought before, THANKS!

maringtr
maringtr
  • Member since: Sep. 16, 2011
  • Offline.
Forum Stats
Member
Level 03
Programmer
Response to Mario like collision detection 2012-04-06 12:57:35 Reply

hitTestPoint() and hitTestObject() have their pros and cons. For a Mario-styled game, I personally prefer to code my own hit tests as well, based on basic math. If done right, this may result in a really smooth running and light game.