Author Topic: Suggestion: hitFloor(Contact:FlxCore = null)  (Read 3036 times)

PizzaBoy

  • Guest
Suggestion: hitFloor(Contact:FlxCore = null)
« on: Sun, Nov 22, 2009 »
hitFloor, hitWall, and hitCeiling should pass what object was hit so you can get information about it. For example, a moving platform going up should go down if it hits a ceiling, but not if it hits a player riding it:

Code: [Select]
override public function hitCeiling(Contact:FlxCore = null):Boolean
{
if (Contact is Player) return false;
speedY = -speedY;
return true;
}

Socapex

  • Active Member
  • ***
  • Posts: 156
  • Karma: +0/-0
    • View Profile
Re: Suggestion: hitFloor(Contact:FlxCore = null)
« Reply #1 on: Sun, Nov 22, 2009 »
I would personnally love some implementation of this, but I don't know how hard it would be to code?
Free cake every day at #flixel on irc.freenode.net.
Use your favorite IRC client or  http://webchat.freenode.net/

Adam Atomic

  • Founder
  • Key Contributor
  • *****
  • Posts: 852
  • Karma: +0/-0
  • new dad
    • View Profile
    • Adam Atomic
Re: Suggestion: hitFloor(Contact:FlxCore = null)
« Reply #2 on: Sun, Nov 22, 2009 »
NO worries, this is very high on the list ofthings to stick in :)

PizzaBoy

  • Guest
Re: Suggestion: hitFloor(Contact:FlxCore = null)
« Reply #3 on: Tue, Nov 24, 2009 »
Edit- If you read this before I edited, double check it.

Replace the functions in FlxCore with

Code: [Select]
//@desc Called when this object collides with a FlxBlock on one of its sides
//@return Whether you wish the FlxBlock to collide with it or not
virtual public function hitWall(Contact:FlxCore = null):Boolean { return true; }

//@desc Called when this object collides with the top of a FlxBlock
//@return Whether you wish the FlxBlock to collide with it or not
virtual public function hitFloor(Contact:FlxCore = null):Boolean { return true; }

//@desc Called when this object collides with the bottom of a FlxBlock
//@return Whether you wish the FlxBlock to collide with it or not
virtual public function hitCeiling(Contact:FlxCore = null):Boolean { return true; }

And you'll have to update the overrides in FlxSprite:

Code: [Select]
//@desc Called when this object collides with a FlxBlock on one of its sides
//@return Whether you wish the FlxBlock to collide with it or not
override public function hitWall(Contact:FlxCore = null):Boolean { velocity.x = 0; return true; }

//@desc Called when this object collides with the top of a FlxBlock
//@return Whether you wish the FlxBlock to collide with it or not
override public function hitFloor(Contact:FlxCore = null):Boolean { velocity.y = 0; return true; }

//@desc Called when this object collides with the bottom of a FlxBlock
//@return Whether you wish the FlxBlock to collide with it or not
override public function hitCeiling(Contact:FlxCore = null):Boolean { velocity.y = 0; return true; }

FlxCore.collide (note: taken from B-Flixel version C, may not match normal Flixel...)

Code: [Select]
//@desc Collides a FlxSprite against this block
//@param Spr The FlxSprite you want to collide
virtual public function collide(Spr:FlxSprite):void
{
if((Math.abs(Spr.x + (Spr.width>>1) - x - (width>>1)) > (width>>1) + (Spr.width>>1)) && (Math.abs(Spr.y + (Spr.height>>1) - y - (height>>1)) > (height>>1) + (Spr.height>>1)))
return;

if((Spr.x > x) && (Spr.x + Spr.width < x + width))
{
if((Spr.y + Spr.height < y + (height>>1)) && (Spr.y + Spr.height > y) && Spr.hitFloor(this))
{
Spr.y = y - Spr.height;
return;
}
if((Spr.y > y + (height>>1)) && (Spr.y < y + height) && Spr.hitCeiling(this))
{
Spr.y = y + height;
return;
}
}
if((Spr.y > y) && (Spr.y + Spr.height < y + height))
{
if((Spr.x + Spr.width < x + (width>>1)) && (Spr.x + Spr.width > x) && Spr.hitWall(this))
{
Spr.x = x - Spr.width;
return;
}
if((Spr.x > x + (width>>1)) && (Spr.x < x + width) && Spr.hitWall(this))
{
Spr.x = x + width;
return;
}
}


var yFirst:Boolean = true;
if((Math.abs(Spr.velocity.x) > Math.abs(Spr.velocity.y)))
yFirst = false;

var checkForMoreX:Boolean = false;
var checkForMoreY:Boolean = false;
if(yFirst)
{
if(Spr.velocity.y > 0)
{
if(overlapsPoint(Spr.x + (Spr.width>>1),Spr.y + Spr.height))
{
if(Spr.hitFloor(this))
Spr.y = y - Spr.height;
}
else
checkForMoreY = true;
}
else if(Spr.velocity.y < 0)
{
if(overlapsPoint(Spr.x + (Spr.width>>1),Spr.y))
{
if(Spr.hitCeiling(this))
Spr.y = y + height;
}
else
checkForMoreY = true;
}

if(Spr.velocity.x < 0)
{
if(overlapsPoint(Spr.x,Spr.y + (Spr.height>>1)))
{
if(Spr.hitWall(this))
Spr.x = x + width;
}
else
checkForMoreX = true;
}
else if(Spr.velocity.x > 0)
{
if(overlapsPoint(Spr.x + Spr.width,Spr.y + (Spr.height>>1)))
{
if(Spr.hitWall(this))
Spr.x = x - Spr.width;
}
else
checkForMoreX = true;
}
}
else
{
if(Spr.velocity.x < 0)
{
if(overlapsPoint(Spr.x,Spr.y + (Spr.height>>1)))
{
if(Spr.hitWall(this))
Spr.x = x + width;
}
else
checkForMoreX = true;
}
else if(Spr.velocity.x > 0)
{
if(overlapsPoint(Spr.x + Spr.width,Spr.y + (Spr.height>>1)))
{
if(Spr.hitWall(this))
Spr.x = x - Spr.width;
}
else
checkForMoreX = true;
}

if(Spr.velocity.y > 0)
{
if(overlapsPoint(Spr.x + (Spr.width>>1),Spr.y + Spr.height))
{
if(Spr.hitFloor(this))
Spr.y = y - Spr.height;
}
else
checkForMoreY = true;
}
else if(Spr.velocity.y < 0)
{
if(overlapsPoint(Spr.x + (Spr.width>>1),Spr.y))
{
if(Spr.hitCeiling(this))
Spr.y = y + height;
}
else
checkForMoreY = true;
}
}

if(!checkForMoreY && !checkForMoreX)
return;
var bias:int = Spr.width>>3;
if(bias < 1)
bias = 1;
if(checkForMoreY && checkForMoreX)
{
if(yFirst)
{
if(checkForMoreY)
{
if((Spr.x + Spr.width - bias > x) && (Spr.x + bias < x + width))
{
if((Spr.velocity.y > 0) && (Spr.y + Spr.height > y) && (Spr.y + Spr.height < y + height) && Spr.hitFloor(this))
Spr.y = y - Spr.height;
else if((Spr.velocity.y < 0) && (Spr.y > y) && (Spr.y < y + height) && Spr.hitCeiling(this))
Spr.y = y + height;
}
}
if(checkForMoreX)
{
if((Spr.y + Spr.height - bias > y) && (Spr.y + bias < y + height))
{
if((Spr.velocity.x > 0) && (Spr.x + Spr.width > x) && (Spr.x + Spr.width < x + width) && Spr.hitWall(this))
Spr.x = x - Spr.width;
else if((Spr.velocity.x < 0) && (Spr.x > x) && (Spr.x < x + width) && Spr.hitWall(this))
Spr.x = x + width;
}
}
}
else
{
if(checkForMoreX)
{
if((Spr.y + Spr.height - bias > y) && (Spr.y + bias < y + height))
{
if((Spr.velocity.x > 0) && (Spr.x + Spr.width > x) && (Spr.x + Spr.width < x + width) && Spr.hitWall(this))
Spr.x = x - Spr.width;
else if((Spr.velocity.x < 0) && (Spr.x > x) && (Spr.x < x + width) && Spr.hitWall(this))
Spr.x = x + width;
}
}
if(checkForMoreY)
{
if((Spr.x + Spr.width - bias > x) && (Spr.x + bias < x + width))
{
if((Spr.velocity.y > 0) && (Spr.y + Spr.height > y) && (Spr.y + Spr.height < y + height) && Spr.hitFloor(this))
Spr.y = y - Spr.height;
else if((Spr.velocity.y < 0) && (Spr.y > y) && (Spr.y < y + height) && Spr.hitCeiling(this))
Spr.y = y + height;
}
}
}
}
else if(checkForMoreY)
{
if((Spr.x + Spr.width - bias > x) && (Spr.x + bias < x + width))
{
if((Spr.velocity.y > 0) && (Spr.y + Spr.height > y) && (Spr.y + Spr.height < y + height) && Spr.hitFloor(this))
Spr.y = y - Spr.height;
else if((Spr.velocity.y < 0) && (Spr.y > y) && (Spr.y < y + height) && Spr.hitCeiling(this))
Spr.y = y + height;
}
}
else if(checkForMoreX)
{
if((Spr.y + Spr.height - bias > y) && (Spr.y + bias < y + height))
{
if((Spr.velocity.x > 0) && (Spr.x + Spr.width > x) && (Spr.x + Spr.width < x + width) && Spr.hitWall(this))
Spr.x = x - Spr.width;
else if((Spr.velocity.x < 0) && (Spr.x > x) && (Spr.x < x + width) && Spr.hitWall(this))
Spr.x = x + width;
}
}
}

Then just use it in your class by overriding the function, example:

Code: [Select]
override public function hitWall(Contact:FlxCore = null):Boolean
{
if (Contact is VertPlatform) return false;
return super.hitWall(Contact);
}
« Last Edit: Tue, Nov 24, 2009 by PizzaBoy »

ShooterMG

  • Member
  • **
  • Posts: 71
  • Karma: +0/-0
    • View Profile
Re: Suggestion: hitFloor(Contact:FlxCore = null)
« Reply #4 on: Tue, Nov 24, 2009 »
Thanks for taking the time out to post the code, I'll definitely be using this  :)

Socapex

  • Active Member
  • ***
  • Posts: 156
  • Karma: +0/-0
    • View Profile
Re: Suggestion: hitFloor(Contact:FlxCore = null)
« Reply #5 on: Wed, Nov 25, 2009 »
Awesome!!! Thanks so much. This will be really useful for falling platforms.
Free cake every day at #flixel on irc.freenode.net.
Use your favorite IRC client or  http://webchat.freenode.net/

Adam Atomic

  • Founder
  • Key Contributor
  • *****
  • Posts: 852
  • Karma: +0/-0
  • new dad
    • View Profile
    • Adam Atomic
Re: Suggestion: hitFloor(Contact:FlxCore = null)
« Reply #6 on: Thu, Nov 26, 2009 »
checked this in to github tonight!  along with some other stuff...

MattB

  • Member
  • **
  • Posts: 28
  • Karma: +0/-0
    • View Profile
Re: Suggestion: hitFloor(Contact:FlxCore = null)
« Reply #7 on: Tue, Dec 22, 2009 »
I'm currently working on a game where the map is largely assembled from larger FlxSprites that the player collides with. Upon updating to v1.26 the player now causes the floors to sink, move far to the left, etc, etc. Upon setting the hitFloor, Ceiling, Wall, functions to return false, the map objects no longer jump around when the player hits them, but the player still slowly sinks into them, wades through them like quick sand.

I'm at a loss as to what to do about it.

MattB

  • Member
  • **
  • Posts: 28
  • Karma: +0/-0
    • View Profile
Re: Suggestion: hitFloor(Contact:FlxCore = null)
« Reply #8 on: Tue, Dec 22, 2009 »
Alright... I just updated to version 1.40 and... I'm pretty sure this'll have to stay a 1.25 project.