This commit is contained in:
parent
b073f60cc2
commit
808f595076
3 changed files with 35 additions and 217 deletions
|
@ -508,20 +508,20 @@ void CPlayer::setMapSize(DVECTOR _mapSize)
|
||||||
int CPlayer::getHeightFromGround(int _x,int _y,int _maxHeight)
|
int CPlayer::getHeightFromGround(int _x,int _y,int _maxHeight)
|
||||||
{
|
{
|
||||||
int height;
|
int height;
|
||||||
|
DVECTOR platformPos;
|
||||||
|
DVECTOR newPos;
|
||||||
if(isOnPlatform())
|
if(isOnPlatform())
|
||||||
{
|
{
|
||||||
DVECTOR platformPos;
|
CThing *platform = isOnPlatform();
|
||||||
platformPos=m_platform->getPosDelta();
|
height = platform->getNewYPos( this ) - Pos.vy;
|
||||||
DVECTOR newPos = getNewCollidedPos();
|
|
||||||
|
|
||||||
// since collision was detected in the LAST frame, we must check to see where the platform has moved to in THIS frame
|
int groundHeight = m_layerCollision->getHeightFromGround(_x,_y,_maxHeight);
|
||||||
|
|
||||||
height = newPos.vy + platformPos.vy - Pos.vy;
|
if ( groundHeight < height )
|
||||||
|
{
|
||||||
// if(height<-_maxHeight)
|
height = groundHeight;
|
||||||
// {
|
clearPlatform();
|
||||||
// height=-_maxHeight;
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -350,6 +350,9 @@ void CThing::think(int _frames)
|
||||||
PosDelta.vx=Pos.vx-PosLast.vx;
|
PosDelta.vx=Pos.vx-PosLast.vx;
|
||||||
PosDelta.vy=Pos.vy-PosLast.vy;
|
PosDelta.vy=Pos.vy-PosLast.vy;
|
||||||
PosLast=Pos;
|
PosLast=Pos;
|
||||||
|
|
||||||
|
//m_collisionAngle += 1;
|
||||||
|
//m_collisionAngle &= 4095;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
|
@ -596,107 +599,16 @@ void CThing::updateCollisionArea()
|
||||||
s32 CThing::getNewYPos(CThing *_thisThing)
|
s32 CThing::getNewYPos(CThing *_thisThing)
|
||||||
{
|
{
|
||||||
CRECT thisRect;
|
CRECT thisRect;
|
||||||
DVECTOR thatPos = _thisThing->getPos();
|
|
||||||
|
|
||||||
thisRect = getCollisionArea();
|
thisRect = getCollisionArea();
|
||||||
|
|
||||||
// 'render' collision box at correct angle
|
if ( thisRect.y1 < thisRect.y2 )
|
||||||
|
|
||||||
SVECTOR testPointsNonRel[4];
|
|
||||||
VECTOR testPoints[4];
|
|
||||||
|
|
||||||
testPointsNonRel[0].vx = thisRect.x1 - Pos.vx;
|
|
||||||
testPointsNonRel[0].vy = thisRect.y1 - Pos.vy;
|
|
||||||
|
|
||||||
testPointsNonRel[1].vx = thisRect.x2 - Pos.vx;
|
|
||||||
testPointsNonRel[1].vy = thisRect.y1 - Pos.vy;
|
|
||||||
|
|
||||||
testPointsNonRel[2].vx = thisRect.x2 - Pos.vx;
|
|
||||||
testPointsNonRel[2].vy = thisRect.y2 - Pos.vy;
|
|
||||||
|
|
||||||
testPointsNonRel[3].vx = thisRect.x1 - Pos.vx;
|
|
||||||
testPointsNonRel[3].vy = thisRect.y2 - Pos.vy;
|
|
||||||
|
|
||||||
MATRIX mtx;
|
|
||||||
SetIdentNoTrans(&mtx );
|
|
||||||
RotMatrixZ( m_collisionAngle, &mtx );
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for ( i = 0 ; i < 4 ; i++ )
|
|
||||||
{
|
{
|
||||||
ApplyMatrix( &mtx, &testPointsNonRel[i], &testPoints[i] );
|
return( thisRect.y1 );
|
||||||
|
|
||||||
testPoints[i].vx += Pos.vx;
|
|
||||||
testPoints[i].vy += Pos.vy;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now find the highest y pos
|
|
||||||
|
|
||||||
// first set highestY to lowest of the four points
|
|
||||||
|
|
||||||
s16 highestY = testPoints[0].vy;
|
|
||||||
|
|
||||||
for ( i = 1 ; i < 4 ; i++ )
|
|
||||||
{
|
|
||||||
if ( testPoints[i].vy > highestY ) // remember y is inverted
|
|
||||||
{
|
|
||||||
highestY = testPoints[i].vy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = 0 ; i < 4 ; i++ )
|
|
||||||
{
|
|
||||||
int j = i + 1;
|
|
||||||
j %= 4;
|
|
||||||
|
|
||||||
VECTOR highestX, lowestX;
|
|
||||||
|
|
||||||
if ( testPoints[i].vx < testPoints[j].vx )
|
|
||||||
{
|
|
||||||
lowestX = testPoints[i];
|
|
||||||
highestX = testPoints[j];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lowestX = testPoints[j];
|
return( thisRect.y2 );
|
||||||
highestX = testPoints[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( highestX.vx == lowestX.vx )
|
|
||||||
{
|
|
||||||
// have to compare heights of both points to get highest
|
|
||||||
|
|
||||||
if ( lowestX.vy < highestY )
|
|
||||||
{
|
|
||||||
highestY = lowestX.vy;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( highestX.vy < highestY )
|
|
||||||
{
|
|
||||||
highestY = highestX.vy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( thatPos.vx >= lowestX.vx && thatPos.vx <= highestX.vx )
|
|
||||||
{
|
|
||||||
// current position is above or below this line
|
|
||||||
|
|
||||||
s16 testY;
|
|
||||||
|
|
||||||
testY = lowestX.vy + ( ( thatPos.vx - lowestX.vx ) * ( highestX.vy - lowestX.vy ) ) /
|
|
||||||
( highestX.vx - lowestX.vx );
|
|
||||||
|
|
||||||
if ( testY < highestY )
|
|
||||||
{
|
|
||||||
highestY = testY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return( highestY );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
|
@ -711,8 +623,6 @@ int CThing::checkCollisionAgainst(CThing *_thisThing, int _frames)
|
||||||
int radius;
|
int radius;
|
||||||
int collided;
|
int collided;
|
||||||
|
|
||||||
MATRIX mtx;
|
|
||||||
|
|
||||||
pos=getCollisionCentre();
|
pos=getCollisionCentre();
|
||||||
thisThingPos=_thisThing->getCollisionCentre();
|
thisThingPos=_thisThing->getCollisionCentre();
|
||||||
|
|
||||||
|
@ -725,106 +635,12 @@ int CThing::checkCollisionAgainst(CThing *_thisThing, int _frames)
|
||||||
|
|
||||||
thisRect=getCollisionArea();
|
thisRect=getCollisionArea();
|
||||||
|
|
||||||
// ensure user 'sticks' to platform whilst it is moving along
|
|
||||||
|
|
||||||
thatRect=_thisThing->getCollisionArea();
|
thatRect=_thisThing->getCollisionArea();
|
||||||
|
|
||||||
// rotate thatPos opposite way to this CThing's collision angle, so that we can regard them both as being at 0 rotation
|
|
||||||
|
|
||||||
// get target thing's position
|
|
||||||
|
|
||||||
DVECTOR thatPos = _thisThing->getPos();
|
|
||||||
|
|
||||||
// get target thing's position relative to this thing's position
|
|
||||||
|
|
||||||
SVECTOR relativePos;
|
|
||||||
relativePos.vx = thatPos.vx - Pos.vx;
|
|
||||||
relativePos.vy = thatPos.vy - Pos.vy;
|
|
||||||
|
|
||||||
VECTOR newPos;
|
|
||||||
|
|
||||||
// get target thing's collision area relative to 0
|
|
||||||
|
|
||||||
thatRect.x1 -= thatPos.vx;
|
|
||||||
thatRect.y1 -= thatPos.vy;
|
|
||||||
thatRect.x2 -= thatPos.vx;
|
|
||||||
thatRect.y2 -= thatPos.vy;
|
|
||||||
|
|
||||||
SetIdentNoTrans(&mtx );
|
|
||||||
RotMatrixZ( -m_collisionAngle, &mtx );
|
|
||||||
|
|
||||||
// rotation target relative position back to 0 by this thing's collision angle
|
|
||||||
|
|
||||||
ApplyMatrix( &mtx, &relativePos, &newPos );
|
|
||||||
|
|
||||||
// add on this thing's position to get new target thing's position after rotation around this thing
|
|
||||||
|
|
||||||
newPos.vx += Pos.vx;
|
|
||||||
newPos.vy += Pos.vy;
|
|
||||||
|
|
||||||
// reposition target thing's collision area
|
|
||||||
|
|
||||||
thatRect.x1 += newPos.vx;
|
|
||||||
thatRect.y1 += newPos.vy;
|
|
||||||
thatRect.x2 += newPos.vx;
|
|
||||||
thatRect.y2 += newPos.vy;
|
|
||||||
|
|
||||||
// check to see if bounding boxes collide
|
|
||||||
|
|
||||||
if(((thisRect.x1>=thatRect.x1&&thisRect.x1<=thatRect.x2)||(thisRect.x2>=thatRect.x1&&thisRect.x2<=thatRect.x2)||(thisRect.x1<=thatRect.x1&&thisRect.x2>=thatRect.x2))&&
|
if(((thisRect.x1>=thatRect.x1&&thisRect.x1<=thatRect.x2)||(thisRect.x2>=thatRect.x1&&thisRect.x2<=thatRect.x2)||(thisRect.x1<=thatRect.x1&&thisRect.x2>=thatRect.x2))&&
|
||||||
((thisRect.y1>=thatRect.y1&&thisRect.y1<=thatRect.y2)||(thisRect.y2>=thatRect.y1&&thisRect.y2<=thatRect.y2)||(thisRect.y1<=thatRect.y1&&thisRect.y2>=thatRect.y2)))
|
((thisRect.y1>=thatRect.y1&&thisRect.y1<=thatRect.y2)||(thisRect.y2>=thatRect.y1&&thisRect.y2<=thatRect.y2)||(thisRect.y1<=thatRect.y1&&thisRect.y2>=thatRect.y2)))
|
||||||
{
|
{
|
||||||
collided=true;
|
collided=true;
|
||||||
|
|
||||||
// check to see if centre point (i.e. where the object is standing) collides too
|
|
||||||
|
|
||||||
if ( ( newPos.vx >= thisRect.x1 && newPos.vx <= thisRect.x2 ) &&
|
|
||||||
( newPos.vy >= thisRect.y1 && newPos.vy <= thisRect.y2 ) )
|
|
||||||
{
|
|
||||||
thatPos.vy = getNewYPos( _thisThing );
|
|
||||||
|
|
||||||
// vertical height change is the sum of the maximums of BOTH objects
|
|
||||||
// potentially, one object could be falling down through another object that is moving up
|
|
||||||
|
|
||||||
s32 verticalDelta = abs( _thisThing->getPosDelta().vy ) + abs( this->getPosDelta().vy );
|
|
||||||
|
|
||||||
if ( thatPos.vy - _thisThing->getPos().vy >= -verticalDelta )
|
|
||||||
{
|
|
||||||
if ( _thisThing->getHasPlatformCollided() )
|
|
||||||
{
|
|
||||||
// if this has already collided with a platform, check the current platform is
|
|
||||||
// (a) within 10 units,
|
|
||||||
// (b) higher
|
|
||||||
|
|
||||||
DVECTOR oldCollidedPos = _thisThing->getNewCollidedPos();
|
|
||||||
|
|
||||||
s32 oldY = abs( oldCollidedPos.vy - ( _thisThing->getPos().vy - verticalDelta ) );
|
|
||||||
s32 currentY = abs( thatPos.vy - ( _thisThing->getPos().vy - verticalDelta ) );
|
|
||||||
|
|
||||||
//if ( thatPos.vy < oldCollidedPos.vy )
|
|
||||||
if ( currentY < oldY )
|
|
||||||
{
|
|
||||||
_thisThing->setNewCollidedPos( thatPos );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_thisThing->setHasPlatformCollided( true );
|
|
||||||
|
|
||||||
_thisThing->setCentreCollision( true );
|
|
||||||
|
|
||||||
_thisThing->setNewCollidedPos( thatPos );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_thisThing->setCentreCollision( false );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_thisThing->setCentreCollision( false );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,33 +126,35 @@ public:
|
||||||
|
|
||||||
// -- Collision --
|
// -- Collision --
|
||||||
public:
|
public:
|
||||||
virtual int canCollide() {return true;}
|
|
||||||
virtual int checkCollisionAgainst(CThing *_thisThing, int _frames);
|
|
||||||
void updateCollisionArea();
|
|
||||||
virtual void collidedWith(CThing *_thisThing) {;}
|
|
||||||
virtual void setHasPlatformCollided( bool newVal ) {;}
|
|
||||||
virtual bool getHasPlatformCollided() {return false;}
|
|
||||||
s32 getNewYPos( CThing *_thisThing );
|
|
||||||
void setNewCollidedPos(DVECTOR newPos) {m_newCollidedPos = newPos;}
|
|
||||||
protected:
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int x1,y1,x2,y2;
|
int x1,y1,x2,y2;
|
||||||
}
|
}
|
||||||
CRECT;
|
CRECT;
|
||||||
|
|
||||||
void setCollisionSize(int _w,int _h);
|
|
||||||
void setCollisionCentreOffset(int _x,int _y) {m_collisionCentreOffset.vx=_x;m_collisionCentreOffset.vy=_y;}
|
DVECTOR getCollisionCentre() {return m_collisionCentre;}
|
||||||
void setCollisionCentreOffset(DVECTOR xy) {m_collisionCentreOffset=xy;}
|
|
||||||
void setCentreCollision(bool newCentreCollision) {m_centreCollision = newCentreCollision;}
|
|
||||||
void setCollisionAngle(int newAngle) {m_collisionAngle = newAngle;}
|
|
||||||
int getCollisionRadius() {return m_collisionRadius;}
|
int getCollisionRadius() {return m_collisionRadius;}
|
||||||
CRECT getCollisionArea() {return m_collisionArea;}
|
CRECT getCollisionArea() {return m_collisionArea;}
|
||||||
DVECTOR getCollisionSize() {return m_collisionSize;}
|
|
||||||
DVECTOR getCollisionCentre() {return m_collisionCentre;}
|
|
||||||
s16 getCollisionAngle() {return m_collisionAngle;}
|
s16 getCollisionAngle() {return m_collisionAngle;}
|
||||||
bool getCentreCollision() {return m_centreCollision;}
|
bool getCentreCollision() {return m_centreCollision;}
|
||||||
DVECTOR getNewCollidedPos() {return m_newCollidedPos;}
|
DVECTOR getNewCollidedPos() {return m_newCollidedPos;}
|
||||||
|
DVECTOR getCollisionSize() {return m_collisionSize;}
|
||||||
|
|
||||||
|
virtual int canCollide() {return true;}
|
||||||
|
virtual int checkCollisionAgainst(CThing *_thisThing, int _frames);
|
||||||
|
void updateCollisionArea();
|
||||||
|
virtual void collidedWith(CThing *_thisThing) {;}
|
||||||
|
virtual void setHasPlatformCollided( bool newVal ) {;}
|
||||||
|
virtual bool getHasPlatformCollided() {return false;}
|
||||||
|
virtual s32 getNewYPos( CThing *_thisThing );
|
||||||
|
void setNewCollidedPos(DVECTOR newPos) {m_newCollidedPos = newPos;}
|
||||||
|
void setCentreCollision(bool newCentreCollision) {m_centreCollision = newCentreCollision;}
|
||||||
|
protected:
|
||||||
|
void setCollisionSize(int _w,int _h);
|
||||||
|
void setCollisionCentreOffset(int _x,int _y) {m_collisionCentreOffset.vx=_x;m_collisionCentreOffset.vy=_y;}
|
||||||
|
void setCollisionCentreOffset(DVECTOR xy) {m_collisionCentreOffset=xy;}
|
||||||
|
void setCollisionAngle(int newAngle) {m_collisionAngle = newAngle;}
|
||||||
private:
|
private:
|
||||||
DVECTOR m_collisionSize;
|
DVECTOR m_collisionSize;
|
||||||
DVECTOR m_collisionCentreOffset;
|
DVECTOR m_collisionCentreOffset;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue