Programming 2D Games 读书笔记(第六章)

时间:2023-02-06 23:34:07

 

http://www.programming2dgames.com/chapter6.htm

示例一:Bounce

边界碰撞测试

velocity为移动的速度,

  1. 超过右边界,velocity.x为负,spriteData.x位置减去宽度
  2. 超过左边界,velocity.x为正

上下边界同理

//=============================================================================
// update
// typically called once per frame
// frameTime is used to regulate the speed of movement and animation
//=============================================================================
void Ship::update(float frameTime)
{
    Entity::update(frameTime);
    spriteData.angle += frameTime * shipNS::ROTATION_RATE;  // rotate the ship
    spriteData.x += frameTime * velocity.x;     // move ship along X 
    spriteData.y += frameTime * velocity.y;     // move ship along Y

    float fScale=getScale();
    // Bounce off walls
    // if hit right screen edge
    if (spriteData.x > GAME_WIDTH-shipNS::WIDTH*fScale)
    {
        // position at right screen edge
        spriteData.x = GAME_WIDTH-shipNS::WIDTH*fScale;
        velocity.x = -velocity.x;               // reverse X direction
    } 
    else if (spriteData.x < 0)                  // else if hit left screen edge
    {
        spriteData.x = 0;                       // position at left screen edge
        velocity.x = -velocity.x;               // reverse X direction
    }
    // if hit bottom screen edge
    if (spriteData.y > GAME_HEIGHT-shipNS::HEIGHT*fScale)
    {
        // position at bottom screen edge
        spriteData.y = GAME_HEIGHT-shipNS::HEIGHT*fScale;
        velocity.y = -velocity.y;               // reverse Y direction
    }
    else if (spriteData.y < 0)                  // else if hit top screen edge
    {
        spriteData.y = 0;                       // position at top screen edge
        velocity.y = -velocity.y;               // reverse Y direction
    }
}

示例二:Planet Collision

参考:http://wenku.baidu.com/view/45544cfcfab069dc50220145.html

1.包围球碰撞

//=============================================================================
// Circular collision detection method
// Called by collision(), default collision detection method
// Post: returns true if collision, false otherwise
//       sets collisionVector if collision
//=============================================================================
bool Entity::collideCircle(Entity &ent, VECTOR2 &collisionVector)
{
    // difference between centers
    distSquared = *getCenter() - *ent.getCenter();
    distSquared.x = distSquared.x * distSquared.x;      // difference squared
    distSquared.y = distSquared.y * distSquared.y;

    // Calculate the sum of the radii (adjusted for scale)
    sumRadiiSquared = (radius*getScale()) + (ent.radius*ent.getScale());
    sumRadiiSquared *= sumRadiiSquared;                 // square it

    // if entities are colliding
    if(distSquared.x + distSquared.y <= sumRadiiSquared)
    {
        // set collision vector
        collisionVector = *ent.getCenter() - *getCenter();
        return true;
    }
    return false;   // not colliding
}

2.AABB碰撞检测

//=============================================================================
// Axis aligned bounding box collision detection method
// Called by collision()
// Post: returns true if collision, false otherwise
//       sets collisionVector if collision
//=============================================================================
bool Entity::collideBox(Entity &ent, VECTOR2 &collisionVector)
{
    // if either entity is not active then no collision may occcur
    if (!active || !ent.getActive())
        return false;

    // Check for collision using Axis Aligned Bounding Box.
    if( (getCenterX() + edge.right*getScale() >= ent.getCenterX() + ent.getEdge().left*ent.getScale()) && 
        (getCenterX() + edge.left*getScale() <= ent.getCenterX() + ent.getEdge().right*ent.getScale()) &&
        (getCenterY() + edge.bottom*getScale() >= ent.getCenterY() + ent.getEdge().top*ent.getScale()) && 
        (getCenterY() + edge.top*getScale() <= ent.getCenterY() + ent.getEdge().bottom*ent.getScale()) )
    {
        // set collision vector
        collisionVector = *ent.getCenter() - *getCenter();
        return true;
    }

    return false;
}