package
{
public class Physics
{
public function newTrajectory(currentMoveDirection:int, hitTestResults:Object):int
{
if (currentMoveDirection < 1 || currentMoveDirection > 8)
{
throw new Error("Movement direction must be between one and eight");
return 0;
}
if (hitTestResults.next.A_RIGHT_HIT_RIGHT_OF_B || hitTestResults.next.A_RIGHT_HIT_LEFT_OF_B)
{
switch (currentMoveDirection)
{
case 2: return 8;
case 3: return 7;
case 4: return 6;
}
}
if (hitTestResults.next.A_LEFT_HIT_RIGHT_OF_B || hitTestResults.next.A_LEFT_HIT_LEFT_OF_B)
{
switch (currentMoveDirection)
{
case 8: return 2;
case 7: return 3;
case 6: return 4;
}
}
if (hitTestResults.next.A_TOP_HIT_TOP_OF_B || hitTestResults.next.A_TOP_HIT_BOTTOM_OF_B)
{
switch (currentMoveDirection)
{
case 1: return 5;
case 2: return 4;
case 8: return 6;
}
}
if (hitTestResults.next.A_BOTTOM_HIT_TOP_OF_B || hitTestResults.next.A_BOTTOM_HIT_BOTTOM_OF_B)
{
switch (currentMoveDirection)
{
case 5: return 1;
case 4: return 2;
case 6: return 8;
}
}
return 1;
}
public function hitTest(a:Object, b:Object):Object
{
/*
* Template:
* a.x
* a.y
* a.width
* a.height
*
* Optional:
* a.xSpeed
* a.ySpeed
* */
//An object with no width or height cannot properly be hitTested.
//So end the function if any of them are equal to zero.
if (a.width == 0 || a.height == 0 || b.width == 0 || b.height == 0)
{
throw new Error("Objects cannot have zero width or height");
return null;
}
a.xMax = a.x + a.width; //The coordinate for the top-right corner of the object.
a.yMax = a.y + a.height; //The coordinate for the bottom-left corner of the object.
a.xSpeed = (a.xSpeed > 0) ? a.xSpeed : 0; //If a.xSpeed is not set, then set it to zero. Otherwise do not change its value.
a.ySpeed = (a.ySpeed > 0) ? a.ySpeed : 0;
a.xNext = a.x + a.xSpeed; //What x will be equal to in the next iteration for this object.
a.yNext = a.y + a.ySpeed;
a.xMaxNext = a.xMax + a.xSpeed;
a.yMaxNext = a.yMax + a.ySpeed;
b.xMax = b.x + b.width;
b.yMax = b.y + b.height;
b.xSpeed = (b.xSpeed > 0) ? b.xSpeed : 0;
b.ySpeed = (b.ySpeed > 0) ? b.ySpeed : 0;
b.xNext = b.x + b.xSpeed;
b.yNext = b.y + b.ySpeed;
b.xMaxNext = b.xMax + b.xSpeed;
b.yMaxNext = b.yMax + b.ySpeed;
var results:Object = new Object();
results.now = new Object();
results.next = new Object();
//State info for the current iteration.
results.now.A_LEFT_OF_B = false;
results.now.A_RIGHT_OF_B = false;
results.now.A_ABOVE_B = false;
results.now.A_BELOW_B = false;
results.now.A_TOUCHING_B = false;
results.now.A_INSIDE_B = false;
results.now.A_RIGHT_HIT_RIGHT_OF_B = false;
results.now.A_RIGHT_HIT_LEFT_OF_B = false;
results.now.A_LEFT_HIT_RIGHT_OF_B = false;
results.now.A_LEFT_HIT_LEFT_OF_B = false;
results.now.A_TOP_HIT_TOP_OF_B = false;
results.now.A_TOP_HIT_BOTTOM_OF_B = false;
results.now.A_BOTTOM_HIT_TOP_OF_B = false;
results.now.A_BOTTOM_HIT_BOTTOM_OF_B = false;
results.now.A_TRCORNER_HIT_TRCORNER_OF_B = false;
results.now.A_TRCORNER_HIT_BLCORNER_OF_B = false;
results.now.A_BLCORNER_HIT_TRCORNER_OF_B = false;
results.now.A_BLCORNER_HIT_BLCORNER_OF_B = false;
results.now.A_TLCORNER_HIT_TLCORNER_OF_B = false;
results.now.A_TLCORNER_HIT_BRCORNER_OF_B = false;
results.now.A_BRCORNER_HIT_TLCORNER_OF_B = false;
results.now.A_BRCORNER_HIT_BRCORNER_OF_B = false;
//State info for the very next iteration.
results.next.A_LEFT_OF_B = false;
results.next.A_RIGHT_OF_B = false;
results.next.A_ABOVE_B = false;
results.next.A_BELOW_B = false;
results.next.A_TOUCHING_B = false;
results.next.A_INSIDE_B = false;
results.next.A_RIGHT_HIT_RIGHT_OF_B = false;
results.next.A_RIGHT_HIT_LEFT_OF_B = false;
results.next.A_LEFT_HIT_RIGHT_OF_B = false;
results.next.A_LEFT_HIT_LEFT_OF_B = false;
results.next.A_TOP_HIT_TOP_OF_B = false;
results.next.A_TOP_HIT_BOTTOM_OF_B = false;
results.next.A_BOTTOM_HIT_TOP_OF_B = false;
results.next.A_BOTTOM_HIT_BOTTOM_OF_B = false;
results.next.A_TRCORNER_HIT_TRCORNER_OF_B = false;
results.next.A_TRCORNER_HIT_BLCORNER_OF_B = false;
results.next.A_BLCORNER_HIT_TRCORNER_OF_B = false;
results.next.A_BLCORNER_HIT_BLCORNER_OF_B = false;
results.next.A_TLCORNER_HIT_TLCORNER_OF_B = false;
results.next.A_TLCORNER_HIT_BRCORNER_OF_B = false;
results.next.A_BRCORNER_HIT_TLCORNER_OF_B = false;
results.next.A_BRCORNER_HIT_BRCORNER_OF_B = false;
/////////////
// N O W //
////////////
//Is objA to the left of objB?
if ( a.xMax < b.x )
results.now.A_LEFTOF_B = true;
//Is objA to the right of objB?
if (a.x > b.xMax)
results.now.A_RIGHTOF_B = true;
//Is objA above objB?
if ( a.yMax < b.y)
results.now.A_ABOVE_B = true;
//Is objA below objB?
if ( a.y > b.yMax )
results.now.A_BELOW_B = true;
//Is any part of objA "inside" of objB? (i.e. are they touching)
if (results.now.A_LEFT_OF_B == false && results.now.A_RIGHT_OF_B == false && results.now.A_ABOVE_B == false && results.now.A_BELOW_B == false)
results.now.A_TOUCHING_B = true;
//Did objA just touch the right side of objB, or go past it?
if ( ( a.x <= b.xMax && a.xMax > b.xMax ) && results.now.A_ABOVE_B == false && results.now.A_BELOW_B == false && results.now.A_LEFT_OF_B == false)
results.now.A_LEFT_HIT_RIGHT_OF_B = true;
if ( ( a.x < b.xMax && a.xMax >= b.xMax ) && results.now.A_ABOVE_B == false && results.now.A_BELOW_B == false && results.now.A_LEFT_OF_B == false)
results.now.A_RIGHT_HIT_RIGHT_OF_B = true;
//Did objA just touch the left side of objB, or go past it?
if ( ( a.xMax >= b.x && a.x < b.x ) && results.now.A_ABOVE_B == false && results.now.A_BELOW_B == false && results.now.A_LEFT_OF_B == false)
results.now.A_RIGHT_HIT_LEFT_OF_B = true;
if ( ( a.xMax > b.x && a.x <= b.x ) && results.now.A_ABOVE_B == false && results.now.A_BELOW_B == false && results.now.A_LEFT_OF_B == false)
results.now.A_LEFT_HIT_LEFT_OF_B = true;
//Did objA just touch the top of objB, or go past it?
if ( ( a.yMax >= b.y && a.y < b.y) && results.now.A_LEFT_OF_B == false && results.now.A_RIGHT_OF_B == false && results.now.A_BELOW_B == false )
results.now.A_BOTTOM_HIT_TOP_OF_B = true;
if ( ( a.yMax > b.y && a.y <= b.y) && results.now.A_LEFT_OF_B == false && results.now.A_RIGHT_OF_B == false && results.now.A_BELOW_B == false )
results.now.A_TOP_HIT_TOP_OF_B = true;
//Did objA just touch the top of objB, or go past it?
if ( ( a.y <= b.yMax && a.yMax > b.yMax ) && results.now.A_LEFT_OF_B == false && results.now.A_RIGHT_OF_B == false && results.now.A_BELOW_B == false )
results.now.A_TOP_HIT_BOTTOM_OF_B = true;
if ( ( a.y < b.yMax && a.yMax >= b.yMax ) && results.now.A_LEFT_OF_B == false && results.now.A_RIGHT_OF_B == false && results.now.A_BELOW_B == false )
results.now.A_BOTTOM_HIT_BOTTOM_OF_B = true;
//Is objA inside of objB?
if ( results.now.A_TOUCHING_B &&
results.now.A_LEFT_HIT_RIGHT_OF_B == false &&
results.now.A_RIGHT_HIT_RIGHT_OF_B == false &&
results.now.A_RIGHT_HIT_LEFT_OF_B == false &&
results.now.A_LEFT_HIT_LEFT_OF_B == false &&
results.now.A_BOTTOM_HIT_TOP_OF_B == false &&
results.now.A_TOP_HIT_TOP_OF_B == false &&
results.now.A_TOP_HIT_BOTTOM_OF_B == false &&
results.now.A_BOTTOM_HIT_BOTTOM_OF_B == false)
results.now.A_INSIDE_B = true;
///////////////
// N E X T //
//////////////
//Will objA be to the right of objB?
if (a.xNext > b.xMaxNext)
results.next.A_RIGHT_OF_B = true;
//Will objA be to the left of objB?
if (a.xMaxNext < b.xNext)
results.next.A_LEFT_OF_B = true;
//Will objA be above objB?
if (a.yMaxNext < b.yNext)
results.next.A_ABOVE_B = true;
//Will objA be below objB?
if (a.yNext > b.yMaxNext)
results.next.A_BELOW_B = true;
//Will any part of objA be "inside" of objB? (i.e. will they be touching)
if (results.next.A_LEFT_OF_B == false && results.next.A_RIGHT_OF_B == false && results.next.A_ABOVE_B == false && results.next.A_BELOW_B == false)
results.next.A_TOUCHING_B = true;
//Did objA just touch the right side of objB, or go past it?
if ( ( a.xNext <= b.xMaxNext && a.xMaxNext > b.xMaxNext ) && results.next.A_ABOVE_B == false && results.next.A_BELOW_B == false && results.next.A_LEFT_OF_B == false)
results.next.A_LEFT_HIT_RIGHT_OF_B = true;
if ( ( a.x < b.xMaxNext && a.xMaxNext >= b.xMaxNext ) && results.next.A_ABOVE_B == false && results.next.A_BELOW_B == false && results.next.A_LEFT_OF_B == false)
results.next.A_RIGHT_HIT_RIGHT_OF_B = true;
//Did objA just touch the left side of objB, or go past it?
if ( ( a.xMaxNext >= b.xNext && a.xNext < b.xNext ) && results.next.A_ABOVE_B == false && results.next.A_BELOW_B == false && results.next.A_LEFT_OF_B == false)
results.next.A_RIGHT_HIT_LEFT_OF_B = true;
if ( ( a.xMaxNext > b.xNext && a.xNext <= b.xNext ) && results.next.A_ABOVE_B == false && results.next.A_BELOW_B == false && results.next.A_LEFT_OF_B == false)
results.next.A_LEFT_HIT_LEFT_OF_B = true;
//Did objA just touch the top of objB, or go past it?
if ( ( a.yMaxNext >= b.yNext && a.yNext < b.yNext ) && results.next.A_LEFT_OF_B == false && results.next.A_RIGHT_OF_B == false && results.next.A_BELOW_B == false )
results.next.A_BOTTOM_HIT_TOP_OF_B = true;
if ( ( a.yMaxNext > b.yNext && a.yNext <= b.yNext ) && results.next.A_LEFT_OF_B == false && results.next.A_RIGHT_OF_B == false && results.next.A_BELOW_B == false )
results.next.A_TOP_HIT_TOP_OF_B = true;
//Did objA just touch the top of objB, or go past it?
if ( ( a.yNext <= b.yMaxNext && a.yMaxNext > b.yMaxNext ) && results.next.A_LEFT_OF_B == false && results.next.A_RIGHT_OF_B == false && results.next.A_BELOW_B == false )
results.next.A_TOP_HIT_BOTTOM_OF_B = true;
if ( ( a.yNext < b.yMaxNext && a.yMaxNext >= b.yMaxNext ) && results.next.A_LEFT_OF_B == false && results.next.A_RIGHT_OF_B == false && results.next.A_BELOW_B == false )
results.next.A_BOTTOM_HIT_BOTTOM_OF_B = true;
//Will objA be inside of objB?
if ( results.next.A_TOUCHING_B &&
results.next.A_LEFT_HIT_RIGHT_OF_B == false &&
results.next.A_RIGHT_HIT_RIGHT_OF_B == false &&
results.next.A_RIGHT_HIT_LEFT_OF_B == false &&
results.next.A_LEFT_HIT_LEFT_OF_B == false &&
results.next.A_BOTTOM_HIT_TOP_OF_B == false &&
results.next.A_TOP_HIT_TOP_OF_B == false &&
results.next.A_TOP_HIT_BOTTOM_OF_B == false &&
results.next.A_BOTTOM_HIT_BOTTOM_OF_B == false)
results.next.A_INSIDE_B = true;
return results;
}
}
}