http://www.programming2dgames.com/chapter6.htm
示例一:Bounce
边界碰撞测试
velocity为移动的速度,
- 超过右边界,velocity.x为负,spriteData.x位置减去宽度
- 超过左边界,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; }