void Physics::detectCollisions (const std::vector<PhysicsObject*>& objects) { // Lets go through each collidable object checking if they collide. for (auto i = 0U; i < objects.size(); ++i) { // Cache the values for the first object. auto first = objects[i]; const auto& check = first->getCollider(); const auto checkLayer = m_layers[check.getLayer()]; auto checkBox = check.getBox(); checkBox.translate (first->getPosition().x, first->getPosition().y); for (auto j = i + 1; j < objects.size(); ++j) { // Cache the values for the second object. auto second = objects[j]; const auto& against = second->getCollider(); // Check if their layers collide. if ((checkLayer | (1 << against.getLayer())) > 0) { // We must now check if the rectangles intersect. auto againstBox = against.getBox(); againstBox.translate (second->getPosition().x, second->getPosition().y); // Check if they intersect. if (checkBox.intersects (againstBox)) { // Determine the desired collision type. if (check.isTrigger()) { first->onTrigger (second); if (against.isTrigger()) { second->onTrigger (first); } } // Collider on trigger. else if (against.isTrigger()) { second->onTrigger (first); } // Collider on collider. else { first->onCollision (second); second->onCollision (first); } } } } } }
void HelpScene::onUpdate() { handleInput(); update(); onCollision(); }
bool Ball::collisionHandler() { //IF they're a wall if (World::getInstance()->getGamePlayer(0)->getHealth() <= 0 && this->getY() + this->getRadius() > World::getInstance()->getWorldSize()*14/15) { this->setY(World::getInstance()->getWorldSize()*14/15 - this->getRadius()); this->invertSpeedY(); return true; } if (World::getInstance()->getGamePlayer(1)->getHealth() <= 0 && this->getX() + this->getRadius() > World::getInstance()->getWorldSize()*14/15) { this->setX(World::getInstance()->getWorldSize()*14/15 - this->getRadius()); this->invertSpeedX(); return true; } if (World::getInstance()->getGamePlayer(2)->getHealth() <= 0 && this->getY() - this->getRadius() < World::getInstance()->getWorldSize()/15) { this->setY(World::getInstance()->getWorldSize()/15 + this->getRadius()); this->invertSpeedY(); return true; } if (World::getInstance()->getGamePlayer(3)->getHealth() <= 0 && this->getX() - this->getRadius() < World::getInstance()->getWorldSize()/15) { this->setX(World::getInstance()->getWorldSize()/15 + this->getRadius()); this->invertSpeedX(); return true; } //if they block it foreach(Object *o, World::getInstance()->getObjects()) { double distance = o->getDistancetoPaddle(QPoint(this->getX(),this->getY())); if (distance != -1 && distance <= this->getRadius()) { onCollision(o); return true; } }
void BlockOccurrence::onCollision(Collisionable* c, int collision_type) { /* Collisions vs Perso */ Perso* perso = dynamic_cast<Perso*>(c); if(perso != NULL) { return onCollision(perso, collision_type); } }
//判断是否发生碰撞 void ItemManager::testCollision(cocos2d::Node * render_node,IDisplayObject *pCollisionTarget) { if (!mItemArray.empty()) { for (int i = 0; i < mItemArray.size(); i++) { auto pItem = mItemArray.at(i); pItem->onCollision(render_node,pCollisionTarget); } } }
void Obstacle::onCollision(const float power) { health-=power; if(health<=0) { onCollision(); createBonus(); } }
void ProjectileOccurrence::onCollision(Collisionable* c, int collision_type) { /* Collision vs BlockOccurrence */ BlockOccurrence* block = dynamic_cast<BlockOccurrence*>(c); if(block != NULL) { return onCollision(block, collision_type); } /* Otherwise */ _projectile->removeProjectileOccurrence(this); }
bool GameObject::checkCollision(const SDL_Rect& b, bool checkOnly){ if(dead){ return false; } int leftA, leftB; int rightA, rightB; int topA, topB; int bottomA, bottomB; leftA = posX; rightA = posX + width; topA = posY; bottomA = posY + height; leftB = b.x; rightB = b.x + b.w; topB = b.y; bottomB = b.y + b.h; if( bottomA <= topB ) { return false; } if( topA >= bottomB ){ return false; } if( rightA <= leftB ){ return false; } if( leftA >= rightB ) { return false; } if(!checkOnly){ onCollision(); } //If none of the sides from A are outside B return true; }
void GameObject::step(units::MS dt, const GroundPlane& ground_plane, std::vector<GameObject>& game_objects) { if (!should_move_) return; const glm::vec3 delta = velocity_ * static_cast<float>(dt); const glm::vec3 new_center = center_ + delta; if (Bounds(new_center.x - kRadius, new_center.x + kRadius).within(ground_plane.x_bounds()) && Bounds(new_center.z - kRadius, new_center.z + kRadius).within(ground_plane.z_bounds())) { bool collided = false; for (auto& g : game_objects) { if (this != &g && BoundingSphere{new_center, kRadius}.collides(g.bounding_sphere())) { onCollision(); g.onCollision(); collided = true; } } if (!collided) center_ = new_center; } else { velocity_ = -velocity_; step(dt, ground_plane, game_objects); } }
void Projectile::processTick(const Move* move) { Parent::processTick(move); mCurrTick++; if(mSourceObject && mCurrTick > SourceIdTimeoutTicks) { mSourceObject = 0; mSourceObjectId = 0; } // See if we can get out of here the easy way ... if (isServerObject() && mCurrTick >= mDataBlock->lifetime) { deleteObject(); return; } else if (mHidden == true) return; // ... otherwise, we have to do some simulation work. RayInfo rInfo; Point3F oldPosition; Point3F newPosition; oldPosition = mCurrPosition; if(mDataBlock->isBallistic) mCurrVelocity.z -= 9.81 * mDataBlock->gravityMod * (F32(TickMs) / 1000.0f); newPosition = oldPosition + mCurrVelocity * (F32(TickMs) / 1000.0f); // disable the source objects collision reponse while we determine // if the projectile is capable of moving from the old position // to the new position, otherwise we'll hit ourself if (mSourceObject.isValid()) mSourceObject->disableCollision(); disableCollision(); // Determine if the projectile is going to hit any object between the previous // position and the new position. This code is executed both on the server // and on the client (for prediction purposes). It is possible that the server // will have registered a collision while the client prediction has not. If this // happens the client will be corrected in the next packet update. // Raycast the abstract PhysicsWorld if a PhysicsPlugin exists. bool hit = false; if ( gPhysicsPlugin ) { // TODO: hacked for single player... fix me! PhysicsWorld *world = gPhysicsPlugin->getWorld( "Server"/*isServerObject() ? "Server" : "Client"*/ ); if ( world ) hit = world->castRay( oldPosition, newPosition, &rInfo, Point3F( newPosition - oldPosition) * mDataBlock->impactForce ); } else hit = getContainer()->castRay(oldPosition, newPosition, csmDynamicCollisionMask | csmStaticCollisionMask, &rInfo); if ( hit ) { // make sure the client knows to bounce if(isServerObject() && (rInfo.object->getType() & csmStaticCollisionMask) == 0) setMaskBits(BounceMask); // Next order of business: do we explode on this hit? if(mCurrTick > mDataBlock->armingDelay) { MatrixF xform(true); xform.setColumn(3, rInfo.point); setTransform(xform); mCurrPosition = rInfo.point; mCurrVelocity = Point3F(0, 0, 0); // Get the object type before the onCollision call, in case // the object is destroyed. U32 objectType = rInfo.object->getType(); // re-enable the collision response on the source object since // we need to process the onCollision and explode calls if(mSourceObject) mSourceObject->enableCollision(); // Ok, here is how this works: // onCollision is called to notify the server scripts that a collision has occurred, then // a call to explode is made to start the explosion process. The call to explode is made // twice, once on the server and once on the client. // The server process is responsible for two things: // 1) setting the ExplosionMask network bit to guarantee that the client calls explode // 2) initiate the explosion process on the server scripts // The client process is responsible for only one thing: // 1) drawing the appropriate explosion // It is possible that during the processTick the server may have decided that a hit // has occurred while the client prediction has decided that a hit has not occurred. // In this particular scenario the client will have failed to call onCollision and // explode during the processTick. However, the explode function will be called // during the next packet update, due to the ExplosionMask network bit being set. // onCollision will remain uncalled on the client however, therefore no client // specific code should be placed inside the function! onCollision(rInfo.point, rInfo.normal, rInfo.object); explode(rInfo.point, rInfo.normal, objectType ); // break out of the collision check, since we've exploded // we don't want to mess with the position and velocity } else { if(mDataBlock->isBallistic) { // Otherwise, this represents a bounce. First, reflect our velocity // around the normal... Point3F bounceVel = mCurrVelocity - rInfo.normal * (mDot( mCurrVelocity, rInfo.normal ) * 2.0);; mCurrVelocity = bounceVel; // Add in surface friction... Point3F tangent = bounceVel - rInfo.normal * mDot(bounceVel, rInfo.normal); mCurrVelocity -= tangent * mDataBlock->bounceFriction; // Now, take elasticity into account for modulating the speed of the grenade mCurrVelocity *= mDataBlock->bounceElasticity; // Set the new position to the impact and the bounce // will apply on the next frame. //F32 timeLeft = 1.0f - rInfo.t; newPosition = oldPosition = rInfo.point + rInfo.normal * 0.05f; } } } // re-enable the collision response on the source object now // that we are done processing the ballistic movement if (mSourceObject.isValid()) mSourceObject->enableCollision(); enableCollision(); if(isClientObject()) { emitParticles(mCurrPosition, newPosition, mCurrVelocity, TickMs); updateSound(); } mCurrDeltaBase = newPosition; mCurrBackDelta = mCurrPosition - newPosition; mCurrPosition = newPosition; MatrixF xform(true); xform.setColumn(3, mCurrPosition); setTransform(xform); }