Ejemplo n.º 1
0
void Physics::addDynamicRectangle(CollidableObject* co, 
								  float centerX, 
								  float centerY, 
								  int width, 
								  int height, 
								  float angle, 
								  float density, 
								  float friction, 
								  float gravityScale)
{
	b2BodyDef bodyDef;
	bodyDef.type = b2_dynamicBody;
	bodyDef.position.Set(pixelsToMeters(centerX),-pixelsToMeters(centerY));
	bodyDef.gravityScale = gravityScale;
	bodyDef.angle = angle;
	co->getPhysicalProperties()->rigidBody = box2DWorld->CreateBody(&bodyDef);
	b2Body *rigidBody = co->getPhysicalProperties()->rigidBody;
	rigidBody->SetUserData(co);
	b2FixtureDef fixtureDef;
	setCollisionFilters(co, &fixtureDef);
	b2PolygonShape box;
	box.SetAsBox(pixelsToMeters(width/2), pixelsToMeters(height/2));
	fixtureDef.shape = &box;
	fixtureDef.density = density;
	fixtureDef.friction = friction;
	fixtureDef.restitution = .03f;
	co->getPhysicalProperties()->rigidBody->CreateFixture(&fixtureDef);
	co->getPhysicalProperties()->setWidth(width);
	co->getPhysicalProperties()->setHeight(height);
}
Ejemplo n.º 2
0
//////////////////////////KEEP/////////////////////////////////////////////
void Physics::addCollidableObject(CollidableObject *collidableObjectToAdd)
{
	PhysicalProperties *pp = collidableObjectToAdd->getPhysicalProperties();
	float height = pixelsToMeters(collidableObjectToAdd->getBoundingVolume()->getHeight()) / 2;
	float width = pixelsToMeters(collidableObjectToAdd->getBoundingVolume()->getWidth()) / 2;
	float x = pixelsToMeters(pp->getX());
	float y = pixelsToMeters(-pp->getY());

	// Define the dynamic body. We set its position and call the body factory.
	b2BodyDef bodyDef;
	bodyDef.type = b2_dynamicBody;
	bodyDef.position.Set(x, y);
	b2Body* body = box2DWorld->CreateBody(&bodyDef);

	testSubjectBody = body;

	// Define another box shape for our dynamic body.
	b2PolygonShape dynamicBox;
	dynamicBox.SetAsBox(width, height);

	// Define the dynamic body fixture.
	b2FixtureDef fixtureDef;
	fixtureDef.shape = &dynamicBox;

	// Set the box density to be non-zero, so it will be dynamic.
	fixtureDef.density = 1.0f;

	// Override the default friction.
	fixtureDef.friction = 0.3f;

	// Add the shape to the body.
	body->CreateFixture(&fixtureDef);
}
Ejemplo n.º 3
0
Shuriken::Shuriken(const sf::Vector2f& position, const sf::Vector2f& velocity, Game* game)
	: Entity(position, game, "shuriken " + std::to_string(Id))
{
	++Id;

	sprite_.setTexture(game->getTextureManager().getTexture("spriteSheet"));
	sprite_.setTextureRect(sf::IntRect(0, 310, 20, 20));
	sprite_.setOrigin(sprite_.getLocalBounds().left + sprite_.getLocalBounds().width / 2.f, 
		sprite_.getLocalBounds().top + sprite_.getLocalBounds().height / 2.f);

	b2BodyDef bodyDef;
	bodyDef.position.Set(pixelsToMeters(position.x), pixelsToMeters(position.y));
	bodyDef.type = b2_dynamicBody;

	b2PolygonShape shape;
	shape.SetAsBox(pixelsToMeters(static_cast<float>(20)) / 2.f,
		pixelsToMeters(static_cast<float>(20)) / 2.f);

	body_ = game->getWorld()->CreateBody(&bodyDef);

	b2FixtureDef fixtureDef;
	fixtureDef.shape = &shape;
	fixtureDef.density = 1.f;
	fixtureDef.restitution = 0.f;
	fixtureDef.isSensor = true;

	body_->CreateFixture(&fixtureDef);
	body_->SetFixedRotation(false);
	body_->SetUserData(this);
	body_->SetGravityScale(0.f);
	body_->ApplyLinearImpulse(b2Vec2(velocity.x, velocity.y), body_->GetWorldCenter(), true);
	body_->SetAngularVelocity(10.f);

	sprite_.setPosition(metersToPixels(body_->GetPosition().x), metersToPixels(body_->GetPosition().y));
}
Ejemplo n.º 4
0
Finish::Finish(const sf::Vector2f& position, Game* game)
	: Entity(position, game, "finish")
{
	sprite_.setTexture(game->getTextureManager().getTexture("spriteSheet"));
	sprite_.setTextureRect(sf::IntRect(0, 335, 32, 32));
	sprite_.setOrigin(sprite_.getLocalBounds().left + sprite_.getLocalBounds().width / 2.f, 
		sprite_.getLocalBounds().top + sprite_.getLocalBounds().height / 2.f);

	b2BodyDef bodyDef;
	bodyDef.position.Set(pixelsToMeters(position.x), pixelsToMeters(position.y));

	b2PolygonShape shape;
	shape.SetAsBox(pixelsToMeters(static_cast<float>(sprite_.getTexture()->getSize().x)) / 2.f,
		pixelsToMeters(static_cast<float>(sprite_.getTexture()->getSize().y)) / 2.f);

	body_ = game->getWorld()->CreateBody(&bodyDef);

	b2FixtureDef fixtureDef;
	fixtureDef.shape = &shape;
	fixtureDef.density = 1.f;
	fixtureDef.isSensor = true;

	body_->CreateFixture(&fixtureDef);
	body_->SetGravityScale(0.f);
	body_->SetFixedRotation(true);
	body_->SetUserData(this);

	sprite_.setPosition(metersToPixels(body_->GetPosition().x), metersToPixels(body_->GetPosition().y));
}
Ejemplo n.º 5
0
Ball::Ball()
{
	ballImage = new Bitmap("magic_ball.bmp", true);
	isUnderPhysicsControl = false;

	ballRadius = pixelsToMeters((ballImage->getHeight()) / 2);

	Xpos = pixelsToMeters(725);
	Ypos = pixelsToMeters(100) + ballRadius;
}
Ejemplo n.º 6
0
void Physics::addCollidableTiles(TiledLayer *collidableTiles)
{
	if(!collidableTiles->hasCollidableTiles())
	{
		//Why are you wasting time calling this method on a layer that doesn't even have collidable tiles?
		//I'd throw an exception, but that's too much work.
		return;
	}

	int rows = collidableTiles->getRows();
	int columns = collidableTiles->getColumns();
	int tileWidth = collidableTiles->getTileWidth();
	int tileHeight = collidableTiles->getTileHeight();

	for(int i = 0; i < rows; i++)
	{
		for(int k = 0; k < columns; k++)
		{
			Tile *tile = collidableTiles->getTile(i,k);

			if(tile->collidable)
			{
				//The bodyDef position is actually the position of the center of mass, so we add half the height and width to the original x coordinate
				b2BodyDef tileBodyDef;
				float tileXScaled = pixelsToMeters(tileWidth * k + tileWidth/2);
				float tileYScaled = -pixelsToMeters(tileHeight * i + tileHeight/2);
				float tileWidthScaled = pixelsToMeters(tileWidth)/2.0;
				float tileHeightScaled = pixelsToMeters(tileHeight)/2.0;
				tileBodyDef.position.Set(tileXScaled, tileYScaled);

				// Call the body factory which allocates memory for the ground body
				// from a pool and creates the ground box shape (also from a pool).
				// The body is also added to the world.
				b2Body* tileBody = box2DWorld->CreateBody(&tileBodyDef);

				//!!! THIS MAY CAUSE A MEMORY LEAK IF WE DESTORY THE TILE BODY WITHOUT ALSO DESTROYING THE USER DATA
				tileBody->SetUserData(new CollidableObject(CollisionType::TILE));

				//We need to keep a reference to the body so that we can destroy it 
				//later when we no longer need it
				//--------WE NEED TO STORE THE TILE BODIES IN A DATA STRUCTURE HERE----//

				// Define the ground box shape.
				b2PolygonShape groundBox;

				// The extents are the half-widths of the box.
				groundBox.SetAsBox(tileWidthScaled, tileHeightScaled);

				// Add the ground fixture to the ground body.
				tileBody->CreateFixture(&groundBox, 0.0f);
			}
		}
	}
}
Ejemplo n.º 7
0
void Physics::addStaticRectangle(int x, int y, float width, float height)
{
	b2BodyDef bodyDef;

	//The bodyDef position is actually the position of the center of mass
	bodyDef.position.Set(pixelsToMeters(x + width/2),-pixelsToMeters(y + height/2));
	b2Body* body = box2DWorld->CreateBody(&bodyDef);
	
	b2FixtureDef fixtureDef;

	b2PolygonShape box;
	box.SetAsBox(pixelsToMeters(width/2), pixelsToMeters(height/2));
	fixtureDef.shape = &box;
	fixtureDef.friction = 0.3f;

	body->CreateFixture(&fixtureDef);
}
Ejemplo n.º 8
0
void Physics::update(Game *game)
{
	// Prepare for simulation. Typically we use a time step of 1/60 of a
	// second (60Hz) and 10 iterations. This provides a high quality simulation
	// in most game scenarios.
	float32 timeStep = 1.0f / 60.0f;
	int32 velocityIterations = 6;
	int32 positionIterations = 2;

	// This is our little game loop.
	for (int32 i = 0; i < 60; ++i)
	{
		// Instruct the world to perform a single step of simulation.
		// It is generally best to keep the time step and iterations fixed.
		box2DWorld->Step(timeStep, velocityIterations, positionIterations);
	}

	list<b2Body*>::iterator bodiesIterator;
	bodiesIterator = bodiesToDestroy.begin();
	while (bodiesIterator != bodiesToDestroy.end())
	{
		b2Body* body = *bodiesIterator;
		bodiesIterator++;
		box2DWorld->DestroyBody(body);
 	}
	bodiesToDestroy.clear();

	if(explosionThisFrame)
	{
		list<Explosion*>::iterator explosionsIterator;
		explosionsIterator = explosions.begin();
		while (explosionsIterator != explosions.end())
		{
			Explosion* explosion = *explosionsIterator;
			explosionsIterator++;

			int numRays = explosion->numOfRays;
			b2Vec2 center = explosion->explosionEpicenter;
			float blastRadius = explosion->blastRadius; 
			for (int i = 0; i < numRays; i++) 
			{
				float angle = (i / (float)numRays) * 360 * DEGTORAD;
				b2Vec2 rayDir( sinf(angle), cosf(angle) );
				b2Vec2 rayEnd = center + pixelsToMeters(blastRadius) * rayDir;

				//check what this ray hits
				ExplosionCallback callback;//basic callback to record body and hit point
				box2DWorld->RayCast(&callback, center, rayEnd);
				if ( callback.getClosestFixture() ) 
					applyBlastImpulse(callback.getClosestFixture()->GetBody(), center, callback.getImplusePoint(), (explosion->blastPower / (float)numRays));
			}
		}
		explosions.clear();
		explosionThisFrame = false;
	}
}
Ejemplo n.º 9
0
Bullet::Bullet(const sf::Vector2f& position, int direction, Game* game)
	: Entity(position, game, "bullet " + std::to_string(Id))
	, Speed(0.5f)
	, TextureWidth(16)
	, TextureHeight(16)
{
	++Id;

	sprite_.setTexture(game->getTextureManager().getTexture("spriteSheet"));
	sprite_.setTextureRect(sf::IntRect(0, 0, TextureWidth, TextureHeight));
	sprite_.setOrigin(sprite_.getLocalBounds().left + sprite_.getLocalBounds().width / 2.f, 
		sprite_.getLocalBounds().top + sprite_.getLocalBounds().height / 2.f);

	b2BodyDef bodyDef;
	bodyDef.position.Set(pixelsToMeters(position.x), pixelsToMeters(position.y));
	bodyDef.type = b2_dynamicBody;

	b2PolygonShape shape;
	shape.SetAsBox(pixelsToMeters(static_cast<float>(TextureWidth)) / 2.f,
		pixelsToMeters(static_cast<float>(TextureHeight)) / 2.f);

	body_ = game->getWorld()->CreateBody(&bodyDef);

	b2FixtureDef fixtureDef;
	fixtureDef.shape = &shape;
	fixtureDef.density = 1.f;
	fixtureDef.restitution = 0.f;
	fixtureDef.isSensor = true;

	body_->CreateFixture(&fixtureDef);
	body_->SetFixedRotation(true);
	body_->SetUserData(this);
	body_->SetGravityScale(0.f);
	body_->ApplyLinearImpulse(b2Vec2(Speed * direction, 0.f), body_->GetWorldCenter(), true);

	sprite_.setPosition(metersToPixels(body_->GetPosition().x), metersToPixels(body_->GetPosition().y));
}
Ejemplo n.º 10
0
void Physics::addCollidableObject(CollidableObject* co, float x, float y, int width, int height, float angle,
								  float density, float friction, bool fixedRotation, float gravityScale, bool isCircular)
{
	b2BodyDef bodyDef;
	bodyDef.type = b2_dynamicBody;
	//The bodyDef position is actually the position of the center of mass
	bodyDef.position.Set(pixelsToMeters(x + width/2),-pixelsToMeters(y + height/2));
	bodyDef.gravityScale = gravityScale;
	bodyDef.angle = angle;
	co->getPhysicalProperties()->rigidBody = box2DWorld->CreateBody(&bodyDef);
	b2Body *rigidBody = co->getPhysicalProperties()->rigidBody;
	rigidBody->SetUserData(co);
	
	b2FixtureDef fixtureDef;
	setCollisionFilters(co, &fixtureDef);

	b2PolygonShape box;
	b2CircleShape circle;
	if(!isCircular)
	{
		box.SetAsBox(pixelsToMeters(width/2), pixelsToMeters(height/2));
		fixtureDef.shape = &box;
	}
	else
	{
		//The circle shape should be centered over the body
		circle.m_p.Set(-pixelsToMeters(width/2),-pixelsToMeters(height/2));
		//Width and height should be equal, so it doesn't matter which we use here for the radius
		circle.m_radius = pixelsToMeters(width/2);
		fixtureDef.shape = &circle;
	}
	fixtureDef.density = density;
	fixtureDef.friction = friction;
	fixtureDef.restitution = .03f;
	co->getPhysicalProperties()->rigidBody->CreateFixture(&fixtureDef);
	co->getPhysicalProperties()->rigidBody->SetFixedRotation(fixedRotation);
	co->getPhysicalProperties()->setWidth(width);
	co->getPhysicalProperties()->setHeight(height);
}
Ejemplo n.º 11
0
void Ball::update(Uint32 deltaTime, AngularWall * wallAngle)
{
	BasePhysics::update(deltaTime);
	updateLabels(deltaTime);

	//Detect the collision with the ground
	if ((Ypos - ballRadius) < pixelsToMeters(10))
	{
		Ypos = pixelsToMeters(10.01) + ballRadius;
		Yvel = R *- Yvel;
		Xvel *= R;
	}

	//Collision detection with the right wall
	if ((Xpos + ballRadius) > pixelsToMeters(1490))
	{
		Xpos = pixelsToMeters(1489.99) - ballRadius;
		Yvel *= R;
		Xvel = R *- Xvel;
	}

	//Collision detection with the left wall
	if ((Xpos - ballRadius) < pixelsToMeters(10))
	{
		Xpos = pixelsToMeters(10.01) + ballRadius;
		Yvel *= R;
		Xvel = R *-Xvel;
	}

	//Collision detection against angular wall
	Vector2D pos(Xpos, Ypos);
	//For each side of the wall
	for (int i = 0; i < 4; i++)
	{
		//Get the start and end points of the line that represents this edge
		Vector2D start, end;
		wallAngle->getWallPoints(i, start, end);

		//Project the ball onto this line
		Vector2D point = GetClosestPointOnLineSegment(start, end, pos);

		float dist = (point - pos).length();

		// If the closest point on the line segment is within the bounds of our radius, then we have collided with it
		if (dist <= ballRadius)
		{
			Vector2D surfaceNormal = wallAngle->getSurfaceNormal(i);

			//Push the ball out so it isn't colliding anymore
			Vector2D newpos = point + (surfaceNormal * (ballRadius + pixelsToMeters(0.01)));
			Xpos = newpos.x;
			Ypos = newpos.y;

			//Since we have collided wih the wall, we need to bounce off it
			//To do so, we reflect the ball's velocity, around the wall's edge's surfacenormal
			//This code was adapted from: http://www.3dkingdoms.com/weekly/weekly.php?a=2
			Vector2D incoming(Xvel, Yvel);

			Vector2D result = surfaceNormal * incoming.dot(surfaceNormal);
			result *= -2.f;
			result += incoming;
			result *= R;

			Xvel = result.x;
			Yvel = result.y;
		}
	}
}