Hit-test problem? (AS3)
- mmcxii
-
mmcxii
- Member since: Jan. 1, 2011
- Offline.
-
- Forum Stats
- Member
- Level 10
- Game Developer
I'm having trouble with my player falling through the ground when landing and I can't seem to fix it. Here is the code I'm using:
if (player.y + player.height / 2 >= ground.y - ground.height / 2)
{
player.y = (ground.y - ground.height / 2) - (player.height / 2 );
Player.onGround = true;
}
http://www.newgrounds.com/dump/item/ac962827ba3d67b45d9e485c 7f19788f
To me it seems like the
player.y = (ground.y - ground.height / 2) - (player.height / 2 );
line isn't being read fast enough or something, but I'm not sure. Any ideas?
- MintPaw
-
MintPaw
- Member since: Jun. 11, 2006
- Offline.
-
- Forum Stats
- Member
- Level 10
- Programmer
At 8/3/13 01:47 PM, mmcxii wrote: I'm having trouble with my player falling through the ground when landing and I can't seem to fix it. Here is the code I'm using:
if (player.y + player.height / 2 >= ground.y - ground.height / 2)
{
player.y = (ground.y - ground.height / 2) - (player.height / 2 );
Player.onGround = true;
}
http://www.newgrounds.com/dump/item/ac962827ba3d67b45d9e485c 7f19788f
To me it seems like the
player.y = (ground.y - ground.height / 2) - (player.height / 2 );
line isn't being read fast enough or something, but I'm not sure. Any ideas?
You do realize with this approach you can only have one ground with one height right? In that case you may as well go:
if (player.y > 500) player.y = 500;
- mmcxii
-
mmcxii
- Member since: Jan. 1, 2011
- Offline.
-
- Forum Stats
- Member
- Level 10
- Game Developer
At 8/3/13 01:54 PM, MintPaw wrote: You do realize with this approach you can only have one ground with one height right? In that case you may as well go:
if (player.y > 500) player.y = 500;
Damn, you are right. I was wondering how I would go about adding platforms and what not. What is the best way to go about this?
- MintPaw
-
MintPaw
- Member since: Jun. 11, 2006
- Offline.
-
- Forum Stats
- Member
- Level 10
- Programmer
Put multiple "grounds" in one array and loop through them to test collision. Although even then your current method isn't going to work, you're basically saying "If the player is lower than this object, bump the player up to this object" Which when you include multiple grounds the player is always going to be bumped up to the highest one regardless of whether or not the player should be on that ground.
You need to use true gravity and collision, constantly move the player downward and bump him up when he moves through a "ground".
It's very easy if your platforms will all be rectangles, just simply check if the bottom centre point if the player is intersecting the rectangle that represents the ground here's a page that talks about that operation. Although you could probably just Google "Point in a rectangle" to find some info on it.
- mmcxii
-
mmcxii
- Member since: Jan. 1, 2011
- Offline.
-
- Forum Stats
- Member
- Level 10
- Game Developer
At 8/3/13 02:39 PM, MintPaw wrote: You need to use true gravity and collision, constantly move the player downward and bump him up when he moves through a "ground".
Shouldn't my code still prevent the player from falling through slightly after jumping? What's the reason it's happening?
- mmcxii
-
mmcxii
- Member since: Jan. 1, 2011
- Offline.
-
- Forum Stats
- Member
- Level 10
- Game Developer
Still having problems with this. Can anyone explain how adding multiple platforms would work? Do I just use .push to push them into an array then use platform[i] to figure out which one he is standing on?
Also, I'm still having trouble with why my player falls slightly through the ground every time he jumps.
Thanks
- HappyWhaleStudios
-
HappyWhaleStudios
- Member since: Feb. 1, 2013
- Online!
-
- Forum Stats
- Member
- Level 07
- Game Developer
Here's a way to use a similar method that supports multiple platforms:
var platforms:Array;
var floor:int = 1000;//some very high number that can be the very bottom where you fall off and die
var onPlatform:int = -1;
have this run every frame:
for(var i:int = 0; i<platforms.length; i++)
{
platforms[i].checkChar(i);
}
and when you create a platform:
var p:MovieClip = new Platform();//I'm assuming you know how to make that work, if not, say so in a reply
p.x=100;
p.y=100;
p.checkChar = function(place:int)
{
if(Math.abs(player.x-this.x)<=this.width/2+player.width/2&&p layer.y+player.height/2<this.y-this.height/2&&onPlatform!=pl ace&&!(floor<this.y-this.height/2))
{
onPlatform=place;
floor=this.y-this.height/2;
}
the absolute value gets the distance either way of the character from the center of the platform, and if the character is on the platform x-wise, it checks to see if the character is above the platform, the platform isn't already the one you're on, and the floor value isn't higher than what it already was (this fixes situations where there are multiple platforms stacked on top of each other). and then also this, to make sure that after the character is done on that platform, the floor readjusts:
if(Math.abs(this.x-char.x)>this.width/2&&onPlatform==place)
{
if(player.y==floor)
{
player.y-=2;//this way if there are 2 platforms right next to each other, the player can run across without falling through the second one
}
floor=1000;
onPlatform=-1;
}
- HappyWhaleStudios
-
HappyWhaleStudios
- Member since: Feb. 1, 2013
- Online!
-
- Forum Stats
- Member
- Level 07
- Game Developer
And after all that stuff, remember to addChild(p); and I forgot this, very important:
platforms.push(p);
I'm not sure if this fixes your original issue or not, I think it does, but this at least shows you one way that you can make multiple platforms using arrays in code
- milchreis
-
milchreis
- Member since: Jan. 11, 2008
- Offline.
-
- Forum Stats
- Member
- Level 26
- Programmer
At 8/6/13 12:03 AM, HappyWhaleStudios wrote: and when you create a platform:
var p:MovieClip = new Platform();//I'm assuming you know how to make that work, if not, say so in a reply
p.x=100;
p.y=100;
p.checkChar = function(place:int)
{
if(Math.abs(player.x-this.x)<=this.width/2+player.width/2&&p layer.y+player.height/2<this.y-this.height/2&&onPlatform!=pl ace&&!(floor<this.y-this.height/2))
{
onPlatform=place;
floor=this.y-this.height/2;
}
One should never assign methods dynamically like that. It should be done in the class.
Having the hittesting method as a member of Platform doesn't make much sense either.
It should be within the document class.
- mmcxii
-
mmcxii
- Member since: Jan. 1, 2011
- Offline.
-
- Forum Stats
- Member
- Level 10
- Game Developer
At 8/6/13 04:19 AM, milchreis wrote:At 8/6/13 12:03 AM, HappyWhaleStudios wrote: and when you create a platform:One should never assign methods dynamically like that. It should be done in the class.
var p:MovieClip = new Platform();//I'm assuming you know how to make that work, if not, say so in a reply
p.x=100;
p.y=100;
p.checkChar = function(place:int)
{
if(Math.abs(player.x-this.x)<=this.width/2+player.width/2&&p layer.y+player.height/2<this.y-this.height/2&&onPlatform!=pl ace&&!(floor<this.y-this.height/2))
{
onPlatform=place;
floor=this.y-this.height/2;
}
Having the hittesting method as a member of Platform doesn't make much sense either.
It should be within the document class.
Question, the way I have it setup currently is there is a movieclip on the stage called levelCaller that is my "document class" (I really don't use one). In the level caller I call the menu, then the first level, second, etc (all of those are in their own class). Is it best to do the platform testing in the levelCaller or should I be doing it in each level?
- Innermike
-
Innermike
- Member since: Sep. 11, 2009
- Offline.
-
- Forum Stats
- Member
- Level 14
- Blank Slate
Just a point on the side, 'hit-test' is a pretty specific thing, unless you're using the flash hit-test function then it's not a 'hit-test'.
At 8/3/13 02:39 PM, MintPaw wrote: You need to use true gravity and collision, constantly move the player downward and bump him up when he moves through a "ground".
But that's not 'true', when we fall we don't go down into the ground and then get pushed back out (normal reaction anybody?) if something is very thin and you're moving very fast you'll end up going straight through. It makes more sense to check the path he's moving in currently and predict any possible collisions.
nobody
- HappyWhaleStudios
-
HappyWhaleStudios
- Member since: Feb. 1, 2013
- Online!
-
- Forum Stats
- Member
- Level 07
- Game Developer
At 8/6/13 04:19 AM, milchreis wrote:At 8/6/13 12:03 AM, HappyWhaleStudios wrote: and when you create a platform:One should never assign methods dynamically like that. It should be done in the class.
var p:MovieClip = new Platform();//I'm assuming you know how to make that work, if not, say so in a reply
p.x=100;
p.y=100;
p.checkChar = function(place:int)
{
if(Math.abs(player.x-this.x)<=this.width/2+player.width/2&&p layer.y+player.height/2<this.y-this.height/2&&onPlatform!=pl ace&&!(floor<this.y-this.height/2))
{
onPlatform=place;
floor=this.y-this.height/2;
}
Having the hittesting method as a member of Platform doesn't make much sense either.
It should be within the document class.
Yeah you're right, I pulled this example off an old project of mine, I didn't feel like redoing it, that's just that way I learned it first. He's right, if you want to do this properly you should make a legitimate class for the platform instead of just extending the MovieClip class like I did in that example.
- mmcxii
-
mmcxii
- Member since: Jan. 1, 2011
- Offline.
-
- Forum Stats
- Member
- Level 10
- Game Developer
So I've decided to go with hitTestPoint and just throwing all the platforms for one level into it's own movie clip. This is the code I've written so far:
while (ground.hitTestPoint(player.x - player.width / 2, player.y + player.height / 2, true) && i < 10)
{
Player.speedY = 0;
Player.onGround = true;
player.y--;
i++;
}
while (ground.hitTestPoint(player.x + player.width / 2, player.y + player.height / 2, true) && i2 < 10)
{
Player.speedY = 0;
Player.onGround = true;
player.y--;
i2++;
}
The problem is for whatever reason is, well, just look what happens http://www.newgrounds.com/dump/item/4bb087831c2ffbcc27566e5f 45eadedd
- Sometimes he falls through slightly, then all the way.
- After you walk off the platform he doesn't drop down (seems like onGround is being read as true even if he isn't touching ground)
- mmcxii
-
mmcxii
- Member since: Jan. 1, 2011
- Offline.
-
- Forum Stats
- Member
- Level 10
- Game Developer
At 8/6/13 05:14 PM, mmcxii wrote: So I've decided to go with hitTestPoint and just throwing all the platforms for one level into it's own movie clip. This is the code I've written so far:
while (ground.hitTestPoint(player.x - player.width / 2, player.y + player.height / 2, true) && i < 10)
{
Player.speedY = 0;
Player.onGround = true;
player.y--;
i++;
}
while (ground.hitTestPoint(player.x + player.width / 2, player.y + player.height / 2, true) && i2 < 10)
{
Player.speedY = 0;
Player.onGround = true;
player.y--;
i2++;
}
The problem is for whatever reason is, well, just look what happens http://www.newgrounds.com/dump/item/4bb087831c2ffbcc27566e5f 45eadedd
- Sometimes he falls through slightly, then all the way.
- After you walk off the platform he doesn't drop down (seems like onGround is being read as true even if he isn't touching ground)
Okay, update, the variable i wasn't being reset to 0 after it reached 10. Still having him fall slightly through and still having the not dropping down problem. Updated the dump.
- MSGhero
-
MSGhero
- Member since: Dec. 15, 2010
- Offline.
-
- Forum Stats
- Supporter
- Level 16
- Game Developer
Why not use math instead of weird hitTests (that don't work)? A platform can be abstracted to a simple Rectangle (unless you have slopes, but same idea). The player can be abstracted to a Rectangle. Check if the two rectangles are overlapping. If the player isn't overlapping with any rectangles, then he's jumping or falling. Otherwise, move him to where he's no longer overlapping. The Rectangle class gives you intersect() and intersection() functions if you don't want to do the math yourself.
- mmcxii
-
mmcxii
- Member since: Jan. 1, 2011
- Offline.
-
- Forum Stats
- Member
- Level 10
- Game Developer
At 8/6/13 05:45 PM, MSGhero wrote: Why not use math instead of weird hitTests (that don't work)? A platform can be abstracted to a simple Rectangle (unless you have slopes, but same idea). The player can be abstracted to a Rectangle. Check if the two rectangles are overlapping. If the player isn't overlapping with any rectangles, then he's jumping or falling. Otherwise, move him to where he's no longer overlapping. The Rectangle class gives you intersect() and intersection() functions if you don't want to do the math yourself.
I mean it is working, I'm just having trouble setting onGround back to false when he isn't standing on the platforms. As in, when you just walk off it keeps onGround as true.
- mmcxii
-
mmcxii
- Member since: Jan. 1, 2011
- Offline.
-
- Forum Stats
- Member
- Level 10
- Game Developer
At 8/6/13 06:03 PM, mmcxii wrote: I mean it is working, I'm just having trouble setting onGround back to false when he isn't standing on the platforms. As in, when you just walk off it keeps onGround as true.
Okay, I fixed the on ground thing, but now it can't decide what animation to stick to.
http://www.newgrounds.com/dump/item/cabc8b3f74ab96b8dbbae623 fd62d218
- mmcxii
-
mmcxii
- Member since: Jan. 1, 2011
- Offline.
-
- Forum Stats
- Member
- Level 10
- Game Developer
At 8/6/13 06:45 PM, mmcxii wrote:At 8/6/13 06:03 PM, mmcxii wrote: I mean it is working, I'm just having trouble setting onGround back to false when he isn't standing on the platforms. As in, when you just walk off it keeps onGround as true.Okay, I fixed the on ground thing, but now it can't decide what animation to stick to.
http://www.newgrounds.com/dump/item/cabc8b3f74ab96b8dbbae623 fd62d218
Still can't seem to find a solution for this.
while (ground.hitTestPoint(player.x - player.width / 2 + 6, player.y + player.height / 2, true) && i < 10)
{
Player.onGround = true;
Player.speedY = 0;
player.y--;
i++;
switchThing = true;
}
while (ground.hitTestPoint(player.x + player.width / 2 - 6, player.y + player.height / 2, true) && i2 < 10)
{
Player.onGround = true;
Player.speedY = 0;
player.y--;
i2++;
switchThing = true;
}
Example of how I'm doing the hit-testing.
- Sam
-
Sam
- Member since: Oct. 1, 2005
- Offline.
-
- Forum Stats
- Moderator
- Level 19
- Programmer
Check a couple of pixels lower than you're collision test. The reason it's jumping between states is because you're constantly moving it by one pixel so for one frame it's colliding and therefore one state is active, and the next frame it's been moved by one pixel up and isn't colliding so is in a different state. If you check a couple of pixels below the player to see if the ground is actually there, you can use that as a hacky way of managing your states.
- mmcxii
-
mmcxii
- Member since: Jan. 1, 2011
- Offline.
-
- Forum Stats
- Member
- Level 10
- Game Developer
At 8/9/13 02:36 PM, Sam wrote: Check a couple of pixels lower than you're collision test. The reason it's jumping between states is because you're constantly moving it by one pixel so for one frame it's colliding and therefore one state is active, and the next frame it's been moved by one pixel up and isn't colliding so is in a different state. If you check a couple of pixels below the player to see if the ground is actually there, you can use that as a hacky way of managing your states.
What exactly do you mean check a couple pixels lower than my collision test?
Also, I figured it was because once it pushed it out of the collision test, the gravity instantly puts it back into the collision test so it keeps going back and forth. Is that correct?
- Sam
-
Sam
- Member since: Oct. 1, 2005
- Offline.
-
- Forum Stats
- Moderator
- Level 19
- Programmer
At 8/9/13 10:25 PM, mmcxii wrote: What exactly do you mean check a couple pixels lower than my collision test?
Could probably do something like this
if(ground.hitTestPoint(player.x + player.width / 2, player.y + player.height / 2 + 2, true))
{
Player.onGround = true;
}
else
{
Player.onGround = false;
}
Or maybe even:
Player.onGround = ground.hitTestPoint(player.x + player.width / 2, player.y + player.height / 2 + 2, true); - tareq8193
-
tareq8193
- Member since: Aug. 10, 2013
- Offline.
-
- Forum Stats
- Member
- Level 01
- Programmer
At 8/3/13 01:47 PM, mmcxii wrote: I'm having trouble with my player falling through the ground when landing and I can't seem to fix it. Here is the code I'm using:
if (player.y + player.height / 2 >= ground.y - ground.height / 2)
{
player.y = (ground.y - ground.height / 2) - (player.height / 2 );
Player.onGround = true;
}
http://www.newgrounds.com/dump/item/ac962827ba3d67b45d9e485c 7f19788f
To me it seems like the
player.y = (ground.y - ground.height / 2) - (player.height / 2 );
line isn't being read fast enough or something, but I'm not sure. Any ideas?
////----It seems your player and ground is into two different class that you've added into main class or you player is into ///---different class and ground into main class that you added player as you call a variable 'onGround' into main class, //---right?
///----push both them into array like:
var playerArray:Array = new Array();
var groundArray:Array = new Array();
playerArray.push(player);
groundArray.push(ground);
///----Make a for loop
for(var p:int=0; p<playerArray.length; p++){
var currentPlayer:player = playerArray[p];
for(var g:int=0; g<groundArray.lenght; g++){
var currentGround:ground = groundArray[g];
if (currentPlayer.y + currentPlayer.height / 2 >= currentGround.y - currentGround.height / 2)
{
currentPlayer.y = (currentGround.y - currentGround.height / 2) - (currentPlayer.height / 2 );
currentPlayer.onGround = true;
}
}
}
////-----You this code and it will work, I think, thanks

