void Collisionhandler::collisionBetweenEntitiesAndTerrains(Entities &entities, Terrains &terrains){
	for (Entities::size_type i = 0; i < entities.size(); i++){
		Entity *e0 = entities[i];
		for (Terrains::size_type j = 0; j < terrains.size(); j++){
			Terrain *e1 = terrains[j];
			if (e0->isOnScreen() && e1->isOnScreen()) {
				if (hasCollided(e0, e1)) {
					checkCollisionDirection(e0, e1);
				}
			}
		}
	}
}
void Collisionhandler::collisionBetweenEntities(Entities &entities){
	for (Entities::size_type i = 0; i < entities.size(); i++){
		Entity *e0 = entities[i];
		for (Entities::size_type j = i + 1; j < entities.size(); j++){
			Entity *e1 = entities[j];
			if (e0->isOnScreen() && e1->isOnScreen()) {
				if (hasCollided(e0, e1)) {
					if (e0->getType() != e1->getType() && e0->getType() == Entity::PLAYER) {
						checkCollisionDirection(e0, e1);
						//checkCollisionDirection(e1, e0);
					}
				}
			}
		}
	}
}
Пример #3
0
void Shot::draw(BITMAP *buffer, int offsetX, int offsetY, int layer){
	int x = getDrawPositionX();
	int y = getDrawPositionY();

	int frame;
	if(! hasCollided()){
		frame = mFrame/10;
		mShotAnimation[mShotType]->drawFrame(buffer,
			frame, 
			offsetX + x - mShotAnimation[mShotType]->getFrameWidth()/2, 
			offsetY + y+getHalfSize().y-mShotAnimation[mShotType]->getFrameHeight());
	} else {
		cFrame++;
		frame = cFrame/10;
		mCollisionAnimation[mShotType]->drawFrame(buffer,
			frame, 
			offsetX + x - mCollisionAnimation[mShotType]->getFrameWidth()/2, 
			offsetY + y+getHalfSize().y-mCollisionAnimation[mShotType]->getFrameHeight());
	}
}
Пример #4
0
    //Stroke vs rectangle
    bool hasCollided(sf::Vector2f c1, float r11, float r12, sf::Vector2f c2, sf::Vector2f s2, float dir2)
    {
        if (!hasCollided(c2, s2, dir2, c1, r12)) return false;
        if (r11 < 0) return false;

        //Transforming vectors
        float unitX2 = cos(dir2);
        float unitY2 = sin(dir2);
        sf::Vector2f rotWidth2(unitX2 * s2.x / 2.f, unitY2 * s2.x / 2.f);
        sf::Vector2f rotHeight2(-unitY2 * s2.y / 2.f, unitX2 * s2.y / 2.f);
        sf::Vector2f tr2[] = {c2 - rotWidth2 - rotHeight2,
            c2 + rotWidth2 - rotHeight2,
            c2 + rotWidth2 + rotHeight2,
            c2 - rotWidth2 + rotHeight2};
        
        //Inside edge cross check
        if (getDist(c1, tr2[0]) > r11) return true;
        if (getDist(c1, tr2[1]) > r11) return true;
        if (getDist(c1, tr2[2]) > r11) return true;
        if (getDist(c1, tr2[3]) > r11) return true;

        return false;
    }
Пример #5
0
void Simulation::collisionResolution()
{
	bool collisionDetected = false;
	auto first = planetList.begin();
	while(first != planetList.end())
	{
		for(auto second = planetList.begin(); second != planetList.end(); second++)
		{
			if( (*first) != (*second) && first->hasCollided(*second))
			{
				planetList.push_back((*first) + (*second));
				planetList.erase(second);
				first = planetList.erase(first);			//erase the two collided planets.
				collisionDetected = true;
				break;
			}
		}
		if(collisionDetected)		//If there is a collision, then "first" automatically points to the next value, so there is no need to increment it.
			collisionDetected = false;
		else
			first++;
	}
}
Пример #6
0
 bool hasCollided(sf::Vector2f c1, util::ShapeVector s1, float dir1, sf::Vector2f c2, util::ShapeVector s2, float dir2)
 {
     if (s1.s == Point && s2.s == Point) return hasCollided(c1, c2);
     if (s1.s == Point && s2.s == Circle) return hasCollided(c1, c2, s2.x);
     if (s1.s == Point && s2.s == Rectangle) return hasCollided(c1, c2, sf::Vector2f(s2.x, s2.y), dir2);
     if (s1.s == Point && s2.s == Stroke) return hasCollided(c1, c2, s2.x, s2.y);
     if (s1.s == Circle && s2.s == Point) return hasCollided(c2, c1, s1.x);
     if (s1.s == Circle && s2.s == Circle) return hasCollided(c1, s1.x, c2, s2.x);
     if (s1.s == Circle && s2.s == Rectangle) return hasCollided(c2, sf::Vector2f(s2.x, s2.y), dir2, c1, s1.x);
     if (s1.s == Circle && s2.s == Stroke) return hasCollided(c2, s2.x, s2.y, c1, s1.x);
     if (s1.s == Rectangle && s2.s == Point) return hasCollided(c2, c1, sf::Vector2f(s1.x, s1.y), dir1);
     if (s1.s == Rectangle && s2.s == Circle) return hasCollided(c1, sf::Vector2f(s1.x, s1.y), dir1, c2, s2.x);
     if (s1.s == Rectangle && s2.s == Rectangle) return hasCollided(c1, sf::Vector2f(s1.x, s1.y), dir1, c2, sf::Vector2f(s2.x, s2.y), dir2);
     if (s1.s == Rectangle && s2.s == Stroke) return hasCollided(c2, s2.x, s2.y, c1, sf::Vector2f(s1.x, s1.y), dir1);
     if (s1.s == Stroke && s2.s == Point) return hasCollided(c2, c1, s1.x, s1.y);
     if (s1.s == Stroke && s2.s == Circle) return hasCollided(c1, s1.x, s1.y, c2, s2.x);
     if (s1.s == Stroke && s2.s == Rectangle) return hasCollided(c1, s1.x, s1.y, c2, sf::Vector2f(s2.x, s2.y), dir2);
     return false;
 }
Пример #7
0
void Shot::update(){
	if (++mLife > 180){
		setCollided(true);
	}
	if (touchesDangerousTile()){
		setCollided(true);
	}
	if(hasCollided()){
		if (--mCollidedTimer < 0){
			remove();
			//remove
		}
		return;
	}
	// move
	int cur_x = getPosition().x;
	int cur_y = getPosition().y;
	int floor_y, edge_x;
	int bumps;
	/*
	floor_y= cur_y+getHalfSize().y+5;
	if (mFacingDirection == Direction_Left){
		edge_x=cur_x-getHalfSize().x;
	} else {
		edge_x=cur_x+getHalfSize().x;
	}
	*/
	if(mGravity[mShotType] == ShotType_Bullet){
		setVelocity(float2(mInitialVelocity[mShotType].x*getDirection(),mInitialVelocity[mShotType].y));
	} else {
		setVelocity(float2(mInitialVelocity[mShotType].x*getDirection(),mInitialVelocity[mShotType].y+GRAVITY*mLife));
	}
	//setVelocity(float2(12.0f,.0f));
	bumps=moveWithCollision();

	if((bumps & Direction_Left) != 0 || (bumps & Direction_Right) != 0 || (bumps & Direction_Up) != 0|| (bumps & Direction_Down) != 0 ){
		setCollided(true);
		if (mShotType == ShotType_GravityGrenade || mShotType == ShotType_Fireball) { Sound::playSample("data/sounds/grenadeexplode.wav"); }
	}

	if(!mHurtPlayer){
		std::vector<Entity*> collidedEntity = mRoom->checkEntitiesForCollision(this);
		if(collidedEntity.size() > 0){
			setCollided(true);
			if (mShotType == ShotType_GravityGrenade || mShotType == ShotType_Fireball) { Sound::playSample("data/sounds/grenadeexplode.wav"); }
			for(int i=0;i<collidedEntity.size();i++){
				attack(collidedEntity[i]);
			}
		}
	} else {
		Hero* h = mRoom->getHero();
		Entity::CollisionRect cr= h->getCollisionRect();
		if(Collides(getCollisionRect(),cr)){
			setCollided(true);
			if (mShotType == ShotType_GravityGrenade || mShotType == ShotType_Fireball) { Sound::playSample("data/sounds/grenadeexplode.wav"); }
			if(mShotType == ShotType_Fireball || mShotType == ShotType_Bullet){
				h->die();
				return;
			}
			if(mShotType == ShotType_GravityGrenade){
				attack(h);
				return;
			}
		}
	}

	mFrame++;
	

}
Пример #8
0
/*
	Calculates the coordinates of the collision point
*/
void Convex::convexCollision(Convex* other, sf::RenderWindow* window)
{
	sf::Vector2f collisionNormal;
	float collisionX, collisionY;
	float x1, x2, x3, x4, y1, y2, y3, y4;
	

	if (hasCollided(other))
	{
		for (int i = 0; i < getPointCount(); i++)
		{
			//Retrieves the coordinates of the point i
			x1 = this->getPoint(i).x;
			y1 = this->getPoint(i).y;

			//If the index 'i' equals the amount of points
			//the other end of the line should be the starting point
			if (i == getPointCount() - 1)
			{
				x2 = this->getPoint(0).x;
				y2 = this->getPoint(0).y;
			}
			else
			{
				x2 = this->getPoint(i + 1).x;
				y2 = this->getPoint(i + 1).y;
			}


			for (int j = 0; j < other->getPointCount(); j++)
			{
				x3 = other->getPoint(j).x;
				y3 = other->getPoint(j).y;

				//If the index 'j' equals the amount of points
				//the other end of the line should be the starting point
				if (i == getPointCount() - 1)
				{
					x4 = other->getPoint(0).x;
					y4 = other->getPoint(0).y;
				}
				else
				{
					x4 = other->getPoint(i + 1).x;
					y4 = other->getPoint(i + 1).y;
				}

				collisionX = vectorProduct(vectorProduct(x1, y1, x2, y2),
							 vectorProduct(x1, 1, x2, 1),
							 vectorProduct(x3, y3, x4, y4),
							 vectorProduct(x3, 1, x4, 1))
							 /
							 vectorProduct(vectorProduct(x1, 1, x2, 1),
							 vectorProduct(y1, 1, y2, 1),
							 vectorProduct(x3, 1, x4, 1),
							 vectorProduct(y3, 1, y4, 1));

				collisionY = vectorProduct(vectorProduct(x1, y1, x2, y2),
							 vectorProduct(y1, 1, y2, 1),
							 vectorProduct(x3, y3, x4, y4),
							 vectorProduct(y3, 1, y4, 1))
							 /
							 vectorProduct(vectorProduct(x1, 1, x2, 1),
							 vectorProduct(y1, 1, y2, 1),
							 vectorProduct(x3, 1, x4, 1),
							 vectorProduct(y3, 1, y4, 1));
				
				//Checking that the collision point is actually between the corners
				//of the convexes
				if (isBetween(collisionX, x1, x2) && isBetween(collisionX, x3, x4) &&
					isBetween(collisionY, y1, y2) && isBetween(collisionY, y3, y4))
				{
					//If the collision point is between these points use them to calculate the
					//collisionNormal's components
					if (isBetween(collisionX, x1, x2) && isBetween(collisionY, y1, y2))
					{
						float x = x2 - x1;
						float y = y2 - y1;
						
						float length = sqrt(pow(x, 2) + pow(y, 2));
						float unitX = x / length;
						float unitY = y / length;

						collisionNormal.x = -unitY;
						collisionNormal.y = unitX;

						float impulse = getImpulse(&sf::Vector2f(collisionX, collisionY), &collisionNormal, other, this);
						applyChanges(&collisionNormal, impulse, &sf::Vector2f(collisionX, collisionY), other, this);
					}
					else
					{
						float x = x4 - x3;
						float y = y4 - y3;

						float length = sqrt(pow(x, 2) + pow(y, 2));
						float unitX = x / length;
						float unitY = y / length;

						collisionNormal.x = -unitY;
						collisionNormal.y = unitX;

						float impulse = getImpulse(&sf::Vector2f(collisionX, collisionY), &collisionNormal, this, other);
						applyChanges(&collisionNormal, impulse, &sf::Vector2f(collisionX, collisionY), this, other);
					}
					
					sf::CircleShape circle(5);
					circle.setFillColor(sf::Color::Red);
					circle.setPosition(collisionX, collisionY);
					window->draw(circle);
				}
			}
		}
	}
}
Пример #9
0
const int Ball::move(short scrWidth, short scrHeight,
                     double deltaTime,
                     const SDL_Rect bat,
                     const double batSpeed,
                     std::vector<Brick*>& bricks)
{
    direction.normalize();
    int score = 0;
    const int speedCollisionIncrease = 6;

//=====================
//MOVE THE BALL ACROSS
//=====================
    const double xMove = direction.x * speed * deltaTime;
    position.x += xMove;

    //the only time it'll hit the player after moving across is when it hits the end of the bat
    //so reverse both velocities
    if( hasCollided(bat) )
    {
        position.x -= xMove;
        direction.x *= -1;
        direction.y *= -1;
        speed += speedCollisionIncrease;
    }

    //left or right of the screen
    if(position.x - radius < 0)
    {
        position.x = radius;
        direction.x *= -1;
    }
    else if (position.x + radius > scrWidth)
    {
        position.x = scrWidth - radius;
        direction.x *= -1;
    }

    //if a brick is destructible, increment the score with the brick's score
    //destroy the brick, move the player back and reverse their direction
    for(auto& b : bricks)
    {
        if( hasCollided(b->box()) )
        {
            if( b->isDestructible() )
            {
                score += b->getScore();
                delete b;
                b = nullptr;
            }

            position.x -= xMove;
            direction.x *= -1;
            speed += speedCollisionIncrease;
        }
    }

    bricks.erase(std::remove(bricks.begin(), bricks.end(), static_cast<Brick*>(nullptr)), bricks.end());

//====================
//MOVE THE BALL DOWN
//====================
    const double yMove = direction.y * speed * deltaTime;
    position.y += yMove;

    //put the ball on the top of the bat so it doesn't get caught "inside" it and reverse the direction
    //the last line adds some spin onto the ball
    if( hasCollided(bat))
    {
        position.y = bat.y - radius;
        direction.y *= -1;
        speed += speedCollisionIncrease;
        direction.x += batSpeed * 0.05f;
    }

    //top of the screen
    if(position.y - radius < 0)
    {
        position.y = radius;
        direction.y *= -1;
    }

    //bottom of the screen
    //return -1 as a special case to say the ball is off screen
    if(position.y - radius > scrHeight)
    {
        return -1;
    }

    for(auto& b : bricks)
    {
        if( hasCollided(b->box()) )
        {
            if( b->isDestructible() )
            {
                score += b->getScore();
                delete b;
                b = nullptr;
            }

            position.y -= yMove;
            direction.y *= -1;
            speed += speedCollisionIncrease;
        }
    }

    bricks.erase(std::remove(bricks.begin(), bricks.end(), static_cast<Brick*>(nullptr)), bricks.end());

    return score;
}