Esempio n. 1
0
    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);
                        }
                    }
                }
            }
        }
    }
Esempio n. 2
0
void Player::moveForward(const float speed)
{
    //Vector3 pos = getPosition();
    const float speed_multiplier = 40;

    float cosYaw = cosf(degreesToRadians(m_yaw));
    float sinYaw = sinf(degreesToRadians(m_yaw));
    //pos.x += float(cosYaw)*speed;
    //pos.z += float(sinYaw)*speed;

    btVector3 linearVelocity = getCollider()->getBody()->getLinearVelocity();

    getCollider()->getBody()->setLinearVelocity(btVector3(btScalar(float(cosYaw)*speed*speed_multiplier), linearVelocity.getY(), btScalar(float(sinYaw)*speed*speed_multiplier)));

    //setPosition(pos);
}
Esempio n. 3
0
void Player::onCollision(GameObject* other)
{
	sf::Vector2f off = { 0.f, 0.f };
	PlatformObject* platform = dynamic_cast<PlatformObject*>(other);
	if (platform)
	{
		
		if (m_position.y + dynamic_cast<BoxCollider*>(getCollider())->GetExtention().y 
			<= platform->getPosition().y)
		{
			onGround = true;
		}
		if (m_collMgr->getCount() > 0)
		{
			off = platform->getCollider()->getOffset();
			off /= static_cast<float>(m_collMgr->getCount());
			off.x = floorf(off.x);
			off.y = floorf(off.y);
			m_position += off;

		}
		else
		{
			m_position += dynamic_cast<PlatformObject*>(platform)->getCollider()->getOffset();
		}
		
	}
	
	//m_velocity *= 0.9f;
	//printf("Player::onCollision()\n")
}
bool GameObject::collides(GameObject * otherGameObject) {
	Collider* c = getCollider();
	assert( otherGameObject != NULL);
	Collider* oc = otherGameObject->getCollider();
	assert( c != NULL);
	assert( oc != NULL);
	return c->collides(oc);
}
Esempio n. 5
0
File: Enemy.cpp Progetto: hdt80/SSS
    void Enemy::tick(float delta) {
        movement(delta);
        if(canFire())
            fire();

        if(getCollider()->collides(SphereCollider(Game::getGame().getPlayer().getPosition(), 1))) {
            // TODO: what side we were hit on
            Connection::getInstance().write("EVN#1;0;");
            destroy();
        }
    }
Esempio n. 6
0
void PhysicsEntity::renderCollider(int x, int y) const
{
    Colliders::RectangleCollider collider = getCollider();

    SDL_Rect srcRect = {
            collider.x + x,
            collider.y + y,
            collider.width,
            collider.height
    };
    SDL_RenderDrawRect(renderer(), &srcRect);
}
Esempio n. 7
0
void Flying::handleMovement(Vector2D velocity)
{
	Vector2D newPos = m_position;
	newPos.y(newPos.y() + velocity.y());
	// Check collisions in y axis
	if (newPos.y() + getCollider().y <= 0
		|| newPos.y() + getCollider().y + getCollider().h >= TheGame::Instance().getMapHeight()
		|| checkCollideTile(newPos)
		|| checkCollideObject(newPos))
	{
		m_bYCollision = !m_bYCollision;
	}
	else
	{
		m_position.y(newPos.y());
	}

	// Update new position
	newPos = m_position;
	newPos.x(m_position.x() + velocity.x());
	// Check collisions in x axis
	if (newPos.x() + getCollider().x <= 0
		|| newPos.x() + getCollider().x + getCollider().w >= TheGame::Instance().getMapWidth()
		|| checkCollideTile(newPos)
		|| checkCollideObject(newPos))
	{
		// There have been a collision, so change direction
		m_bXCollision = !m_bXCollision;
	}
	else
	{
		// Move to new x position
		m_position.x(newPos.x());
	}
}
Esempio n. 8
0
 const SUCCESS StaticObject::checkCollision(PhysicalObject &object)
 {
     if(getCollider() == NULL || object.getCollider() == NULL)
     {
         return SUCCEEDED;
     }
     else
     {
         Radians angle;
         if(getCollider()->canCollide(object.getCollider()->getType()))
             if(getCollider()->collides(*object.getCollider(), &angle))
                 return collided(object, angle);   // this ensures that object collider is called by this collided function, likewise a derived class needs to make sure its own derived collided function is called
             else
                  return SUCCEEDED;
         else if(object.getCollider()->canCollide(getCollider()->getType()))
             if(object.getCollider()->collides(*getCollider(), &angle))
                  return collided(object, angle);
             else
                  return SUCCEEDED;
         else
              return FAILED;
     }
 }
Esempio n. 9
0
void Projectile::loadProjectile()
{
	if(projectileAnimation == NULL)
	{
		for(int i = 0; i < PROJECTILE_FRAMES; i++)
		{
			char pathToFrame[256];
			sprintf_s(pathToFrame, 256, PROJECTILE_FRAMES_PATH, i);

			if((projectileFrames[i] = ImageManager::createImage(pathToFrame)) == NULL)
				return;
		}

		projectileAnimation = AnimationManager::createAnimation(projectileFrames, PROJECTILE_FRAMES, DELAY_BETWEEM_FRAMES);
		projectileAnimation->startPlaying();
		projectileCollideSurface = getCollider(projectileFrames[0]);
	}
}
Esempio n. 10
0
    const SUCCESS PhysicalObject::collided(PhysicalObject &object, const Radians angle)
    {
        Vector initVec(getVelocity()-object.getVelocity());
        Mag_t<double> initVel(initVec.mag());
        Radians initTheta(initVec.theta());
        
		if(fabs(getX(initVel, initTheta-angle)) < REST_THRESHOLD)
        {
			setVelocity(getVelocity()+initVec/2.0);
			object.setVelocity(object.getVelocity()-initVec/2.0);
            antigravitate(object);
            object.antigravitate(*this);
			return SUCCEEDED;
		}
		
        // Frame of reference with the object at rest with this approaching it with an angle of 0
        Point<double> p2(Vector(Mag_t<double>(2.0*getMass()*getX(initVel, initTheta-angle)/(getMass()+object.getMass())), initTheta-angle));  // Gets the velocity of 2 based on elastic collision equation
        Point<double> p1((initVel*getMass()-p2.x()*object.getMass())/getMass(), -p2.y()*object.getMass()/getMass());   // Gets the velocity of 1 based off of elastic collision rulez
        
        if(fabs(p1.x()) < REST_THRESHOLD && fabs(p2.x()) < REST_THRESHOLD)
        {
            p1.x(0.0);
            p2.x(0.0);
        }
        
        Vector v1(p1);
        Vector v2(p2);
        
        v1.theta(-v1.theta()+initTheta);
        v2.theta(angle);
        
        v1 += object.getVelocity();
        v2 += object.getVelocity();
        
        Point<double> dif(object.getPosition()-*position);
        while(getCollider()->collides(*object.getCollider()))
            acceleration.set(*position-dif/pythagoras<double>(dif));
        
        setVelocity(v1);
        object.setVelocity(v2);
        
        return SUCCEEDED;
    }
Esempio n. 11
0
 const SUCCESS StaticObject::collided(PhysicalObject &object, const Radians angle)
 {
     Vector v(object.getVelocity());
     v.theta() -= angle;
     Point<double> appliedMomentum(v);
     if(fabs(appliedMomentum.x()) < REST_THRESHOLD)
     {
         appliedMomentum.x(0);
     }
     appliedMomentum.x() *= -1;
     v = appliedMomentum;
     v.theta() += angle;
     object.setVelocity(v);
     
     Point<double> dif(getPosition()-object.getPosition());
     while(getCollider()->collides(*object.getCollider()))
         object.setPosition(object.getPosition()-dif/pythagoras<double>(dif));
     
     return SUCCEEDED;
 }
Esempio n. 12
0
void
WorkerBee::onState(State state, sf::Time dt)
{
    Vec2d empty(-1.0, -1.0);

    // first state
    if (state == IN_HIVE) {
        // if bee has pollen transfer it to hive
        if (getPollen() > 0) {
            transferPollen(dt);
            flower_location_ = empty;
            setDebugStatus("in_hive_leaving_pollen");
        } else {
            // if bee has not enough energy to leave hive, eat its nectar
            if (getEnergy() < energy_leave_hive_
                && getHive().getNectar() > 0) {
                setDebugStatus("in_hive_eating");
                eatFromHive(dt);
            }
            // if there is a flower in memory and enough energy, target move
            // to this flower
            else if (flower_location_ != empty
                     && getEnergy() > energy_collect_pollen_) {
                setDebugStatus("in_hive_leaving");
                setMoveTarget(flower_location_);
                // change state to to flower
                nextState();
            } else {
                setDebugStatus("in_hive_no_flower");
            }
        }
    }

    // second state
    else if (state == TO_FLOWER) {
        setDebugStatus("to_flower");

        if (getEnergy() < energy_collect_pollen_) {
            nextState();
            nextState();
        }

        Flower* flower  = getAppEnv().getCollidingFlower(getVisionRange());

        if (flower) {
            setMoveTarget(flower->getPosition());
            setMoveState(MoveState::TARGET);
            if (isPointInside(flower->getPosition())) {
                nextState();
            }
        } else if (isPointInside(flower_location_)) {
            // go back to hive and clear location
            nextState();
            nextState();
            setFlowerLocation(Vec2d(-1,-1));
        }
    }

    // third state
    else if (state == COLLECT_POLLEN) {
        // if there is a flower at flower location and it has pollen and
        // bee has not enough pollen, eat pollen from flower
        Flower* flower(getAppEnv().getCollidingFlower(getCollider()));
        if ((getPollen() < max_pollen_)
            && (flower != nullptr)
            && (flower->getPollen() > 0)) {
            eatPollen(flower, dt);
        } else {
            // else skip collection
            nextState();
        }
    } else if (state == RETURN_HIVE) {
        // if bee is in hive change state to in hive
        if (getHive().isColliderInside(getCollider())) {
            nextState();
        }
    }
}
	/**
	*<summary>
	* Check separation Axis test between passed GameObject(A) and calling GameObject(B)
	* You may need to call it twice - for checking collision of B in A's coordinate system
	*</Summary>
	*/
	bool GameObject::separationAxisTest(SharedPointer<GameObject> i_other, float& o_collisionTime, float & o_separationTime, myEngine::typedefs::Axis &o_collisionAxis) //Move to Collsion System to make it better - To-Do
	{
		bool isColliding = false;
		float tCollisionInX = 0.0f;
		float tSeparationInX = 0.0f;
		float tCollisionInY = 0.0f;
		float tSeparationInY = 0.0f;
		float tCollisionInZ = 0.0f;
		float tSeparationInZ = 0.0f;

		//Position of other GameObject in this
		Vector3D i_otherCenterPositionInThis = getTranslatedPosition(i_other->getPosition());

		//Extent of other gameObject in this
		Vector3D i_otherExtentInThis = getTransformedExtents(i_other);

		//Transformed velocity of calling gamobject in its own coordiante system
		Vector3D thisVelocityInThis = getTranslationMatrix() *physicsComponent->getCurrentVelocity();

		//Velocity of other GameObject in calling gameObject coordinate system
		Vector3D i_otherVelocityInThis = getTranslationMatrix() * i_other->physicsComponent->getCurrentVelocity();

		//Relative velocity of other gamObject in freezed gameObject coordinate system i.e. in calling gameObject coordiante system
		Vector3D i_otherChangedVelocityInThis = i_otherVelocityInThis - thisVelocityInThis;

		//Expanding the extents of calling gameObject
		float thisChangedXExtent = getCollider()->getExtendX() + i_otherExtentInThis.getX();
		float thisChangedYExtent = getCollider()->getExtendY() + i_otherExtentInThis.getY();
		float thisChangedZExtent = getCollider()->getExtendZ() + i_otherExtentInThis.getZ();
		
		bool finalCollisionTimeInitialized = false;

		//Swept collision for each axes

		//Checking in X-Axis
		switch (i_otherCenterPositionInThis.getX() >= 0 )
		{
		case true:
			if (i_otherCenterPositionInThis.getX() <= thisChangedXExtent)
			{
				//To-Do - time of collision - Done but need testing
				if (i_otherChangedVelocityInThis.getX() != 0)
				{
					tCollisionInX = abs(((0 + thisChangedXExtent) - i_otherCenterPositionInThis.getX()) / i_otherChangedVelocityInThis.getX());
					tSeparationInX = abs((i_otherCenterPositionInThis.getX() - (0 - thisChangedXExtent)) / i_otherChangedVelocityInThis.getX());
					o_collisionTime = tCollisionInX;
					o_separationTime = tSeparationInX;
					o_collisionAxis = myEngine::typedefs::XAxis;
					finalCollisionTimeInitialized = true;
				}
			}
			else return false;
			break;
		case false:
			if (abs(i_otherCenterPositionInThis.getX()) <= thisChangedXExtent)
			{
				//To-Do - time of collision - Done but need testing
				if (i_otherChangedVelocityInThis.getX() != 0)
				{
					tCollisionInX = abs((i_otherCenterPositionInThis.getX() - (0 - thisChangedXExtent)) / i_otherChangedVelocityInThis.getX());
					tSeparationInX = abs(((0 + thisChangedXExtent) - i_otherCenterPositionInThis.getX()) / i_otherChangedVelocityInThis.getX());
					o_collisionTime = tCollisionInX;
					o_separationTime = tSeparationInX;
					o_collisionAxis = myEngine::typedefs::XAxis;
					finalCollisionTimeInitialized = true;
				}				
			}
			else return false;
			break;
		}


		//Check in Y-axis in case X-Axis collision is true
		switch (i_otherCenterPositionInThis.getY() >= 0)
		{
		case true:
			if (i_otherCenterPositionInThis.getY() <= thisChangedYExtent)
			{
				//To-Do - time of collision -Done but need testing
				if (i_otherChangedVelocityInThis.getY() != 0)
				{
					tCollisionInY = abs(((0 + thisChangedYExtent) - i_otherCenterPositionInThis.getY()) / i_otherChangedVelocityInThis.getY());
					tSeparationInY = abs((i_otherCenterPositionInThis.getY() - (0 - thisChangedYExtent)) / i_otherChangedVelocityInThis.getY());
					
					if (!finalCollisionTimeInitialized)
					{
						o_collisionTime = tCollisionInY;
						o_separationTime = tSeparationInY;
						o_collisionAxis = myEngine::typedefs::YAxis;
					}
					else
					{
						if (tCollisionInY < o_collisionTime)
						{
							o_collisionTime = tCollisionInY;
							o_collisionAxis = myEngine::typedefs::YAxis;

						}

						if (tSeparationInY < o_separationTime)
							o_separationTime = tSeparationInY;
					}
				}
			}
			else return false;
			break;
		case false:
			if (abs(i_otherCenterPositionInThis.getY()) <= thisChangedYExtent)
			{
				//To-Do - time of collision - Done but need testing
				if (i_otherChangedVelocityInThis.getY() != 0)
				{
					tCollisionInY = abs((i_otherCenterPositionInThis.getY() - (0 - thisChangedYExtent)) / i_otherChangedVelocityInThis.getY());
					tSeparationInY = abs(((0 + thisChangedYExtent) - i_otherCenterPositionInThis.getY()) / i_otherChangedVelocityInThis.getY());
					
					if (!finalCollisionTimeInitialized)
					{
						o_collisionTime = tCollisionInY;
						o_separationTime = tSeparationInY;
						o_collisionAxis = myEngine::typedefs::YAxis;
					}
					else
					{

						if (tCollisionInY < o_collisionTime)
						{
							o_collisionTime = tCollisionInY;
							o_collisionAxis = myEngine::typedefs::YAxis;
						}

						if (tSeparationInY < o_separationTime)
							o_separationTime = tSeparationInY;
					}
				}
			}
			else return false;
			break;
		}


		//Check in Z-axis in case X-Axis and Y-Axis collision is true
		switch (i_otherCenterPositionInThis.getZ() >= 0)
		{
		case true:
			if (i_otherCenterPositionInThis.getZ() <= thisChangedZExtent)
			{
				//To-Do - time of collision - Done but need testing
				if (i_otherChangedVelocityInThis.getZ() != 0)
				{
					tCollisionInZ = abs(((0 + thisChangedZExtent) - i_otherCenterPositionInThis.getZ()) / i_otherChangedVelocityInThis.getZ());
					tSeparationInZ = abs((i_otherCenterPositionInThis.getZ() - (0 - thisChangedZExtent)) / i_otherChangedVelocityInThis.getZ());

					if (!finalCollisionTimeInitialized)
					{
						o_collisionTime = tCollisionInZ;
						o_separationTime = tSeparationInZ;
						o_collisionAxis = myEngine::typedefs::ZAxis;
					}
					else
					{

						if (tCollisionInY < o_collisionTime)
						{
							o_collisionTime = tCollisionInZ;
							o_collisionAxis = myEngine::typedefs::ZAxis;
						}

						if (tSeparationInY < o_separationTime)
							o_separationTime = tSeparationInZ;
					}
				}
			}
			else return false;
			break;
		case false:
			if (abs(i_otherCenterPositionInThis.getZ()) <= thisChangedZExtent)
			{
				//To-Do - time of collision - Done but need testing
				if (i_otherChangedVelocityInThis.getZ() != 0)
				{
					tCollisionInZ = abs((i_otherCenterPositionInThis.getZ() - (0 - thisChangedZExtent)) / i_otherChangedVelocityInThis.getZ());
					tSeparationInZ = abs(((0 + thisChangedZExtent) - i_otherCenterPositionInThis.getZ()) / i_otherChangedVelocityInThis.getZ());

					if (!finalCollisionTimeInitialized)
					{
						o_collisionTime = tCollisionInZ;
						o_separationTime = tSeparationInZ;
						o_collisionAxis = myEngine::typedefs::ZAxis;
					}
					else
					{
						if (tCollisionInY < o_collisionTime)
						{
							o_collisionTime = tCollisionInZ;
							o_collisionAxis = myEngine::typedefs::ZAxis;
						}
						if (tSeparationInY < o_separationTime)
							o_separationTime = tSeparationInZ;
					}
				}
			}
			else return false;
			break;
		}

		
		//returning if all if's are false i.e. collsion occured in this coordinate system
		return true;
	}
Esempio n. 14
0
void Chaser::handleMovement(Vector2D velocity)
{
	Vector2D newPos = m_position;
	newPos.x(m_position.x() + velocity.x());

	if (newPos.x() == m_playerPos->x())
	{
		m_velocity.x(0);
	}
	else
	{
		// check if the chaser is trying to go off the map
		if (newPos.x() + getCollider().x < 0)
		{
			m_position.x(-getCollider().x);
		}
		else if (newPos.x() + getCollider().x + getCollider().w > TheGame::Instance().getMapWidth())
		{
			m_position.x(TheGame::Instance().getMapWidth() - getCollider().w - getCollider().x);
		}
		else
		{
			if (checkCollideTile(newPos) || checkCollideObject(newPos))
			{
				// collision, stop x movement
				m_velocity.x(0);

				if (checkCollideTile(newPos))
				{
					// Collision with the map, move to contact
					if (m_position.x() < newPos.x())	// Collision with tile to the right
					{
						m_position.x(m_position.x() + (
							abs(m_xSpeed) - (int(newPos.x() + getCollider().x + getCollider().w) % (*m_pCollisionLayers->begin())->getTileSize())));

					}
					else   // Collision with tile to the left
					{
						m_position.x(m_position.x() -
							(int(m_position.x() + getCollider().x) % (*m_pCollisionLayers->begin())->getTileSize()));
					}
				}
			}
			else
			{
				// no collision, add to the actual x position
				m_position.x(newPos.x());
			}
		}
	}

	newPos.x(m_position.x());
	newPos.y(m_position.y() + velocity.y());

	// check if the chaser is going below map limits
	if (newPos.y() + getCollider().y + getCollider().h > TheGame::Instance().getMapHeight())
	{
		m_position.y(TheGame::Instance().getMapHeight() - getCollider().h - getCollider().y);
		m_velocity.y(0);
	}
	else
	{
		if (checkCollideTile(newPos) || checkCollideObject(newPos))
		{
			// Collision, stop y movement
			m_velocity.y(0);

			if (checkCollideTile(newPos))
			{
				// Collision with map, move to contact. Chaser doesn't jump so it's a lower tile
				m_position.y(m_position.y() +
					(m_ySpeed - (int(newPos.y() + getCollider().y + getCollider().h) % (*m_pCollisionLayers->begin())->getTileSize())));
			}
		}
		else
		{
			// no collision, add to the actual y position
			m_position.y(newPos.y());
		}
	}
}
Esempio n. 15
0
void PhysicsEntity::move(PhysicsEntity::Direction dir)
{
    Colliders::RectangleCollider collider = getCollider();

    switch (dir)
    {
    case Direction_Top:
        if (_collisionSubscriber->value()->isColliding(collider.margin((int) speed(), Colliders::Direction_Top)))
        {
            for (int allowedMargin = (int) speed();
                 allowedMargin >= 0;
                 allowedMargin--)
            {
                if (!_collisionSubscriber->value()->isColliding(
                        collider.margin(allowedMargin, Colliders::Direction_Top)))
                {
                    setPosition(position() + Vector2(0, -allowedMargin));
                    break;
                }
            }
        }
        else
            setPosition(position() + Vector2(0, -speed()));
        break;
    case Direction_Right:
        if (_collisionSubscriber->value()->isColliding(collider.margin((int) speed(), Colliders::Direction_Right)))
        {
            for (int allowedMargin = (int) speed();
                 allowedMargin >= 0;
                 allowedMargin--)
            {
                if (!_collisionSubscriber->value()->isColliding(
                        collider.margin(allowedMargin, Colliders::Direction_Right)))
                {
                    setPosition(position() + Vector2(allowedMargin, 0));
                    break;
                }
            }
        }
        else
            setPosition(position() + Vector2(speed(), 0));
        break;
    case Direction_Left:
        if (_collisionSubscriber->value()->isColliding(collider.margin((int) speed(), Colliders::Direction_Left)))
        {
            for (int allowedMargin = (int) speed();
                 allowedMargin >= 0;
                 allowedMargin--)
            {
                if (!_collisionSubscriber->value()->isColliding(
                        collider.margin(allowedMargin, Colliders::Direction_Left)))
                {
                    setPosition(position() + Vector2(-allowedMargin, 0));
                    break;
                }
            }
        }
        else
            setPosition(position() + Vector2(-speed(), 0));
        break;
    case Direction_Bottom:
        if (_collisionSubscriber->value()->isColliding(collider.margin((int) speed(), Colliders::Direction_Bottom)))
        {
            for (int allowedMargin = (int) speed();
                 allowedMargin >= 0;
                 allowedMargin--)
            {
                if (!_collisionSubscriber->value()->isColliding(
                        collider.margin(allowedMargin, Colliders::Direction_Bottom)))
                {
                    setPosition(position() + Vector2(0, allowedMargin));
                    break;
                }
            }
        }
        else
            setPosition(position() + Vector2(0, speed()));
        break;
    }
}