我对碰撞的重力部分是一个严重的问题,它是基于平台的,但适用 对于我所做的一切都是关于包含重力的碰撞。
当实体击中地面时,它将不断地重新设置为不会撞击地面,不断地“真假虚假......”并且当它正在这样做时,实体的Y速度也在0.0和之间切换-0.3
如果实体在地面上,我需要它始终是真的,而不是看似反弹。
此外,如果用户手动控制实体的Y-Velocity,如果它与边界框的角碰撞,同时在角落方向具有X-Velocity,并且Y-Velocity直接朝向它(在X和Y之间反之亦然,它会卡住,吓坏了,然后决定在整个边界框中堵塞自己。
namespace StackOverFlowExample
{
class Entity
{
/* ... */
public Collision2D Col; // The collision box for the Entity
public bool isGrounded; // Returns True if the Entity is on the ground
private List<Collision2D> TestObjt; // Allows the Entity access to all of the other Collision2D instances
public Vector2 Pos; // Entity's position
public Vector2 V; // Entity's velocity
// Declare the movement & collision Timer
private Timer movementTimer = new Timer( 1 );
private void UpdateCollision()
{
// Reset grounding
this.Col.Direction = 0;
this.isGrounded = false;
// this.isAllowingInput = false;
foreach ( Collision2D testObjt in this.TestObjt )
{
if ( this.Col.CheckCol( testObjt ) )
testObjt.CheckCol( this.Col, this );
}
}
private void UpdatePosition()
{
this.Pos = Vector2.Add( this.Pos, this.V );
this.Col.Sync( Convert.ToInt32( this.Pos.X ), Convert.ToInt32( this.Pos.Y ) );
}
private void UpdateGravity()
{
if ( this.isGrounded == false )
{
this.V.Y = this.V.Y + 0.3F;
} else this.V.Y = 0;
}
private void movementEvent( object source, ElapsedEventArgs e )
{
// Call Methods
this.UpdatePosition();
this.UpdateCollision();
this.UpdateGravity();
}
}
class Collision2D
{
public Vector2 Pos1; // Top, Left
public Vector2 Pos2; // Bottom, Right
public int Direction; // Direction of collision
public void Sync( int NewX, int NewY )
{
float W = Pos2.X - Pos1.X; // Generate Width
float H = Pos2.Y - Pos1.Y; // Generate Height
this.Pos1.X = NewX;
this.Pos1.Y = NewY;
this.Pos2.X = NewX + W;
this.Pos2.Y = NewY + H;
}
// Returns true if there is a collision
public bool CheckCol( Collision2D objt )
{
bool r = true;
if ( this.Pos2.Y < objt.Pos1.Y || this.Pos1.Y > objt.Pos2.Y || this.Pos2.X < objt.Pos1.X || this.Pos1.X > objt.Pos2.X )
r = false;
return r;
}
// Collision actions on Entity
public void CheckCol( Collision2D objt, Entity ent )
{
switch ( ent.Col.GetDirection( this ) )
{
// Ceiling Collision Actions
case 1:
ent.Pos.Y = ent.Pos.Y - ent.V.Y;
break;
// Floor Collision Actions
case 2:
ent.Pos.Y = ent.Pos.Y - ent.V.Y;
ent.isGrounded = true; // Place Entity on the ground for Gravity actions
break;
// Right Wall Collision Actions
case 3:
ent.Pos.X = ent.Pos.X - ent.V.X;
break;
// Left Wall Collision Actions
case 4:
ent.Pos.X = ent.Pos.X - ent.V.X;
break;
}
// Resync the collision bounding box for the entity
ent.Col.Sync( Convert.ToInt32( ent.Pos.X ), Convert.ToInt32( ent.Pos.Y ) );
}
public int GetDirection( Collision2D objt )
{
int r;
r = 0;
if ( objt.Pos2.Y - this.Pos1.Y < this.Pos2.Y - objt.Pos1.Y &&
objt.Pos2.Y - this.Pos1.Y < this.Pos2.X - objt.Pos1.X &&
objt.Pos2.Y - this.Pos1.Y < objt.Pos2.X - this.Pos1.X )
r = 1; // Up
if ( this.Pos2.Y - objt.Pos1.Y < objt.Pos2.Y - this.Pos1.Y &&
this.Pos2.Y - objt.Pos1.Y < this.Pos2.X - objt.Pos1.X &&
this.Pos2.Y - objt.Pos1.Y < objt.Pos2.X - this.Pos1.X )
r = 2; // Down
if ( objt.Pos2.X - this.Pos1.X < this.Pos2.X - objt.Pos1.X &&
objt.Pos2.X - this.Pos1.X < this.Pos2.Y - objt.Pos1.Y &&
objt.Pos2.X - this.Pos1.X < objt.Pos2.Y - this.Pos1.Y )
r = 3; // Right
if ( this.Pos2.X - objt.Pos1.X < objt.Pos2.X - this.Pos1.X &&
this.Pos2.X - objt.Pos1.X < this.Pos2.Y - objt.Pos1.Y &&
this.Pos2.X - objt.Pos1.X < objt.Pos2.Y - this.Pos1.Y )
r = 4; // Left
return r;
}
}
}