Пример #1
0
void Physics::Gravitation(Collision theCollision, PlayerObject *theCharacter)
{
	if (theCharacter->jumping == true)
	{
		this->upforce = this->upforce * 1.30;
	}

	if (this->upforce >0.8)
	{
		theCharacter->jumping = false;
	}

	if(theCollision.isGrounded())
	{
		this->onPlatform = true;
		this->downforce = 0.1;
	}
	if (!theCollision.isGrounded() || this->upforce > 0)
	{
		if (!theCollision.isGrounded())
		{
			this->downforce = this->downforce * 1.02;
		}
		theCharacter->Translate(0.0, (this->upforce - this->downforce)/2, 0.0);
		theCharacter->yPos += (this->upforce - this->downforce)/2;
	}

	if (this->upforce > 0)
	{
		this->upforce -= this->downforce / 9;
	}
}
Пример #2
0
/*
	When we resolve a collision involving a sprite other collisions
	involving it are then obsolete, so this method removes them.
*/
void Physics::removeActiveCOCollisions(CollidableObject *co)
{
	list<Collision*>::iterator coIt = activeCollisions.begin();
	while (coIt != activeCollisions.end())
	{
		// WE'LL NEED THIS TO REMOVE THE ELEMENT
		list<Collision*>::iterator tempIt = coIt;

		// BUT WE'LL MOVE THE ITERATOR ALONG NOW FOR THE NEXT LOOP
		coIt++;

		// GET THE COLLISION WE MAY NEED TO REMOVE
		if (tempIt != activeCollisions.end())
		{
			Collision *c = (*tempIt);

			// AND TEST IT
			if ((co == c->getCO1()) || (co == c->getCO2()))
			{
				// RECYCLE THE COLLIDABLE OBJECTS IF NECESSARY
				if (c->isCollisionWithTile())
				{
					recycledCollidableObjectsList.push_back(c->getCO2());
				}				

				// PUT IT BACK IN THE RECYCLING BIN
				recycledCollisions.push_back(c);		

				// AND REMOVE IT FROM THE LIST
				activeCollisions.erase(tempIt);
			}
		}
	}
}
Пример #3
0
bool World::makeCollision(const b2Fixture& fix, Collision& c) const
{
	if (!mBounds) return false;
	if (fix.GetBody() != mBounds) return false;

	if (fix.GetUserData() == BOUNDS_LEFT_PTR) c.setToWorldBounds(Collision::LEFT);
	else if (fix.GetUserData() == BOUNDS_TOP_PTR) c.setToWorldBounds(Collision::TOP);
	else if (fix.GetUserData() == BOUNDS_RIGHT_PTR) c.setToWorldBounds(Collision::RIGHT);
	else if (fix.GetUserData() == BOUNDS_BOTTOM_PTR) c.setToWorldBounds(Collision::BOTTOM);
	else return false;

	return true;
}
Пример #4
0
void Scene::checkCollisions()
{
    for (std::vector<RigidBody *>::iterator itA = _bodies.begin() ; itA != _bodies.end(); ++itA) {
        for (std::vector<RigidBody *>::iterator itB = itA + 1 ; itB != _bodies.end(); ++itB) {

            Collision *collision = new Collision(*itA, *itB);
            CollisionPair *cp = collision->dispatcher();

            if (cp != NULL) {
                _collisions.push_back(cp);
            }
        }
    }
}
Пример #5
0
Collision ScriptTrigger::hitBy(Collidable* other) {
	Collision c;
	
	c = GameObject::hitBy(other);
	if(!script()->isRunning()) {
		if(c.collided()) {
			// Call onHit via the script engine.
			script()->callFunction(*this, (char*)"onHit", "o", (ScriptableObject*)other);
		}
	}

	// No collision if script is running
	return c;
}
Пример #6
0
void Physics::addCollisionSpriteSprite(CollidableObject *dynamicObjectA, CollidableObject *dynamicObjectB)
{
    // IF WE'VE ALREADY HANDLED A COLLISION BETWEEN THESE TWO OBJECTS THIS
    // FRAME THEN IGNORE IT
    //PAULO- MAYBE IMPORTANT***********************
    /*set<CollidableObject*> doSprite = spriteToSpriteCollisionsThisFrame[dynamicObjectB];
    if (doSprite.find(dynamicObjectB) != doSprite.end())
    return;*/



    // FIRST WE'RE GOING TO DO A MORE NARROW CHECK TO SEE IF THE dynamicObject
    // REALLY DOES COLLIDE WITH THE TILE. TO DO SO WE'LL CALCULATE THE TIME
    // OF COLLISION. IF IT HAPPENS AFTER THIS FRAME IS OVER (> 1), THEN WE
    // WILL IGNORE IT
    unsigned int co1Edge, co2Edge;
    float timeUntilCollision = calculateTimeUntilCollision(dynamicObjectA,dynamicObjectB, co1Edge, co2Edge, 0.0f);
    if (timeUntilCollision > 1.0f)
        return;



    //// NOW LET'S MAKE A COLLISION FOR THE SPRITE-SPRITE
    Collision *collisionToAdd = recycledCollisions.back();
    collisionToAdd->setCO1(dynamicObjectA);
    collisionToAdd->setCO2(dynamicObjectB);
    collisionToAdd->setCO1Edge(co1Edge);
    collisionToAdd->setCO2Edge(co2Edge);
    collisionToAdd->setCollisionWithSprite(true);
    collisionToAdd->setCollisionWithTile(false);
    collisionToAdd->setTimeOfCollision(timeUntilCollision);
    //collisionToAdd->setTile(tile);
    recycledCollisions.pop_back();
    activeCollisions.push_back(collisionToAdd);
}
Пример #7
0
void Tile::Render(Textures* textures, SDL_Rect* clips, SDL_Renderer* Renderer, SDL_Rect* camera)
{
    if(collision.CheckCollision(TileBox, *camera))
    {
        textures->Render(Renderer, TileBox.x - camera->x, TileBox.y - camera->y, &clips[TileType]);
    }
}
Пример #8
0
void makeFence(Level* level, const NewtonWorld* newtonWorld)
{
    CollisionSet fencePartsCollisions;
    fencePartsCollisions.insert(level->getCollision("fence"));
    //fencePartsCollisions.insert(level->getCollision("fenceClip1"));
    //fencePartsCollisions.insert(level->getCollision("fenceClip2"));
    fencePartsCollisions.insert(level->getCollision("fenceTop"));

    Collision* heightMap = level->getCollision("level");

    for (size_t fencesVectorIdx = 0; fencesVectorIdx < level->m_fences.size(); fencesVectorIdx++)
    {
        const vector<Vector>& fence = level->m_fences[fencesVectorIdx];
        for (size_t i = 0; i < fence.size() - 1; i++)
        {    
            const Vector startPoint = fence[i];
            const Vector endPoint = fence[i + 1];
            Vector delta(endPoint - startPoint);
            const Vector rotation(0, - delta.getRotationY(), 0);
            
            float howMany = delta.magnitude() / fenceSpacing;
            delta /= howMany;
            for (int j = 0; j < howMany; j++)
            {
                const string bodyID = "fence" + cast<string>(fencesVectorIdx) + "_" + cast<string>(i) + "_" + cast<string>(j);

                Body* body = new Body(bodyID, level, fencePartsCollisions);
                if (Network::instance->m_isSingle == false)
                {
                    NewtonBodySetMassMatrix(body->m_newtonBody, 0, 0, 0, 0);
                }
                body->m_soundable = true;

                Vector position = Vector(startPoint + delta * static_cast<float>(j));
                position.y = fenceHeight / 2 + heightMap->getHeight(position.x, position.z) + 0.05f;
                body->setTransform(position, rotation);

                NewtonWorldFreezeBody(newtonWorld, body->m_newtonBody);
                NewtonBodySetAutoFreeze(body->m_newtonBody, 1);

                level->m_bodies[bodyID] = body;
            }
        }
    }
}
Пример #9
0
void GameWindow::addCollision(const Vector3d& p, const Vector3d& n)
{
  Collision* c = 0;
  for(unsigned int i = 0; i < cMaxCollisions; ++i)
    if(mCollisions[i]->isDone())
    { c = mCollisions[i]; break; }

  if(c)
  {
    Matrix4d m;
    m.setTranslation(toPoint(p));
    c->setTransformationToGlobal(m);
    double a = atan2(n.getY(), n.getX());
    c->setAngle(a);
    c->setNormal(n);
    c->animate();
  }
}
void Physics::BuildCollision( const char* pUserString, CIwModel* pModel )
{
	// Check user string to test whether to affect this asset
	if( strcmp( pUserString, "collision" ) != 0 )
	{
		return;
	}
	
	// Create a new collision resource and name it after its model partner
	Collision* pCollision = new Collision;
	pCollision->SetName( pModel->DebugGetName() );

	for( uint32 i = 0; i < IwGetModelBuilder()->GetNumFaces(); ++i )
	{
		pCollision->AddFace( IwGetModelBuilder()->GetFace( i ), pModel );
	}

	// Add the collision resource to IwResManager - it will be serialised as part of the current group.
	IwGetResManager()->AddRes( "Collision", pCollision );
}
Пример #11
0
void Engine::RenderFrame()
{	    
	Collision checker; //DELETE
	//Camera offsets
	int camOffsetX, camOffsetY;

	Tile* tile;
	window->clear();
	
	//Get the tile bounds we need to draw
	sf::IntRect bounds = camera->GetTileBounds(tileSize);

	//Figure out how much to offset each tile
	camOffsetX = camera->GetTileOffset(tileSize).x;
	camOffsetY = camera->GetTileOffset(tileSize).y;
	//Loop through and draw each tile
	//We're keeping track of two variables in each loop. How many tiles
	//we've drawn (x and y), and which tile on the map we're drawing (tileX
	//and tileY)
	player->ground = false;	
	for(int y = 0, tileY = bounds.top; y < bounds.height; y++, tileY++)
	{
		for(int x = 0, tileX = bounds.left; x < bounds.width; x++, tileX++)
		{
			tile = new Tile(TextureManager.GetTexture(0)); // background!
			tile->Draw((x * tileSize) - camOffsetX, (y * tileSize) - camOffsetY, window);
			//Get the tile	
			tile = currentLevel->GetTile(tileX, tileY);
			if(tile){
 				tile->Draw((x * tileSize) - camOffsetX, (y * tileSize) - camOffsetY, window);
				if(checker.RectCollide(sf::FloatRect((x * tileSize), (y * tileSize), tileSize, tileSize), sf::FloatRect((player->getPosition().left), (player->getPosition().top), tileSize, tileSize)) && tile->baseSprite.getTexture() == Tile(TextureManager.GetTexture(2)).baseSprite.getTexture()){
				player->ground = true;
				}				
			}
					
		}
	}
	
	player->Draw(camOffsetX, camOffsetY, window);
	window->display();
}
Пример #12
0
Entity* StaticBlock::prepareEntity(PropertyManager& parameters) {
    Entity* entity = new Entity();

    Collision* colli = new Collision();
    sf::Vector2f pos = parameters.Get<sf::Vector2f>("Position");
    Position* position = new Position();
    position->updatePosition(pos.x, pos.y);

    sf::Transformable transform = position->getPosition();
    colli->update(transform);
    colli->setArrayVertex(parameters.Get<sf::VertexArray*>("Vertex"));
    colli->applyRatio(parameters.Get<sf::Vector2f>("Ratio"));
    colli->setType(TypeCollision::STATIC);

    position->setPosition(colli->getTransform());

    entity->Add<Position*>("Position", position);
    entity->Add<Collision*>("Collision", colli);

    entity->Add<Collision*>("Debug", colli);

    OnCollision* onCollision = new OnCollision();
    makeOnCollision(entity->getId(), onCollision);
    entity->Add<OnCollision*>("OnCollision", onCollision);

    return entity;
}
Пример #13
0
/*
Called when a collision is detected between a world tile
and a sprite, this records that collision so that it
can be resolved later if needed.
*/
void Physics::addTileCollision(CollidableObject *dynamicObject, Tile *tile, float tileX, float tileY, float tileWidth, float tileHeight)
{
    // IF WE'VE ALREADY HANDLED A COLLISION BETWEEN THESE TWO OBJECTS THIS
    // FRAME THEN IGNORE IT
    set<Tile*> doTiles = spriteToTileCollisionsThisFrame[dynamicObject];
    if (doTiles.find(tile) != doTiles.end())
        return;

    // GET A DUMMY COLLIDABLE OBJECT TO USE FOR THE TILE
    CollidableObject *tileInfoForCollision = recycledCollidableObjectsList.back();

    // FILL IT WITH DATA
    AABB *bv = tileInfoForCollision->getBoundingVolume();
    bv->setCenterX(tileX + (tileWidth/2));
    bv->setCenterY(tileY + (tileHeight/2));
    bv->setWidth(tileWidth);
    bv->setHeight(tileHeight);

    // FIRST WE'RE GOING TO DO A MORE NARROW CHECK TO SEE IF THE dynamicObject
    // REALLY DOES COLLIDE WITH THE TILE. TO DO SO WE'LL CALCULATE THE TIME
    // OF COLLISION. IF IT HAPPENS AFTER THIS FRAME IS OVER (> 1), THEN WE
    // WILL IGNORE IT
    unsigned int co1Edge, co2Edge;
    float timeUntilCollision = calculateTimeUntilCollision(dynamicObject, tileInfoForCollision, co1Edge, co2Edge, 0.0f);
    if (timeUntilCollision > 1.0f)
        return;

    // IF IT MADE IT HERE, A COLLISION IS HAPPENING
    // AND REMOVE IT FROM THE RECYCLING CENTER
    recycledCollidableObjectsList.pop_back();

    // NOW LET'S MAKE A COLLISION FOR THE TILE-SPRITE
    Collision *collisionToAdd = recycledCollisions.back();
    collisionToAdd->setCO1(dynamicObject);
    collisionToAdd->setCO2(tileInfoForCollision);
    collisionToAdd->setCO1Edge(co1Edge);
    collisionToAdd->setCO2Edge(co2Edge);
    collisionToAdd->setCollisionWithSprite(false);
    collisionToAdd->setCollisionWithTile(true);
    collisionToAdd->setTimeOfCollision(timeUntilCollision);
    collisionToAdd->setTile(tile);
    recycledCollisions.pop_back();
    activeCollisions.push_back(collisionToAdd);
}
Пример #14
0
int Program::main(const std::vector<CL_String> &args)
{
	try
	{
		// Initialize ClanLib base components
		CL_SetupCore setup_core;

		// Initialize the ClanLib display component
		CL_SetupDisplay setup_display;

		#ifdef USE_SOFTWARE_RENDERER
			CL_SetupSWRender setup_swrender;
		#endif

		#ifdef USE_OPENGL_1
			CL_SetupGL1 setup_gl1;
		#endif

		#ifdef USE_OPENGL_2
			CL_SetupGL setup_gl;
		#endif

		// Start the Application
		Collision app;
		int retval = app.start(args);
		return retval;
	}
	catch(CL_Exception &exception)
	{
		// Create a console window for text-output if not available
		CL_ConsoleWindow console("Console", 80, 160);
		CL_Console::write_line("Exception caught: " + exception.get_message_and_stack_trace());
		console.display_close_message();

		return -1;
	}
}
bool RoundCollision::checkAABBCollision(Collision other) {
    if (loc.getX() + raduis >= other.getLocation().getX() + other.getwidth() && loc.getX() - raduis <= other.getLocation().getX() - other.getwidth()) {
        if (loc.getZ() + raduis >= other.getLocation().getZ() + other.getlength() && loc.getZ() - raduis <= other.getLocation().getZ() - other.getlength()) {
            if (loc.getY() + raduis >= other.getLocation().getY() + other.getheight() && loc.getY() - raduis <= other.getLocation().getY() - other.getheight()) {
                return true;
            }
        }
    }
    return false;
}
Пример #16
0
void ContactListener::makeCollision(const ContactKey& key, Collision& collision) const
{
	collision.mContactOne = mWorld.box2CiTranslation(key.mContactPointOne, nullptr); // nullptr for sprite will make contacts in world space
	collision.mContactTwo = mWorld.box2CiTranslation(key.mContactPointTwo, nullptr); // so assume that all contacts are world space position
	collision.mNormal = ci::Vec2f(key.mNormal.x, key.mNormal.y);

	// I *think* the sprite in the key can be ignored, because technically it should
	// always be the object receiving the callback (although I bet I have some details
	// to work out when it comes to sprites colliding with each other).
	// That means it's the fixture I care about.
	if (!key.mFixture) return;
	if (mWorld.makeCollision(*key.mFixture, collision)) return;

	const b2Body*			b = key.mFixture->GetBody();
	ds::ui::Sprite*			sprite = reinterpret_cast<ds::ui::Sprite*>(b ? b->GetUserData() : nullptr);
	if (sprite) collision.setToSprite(sprite->getId());
}
Пример #17
0
bool parseCollision(Collision &col, TiXmlElement* config)
{
  col.clear();

  // Origin
  TiXmlElement *o = config->FirstChildElement("origin");
  if (o) {
    if (!parsePose(col.origin, o))
      return false;
  }

  // Geometry
  TiXmlElement *geom = config->FirstChildElement("geometry");
  col.geometry = parseGeometry(geom);
  if (!col.geometry)
    return false;

  const char *name_char = config->Attribute("name");
  if (name_char)
    col.name = name_char;

  return true;
}
Пример #18
0
  void PListener::BeginContact(b2Contact* contact){
    void* udA = contact->GetFixtureA()->GetBody()->GetUserData();
    Collision* A = nullptr;
    if(udA){
      A = static_cast<Collision*>(udA);
    }

    void* udB = contact->GetFixtureB()->GetBody()->GetUserData();
    Collision* B = nullptr;
    if(udB) {
      B = static_cast<Collision*>(udB);
    }
    
    if(A != nullptr && B != nullptr){
      if((A->type() & CollisionType::DYNAMIC) > 0 && (B->type() & CollisionType::STATIC) > 0){
	A->actor()->beginContact(B);
      } else {
	B->actor()->beginContact(A);
      }
    }
  }
bool PhysicsManager::IsCollisionActive(Collision* collision)
{
	for (unsigned int i = 0; i < activeCollisions.size(); i++)
	{
		Collision* activeCollision = activeCollisions[i];

		if (activeCollision->getThisObject() == collision->getThisObject() &&
			activeCollision->getOtherObject() == collision->getOtherObject())
			return true;
	}

	for (unsigned int i = 0; i < lastFrameActiveCollisions.size(); i++)
	{
		Collision* activeCollision = lastFrameActiveCollisions[i];

		if (activeCollision->getThisObject() == collision->getThisObject() &&
			activeCollision->getOtherObject() == collision->getOtherObject())
			return true;
	}

	return false;
}
Пример #20
0
/*
	This is where all game physics starts each frame. It is called each frame 
	by the game statem manager after player input and AI have been processed. It
	updates the physical state of all dynamic objects in the game and
	moves all objects to their end of frame positions, updates all necessary
	object velocities, and calls all collision event handlers.
*/
void Physics::update(Game *game)
{
	// WE'LL USE A CONTINUOUS COLLISION SYSTEM TO ENSURE TEMPORAL 
	// COHERENCE, WHICH MEANS WE'LL MAKE SURE COLLISIONS ARE RESOLVED
	// IN THE ORDER WITH WHICH THEY HAPPEN. WE DON'T WANT GAME EVENTS
	// TO APPEAR TO HAPPEN IN THE WRONG ORDER. WE'LL TRY TO MAKE IT
	// A LITTLE MORE EFFICIENT BY EMPLOYING A VARIATION ON THE
	// SWEEP AND PRUNE ALGORITHM FOR DYNAMIC-DYNAMIC OBJECT COLLISIONS

	// IN CASE WE'RE DOING THE ONE UPDATE STEP AT A TIME
	// THIS MAKES SURE THE UPDATE DOESN'T GET CALLED AGAIN
	// NEXT FRAME WITHOUT THE USER EXPLICITY REQUESTING IT
	// BY PRESSING THE 'T' KEY (for Time sTep)
	activatedForSingleUpdate = false;

	// WE'LL NEED THE WORLD TO ACCESS THE SPRITES AND WORLD LAYERS
	GameStateManager *gsm = game->getGSM();
	World *world = gsm->getWorld();

	// NOTE THAT WE MAKE SURE THE activeCollisions VECTOR IS
	// EMPTIED BEFORE THIS METHOD EXITS, SO WE CAN ASSUME
	// IT'S EMPTY NOW. activeCollisions CONTAINS ALL THE COLLISIONS
	// DETECTED SO FAR THIS FRAME. THESE ARE THE THINGS WE MUST
	// RESOLVE.

	// START THE CLOCK AT 0, THAT MEANS 0% OF THE WAY THROUGH THE FRAME.
	// NOTE THAT TIME 0 IS THE MOST DANGEROUS TIME FOR DETECTING COLLISIONS
	// BECAUSE THEY CAN BE EASILY OVERLOOKED. THE SAME FOR SIMULTANEOUS 
	// COLLISIONS. TO MINIMIZE RIGID BODY PENETRATION, SUCH CIRCUMSTANCES
	// ARE TYPICALLY HANDLED AS SPECIAL CASES
	currentCollisionTime = 0.0f;

	// FIRST WE NEED TO DO COLLISION TESTING PREP WORK FOR SPRITES
		// APPLY ACCELERATION AND GRAVITY TO VELOCITY
		// INIT TILE COLLISION INFO
			// SET ON TILE LAST FRAME USING ON TILE THIS FRAME
			// SET ON TILE THIS FRAME TO FALSE	
		// GET COLLISIONS WITH ALL TILES TO HAPPEN DURING THIS FRAME
			// PUT THESE COLLISIONS INTO A SORTABLE DATA STRUCTURE
		// INIT SPRITE'S SWEPT SHAPE INFO

	// FOR ALL SPRITES, INCLUDING THE BOTS AND PLAYER
	vector<CollidableObject*>::iterator spritesIt = sortedSweptShapes[LEFT_EDGE]->begin();
	while (spritesIt != sortedSweptShapes[LEFT_EDGE]->end())
	{
		CollidableObject *sprite = (*spritesIt);
		prepSpriteForCollisionTesting(world, sprite);
		getAllTileCollisionsForAGivenSprite(world, sprite, 1.0f);
		spritesIt++;
	}

	// PREPARE FOR SPRITE-SPRITE COLLISION TESTING

		// SWEEP AND PRUNE DATA STRUCTURES PREP WORK
			// SORT S_AND_P VECTOR SORTED BY START X OF SWEPT SHAPE
			// SORT S_AND_P VECTOR SORTED BY END X OF SWEPT SHAPE
			// WE DON'T NEED THE Y-AXIS SORTED, BUT WOULD IF THIS
			// WERE A 3D SYSTEM TO SAVE ON COMPARISONS.

	// WE'RE USING C++'s STL sort METHOD AND ARE PROVIDING
	// A CUSTOM MEANS FOR COMPARISON
	sort(sortedSweptShapes[LEFT_EDGE]->begin(),		sortedSweptShapes[LEFT_EDGE]->end(),	SweptShapesComparitorByLeft());
	sort(sortedSweptShapes[RIGHT_EDGE]->begin(),	sortedSweptShapes[RIGHT_EDGE]->end(),	SweptShapesComparitorByRight());
		
	// RECORD SORTED POSITIONS WITH EACH SPRITE. THEY NEED TO KNOW WHERE
	// THEY ARE IN THOSE DATA STRUCTURES SUCH THAT WE CAN JUMP INTO
	// THOSE DATA STRUCTURES TO TEST COLLISIONS WITH NEIGHBORS
	updateSweptShapeIndices();

	// YOU'LL NEED TO TEST FOR SPRITE-TO-SPRITE COLLISIONS HERE

	// *** LOOP STARTS HERE. WE'LL DO THIS UNTIL THERE ARE NO
	// MORE COLLISIONS TO RESOLVE FOR THIS FRAME
	while (activeCollisions.size() > 0)
	{
		// SORT COLLISION OBJECTS BY TIME OF COLLISION
		// NOTE THAT I'M JUST EMPLOYING THE STL'S List
		// CLASS' SORT METHOD BY PROVIDING MY OWN
		// MEANS FOR COMPARING Collision OBJECTS
		activeCollisions.sort(CollisionComparitor());

		// GET FIRST COLLISION - NOTE THAT WE HAVE THE COLLISIONS SORTED
		// IN DESCENDING ORDER, SO TO TAKE THE EARLIEST ONE, WE REMOVE IT
		// FOM THE BACK OF THE SORTED LIST
		Collision *earliestCollision = activeCollisions.back();
		activeCollisions.pop_back();
		float collisionTime = earliestCollision->getTimeOfCollision();

		// MOVE ALL SPRITES UP TO TIME OF FIRST COLLISION USING
		// APPROPRIATELY SCALED VELOCITIES
		moveAllSpritesUpToBufferedTimeOfCollision(earliestCollision);

		// AND ADVANCE COLLISION TIME
		currentCollisionTime = collisionTime;

		// AND UPDATE THE VELOCITIES OF THE SPRITE(S) INVOLVED IN THE COLLISION
		performCollisionResponse(earliestCollision);

		// EXECUTE COLLISION EVENT CODE
		// TEST TO SEE TYPES OF OBJECTS AND APPROPRIATE RESPONSE
		// ACCORDING TO CUSTOMIZED COLLISION EVENT HANDLER
		collisionListener->respondToCollision(game, earliestCollision);

		// FOR THE TWO OBJECTS INVOLVED IN THE COLLISION
			// REMOVE ALL OTHER COLLISIONS INVOLVING THEM
			// SINCE THEY ARE NOW OBSOLETE. THE REASON BEING
			// THE OBJECT COLLISION NOW LIKELY HAS A 
			// DIFFERENT VECTOR
			// UPDATE THEIR SWEPT SHAPES
			// TEST THEM AGAINST TILES AGAIN
		CollidableObject *co1 = earliestCollision->getCO1();
		CollidableObject *co2 = earliestCollision->getCO2();
		removeActiveCOCollisions(co1);
 		co1->updateSweptShape(1.0f - currentCollisionTime);
		getAllTileCollisionsForAGivenSprite(world, co1, 1.0f - currentCollisionTime);

		// ONLY DO IT FOR THE SECOND ONE IF IT'S NOT A TILE
		if (!earliestCollision->isCollisionWithTile())
		{
			removeActiveCOCollisions(co2);
			co2->updateSweptShape(1.0f - currentCollisionTime);
			getAllTileCollisionsForAGivenSprite(world, co2, 1.0f - currentCollisionTime);
		}
		else
		{
			spriteToTileCollisionsThisFrame[co1].insert(earliestCollision->getTile());
			recycledCollidableObjectsList.push_back(co2);
		}
		
		// NOW WE NEED TO SEE IF THE SPRITES INVOLVED IN THE JUST
		// RESOLVED COLLISION ARE GOING TO BE INVOLVED IN ANY MORE
		// WITH OTHER SPRITES BUT WE DON'T WANT TO CHECK ALL OF THEM,
		// WE ONLY WANT TO CHECK NEIGHBORS, BUT FIRST WE HAVE TO
		// MAKE SURE THE SPRITE(S) THAT WE JUST RESOLVED ARE IN THEIR
		// PROPER SWEPT SHAPE LOCATIONS WITHOUT HAVING TO RESORT EVERTYHING

		// IF IT WAS ONLY ONE SPRITE WITH A TILE THIS IS EASY TO DO
		if (earliestCollision->isCollisionWithTile())
		{
			reorderCollidableObject(co1);
		}
		// YOU'LL HAVE TO WORRY ABOUT REORDERING STUFF FOR COLLISIONS
		// BETWEEN TWO SPRITES
		
		// NOW TEST NEIGHBORS OF SPRITES INVOLVED IN RESOLVED COLLISION
		// AGAINST NEIGHBORS IN SWEPT SHAPE DATA STRUCTURES. YOU'LL HAVE
		// TO FIGURE OUT HOW TO DO THIS AND HOW TO RESOLVE SUCH COLLISIONS
			
		// RECYCLE THE COLLISION SINCE WE'RE NOW DONE WITH IT
		recycledCollisions.push_back(earliestCollision);
	}

	// APPLY THE REMAINING TIME TO MOVE THE SPRITES. NOTE THAT
	// THIS IS ACTUALLY A VERY RISKY, TRICKY STEP BECAUSE IT COULD
	// MOVE OBJECTS ALMOST TO THE POINT OF COLLISION, WHICH MAY THEN
	// BE DETECTED ALMOST AT TIME 0 NEXT FRAME. THERE ARE OTHER TRICKY
	// ISSUES RELATED TO OUR BUFFER AS WELL, SO WE CHEAT A LITTLE HERE
	// AND SCALE THE TIME REMAINING DOWN A LITTE
	if (currentCollisionTime < 1.0f)
		moveAllSpritesToEndOfFrame();

	// INIT TILE COLLISION INFO
	// SET ON TILE LAST FRAME USING ON TILE THIS FRAME
	// SET ON TILE THIS FRAME TO FALSE
	spritesIt = sortedSweptShapes[LEFT_EDGE]->begin();
	while (spritesIt != sortedSweptShapes[LEFT_EDGE]->end())
	{
		CollidableObject *sprite = (*spritesIt);
		sprite->advanceOnTileStatus();
		spritesIt++;
	}

	// WE'RE NOT GOING TO ALLOW MULTIPLE COLLISIONS TO HAPPEN IN A FRAME
	// BETWEEN THE SAME TWO OBJECTS
	spriteToTileCollisionsThisFrame.clear();
}
Пример #21
0
void State::updateObject(dur elapsedTime) {
	// Store current map in case of switch
	GameMap* current_map = m_map;

	if(!enabled) {
		return;
	}

	assert(engine() != NULL);

	// Process input controller
	if(engine()->hardware()) {
		processInput();
	}

	if(!frameCounter) {
		return;
	} else {
		if(frameCounter > 0) {
			frameCounter--;
		}
	}

	// Run scripts
	if(script()->isRunning()) {
		script()->framestep();
	}

	// Update map
	if(current_map != NULL) {
		// Make the cameraman work
		if(cameraman) {
			cameraman->update(elapsedTime);
			current_map->setPosition(cameraman->getCameraPosition());
		}

		// Center map
		if(camTarget) {
			int targetX;
			int targetY;
			int camX;
			int camY;
			int curX;
			int curY;
			int localMaxCamSpeed = maxCamSpeed * elapsedTime;

			// Compute actual target coordinates
			if(camSecondaryTarget) {
				targetX = (camTarget->getX() + camSecondaryTarget->getX()) / 2;
				targetY = (camTarget->getY() + camSecondaryTarget->getY()) / 2;
			} else {
				targetX = camTarget->getX();
				targetY = camTarget->getY();
			}
			// Smooth object switching
			if(camSwitching) {
				camX = (-current_map->getX() * 3 + targetX) / 4;
				camY = (-current_map->getY() * 3 + targetY) / 4;
				curX = current_map->getX();
				curY = current_map->getY();
			} else {
				camX = targetX;
				camY = targetY;
				curX = camX;
				curY = camY;
			}
			// Limit camera speed
			if(camX + current_map->getX() > localMaxCamSpeed) {
				camX = -current_map->getX() + localMaxCamSpeed;
			} else if(-current_map->getX() - camX > localMaxCamSpeed) {
				camX = -current_map->getX() - localMaxCamSpeed;
			}
			if(camY + current_map->getY() > localMaxCamSpeed) {
				camY = -current_map->getY() + localMaxCamSpeed;
			} else if(-current_map->getY() - camY > localMaxCamSpeed) {
				camY = -current_map->getY() - localMaxCamSpeed;
			}

			// set camera position
			current_map->setPosition(-camX, -camY);
			// test if object switching is finished
			if(camSwitching) {
				if(abs(camX - targetX) < 5 && abs(camY - targetY) < 5) {
					camSwitching = false;
				} else if((curX == current_map->getX()) && (curY == current_map->getY())) {
					camSwitching = false;
				}
			}
		}

		// Update map
		current_map->update(elapsedTime);

		// Update mouse cursor
#ifdef MOUSE_SUPPORT
		if(mouseCursor) {
			Collidable* current_mouse = mouseCursor;
			current_mouse->update(elapsedTime);

			Collision c = current_mouse->hitBy(current_map);
			if(c.collided()) {
				current_map->signal(current_mouse, MOUSE_MOVE, 0);
			}

			if(m_hud) {
				c = current_mouse->hitBy(m_hud);
				if(c.collided()) {
					m_hud->signal(current_mouse, MOUSE_MOVE, 0);
				}
			}
		}
#endif
	}

	// Update hud
	if(m_hud != NULL) {
		m_hud->update(elapsedTime);
	}
}
Пример #22
0
/*
This is where all game physics starts each frame. It is called each frame 
by the game statem manager after player input and AI have been processed. It
updates the physical state of all dynamic objects in the game and
moves all objects to their end of frame positions, updates all necessary
object velocities, and calls all collision event handlers.
*/
void Physics::update(Game *game)
{
	// WE'LL USE A CONTINUOUS COLLISION SYSTEM TO ENSURE TEMPORAL 
	// COHERENCE, WHICH MEANS WE'LL MAKE SURE COLLISIONS ARE RESOLVED
	// IN THE ORDER WITH WHICH THEY HAPPEN. WE DON'T WANT GAME EVENTS
	// TO APPEAR TO HAPPEN IN THE WRONG ORDER. WE'LL TRY TO MAKE IT
	// A LITTLE MORE EFFICIENT BY EMPLOYING A VARIATION ON THE
	// SWEEP AND PRUNE ALGORITHM FOR DYNAMIC-DYNAMIC OBJECT COLLISIONS

	// IN CASE WE'RE DOING THE ONE UPDATE STEP AT A TIME
	// THIS MAKES SURE THE UPDATE DOESN'T GET CALLED AGAIN
	// NEXT FRAME WITHOUT THE USER EXPLICITY REQUESTING IT
	// BY PRESSING THE 'T' KEY (for Time sTep)
	activatedForSingleUpdate = false;

	// WE'LL NEED THE WORLD TO ACCESS THE SPRITES AND WORLD LAYERS
	GameStateManager *gsm = game->getGSM();
	World *world = gsm->getWorld();

	// NOTE THAT WE MAKE SURE THE activeCollisions VECTOR IS
	// EMPTIED BEFORE THIS METHOD EXITS, SO WE CAN ASSUME
	// IT'S EMPTY NOW. activeCollisions CONTAINS ALL THE COLLISIONS
	// EMPTIED BEFORE THIS METHOD EXITS, SO WE CAN ASSUME
	// IT'S EMPTY NOW. activeCollisions CONTAINS ALL THE COLLISIONS
	// DETECTED SO FAR THIS FRAME. THESE ARE THE THINGS WE MUST
	// RESOLVE.

	// START THE CLOCK AT 0, THAT MEANS 0% OF THE WAY THROUGH THE FRAME.
	// NOTE THAT TIME 0 IS THE MOST DANGEROUS TIME FOR DETECTING COLLISIONS
	// BECAUSE THEY CAN BE EASILY OVERLOOKED. THE SAME FOR SIMULTANEOUS 
	// COLLISIONS. TO MINIMIZE RIGID BODY PENETRATION, SUCH CIRCUMSTANCES
	// ARE TYPICALLY HANDLED AS SPECIAL CASES
	currentCollisionTime = 0.0f;

	// FIRST WE NEED TO DO COLLISION TESTING PREP WORK FOR SPRITES
	// APPLY ACCELERATION AND GRAVITY TO VELOCITY
	// INIT TILE COLLISION INFO
	// SET ON TILE LAST FRAME USING ON TILE THIS FRAME
	// SET ON TILE THIS FRAME TO FALSE	
	// GET COLLISIONS WITH ALL TILES TO HAPPEN DURING THIS FRAME
	// PUT THESE COLLISIONS INTO A SORTABLE DATA STRUCTURE
	// INIT SPRITE'S SWEPT SHAPE INFO

	// FOR ALL SPRITES, INCLUDING THE BOTS AND PLAYER
	vector<CollidableObject*>::iterator spritesIt = sortedSweptShapes[LEFT_EDGE]->begin();
	while (spritesIt != sortedSweptShapes[LEFT_EDGE]->end())
	{
		CollidableObject *sprite = (*spritesIt);
		prepSpriteForCollisionTesting(world, sprite);
		getAllTileCollisionsForAGivenSprite(world, sprite, 1.0f);
		spritesIt++;
	}

	// PREPARE FOR SPRITE-SPRITE COLLISION TESTING

	// SWEEP AND PRUNE DATA STRUCTURES PREP WORK
	// SORT S_AND_P VECTOR SORTED BY START X OF SWEPT SHAPE
	// SORT S_AND_P VECTOR SORTED BY END X OF SWEPT SHAPE
	// WE DON'T NEED THE Y-AXIS SORTED, BUT WOULD IF THIS
	// WERE A 3D SYSTEM TO SAVE ON COMPARISONS.

	// WE'RE USING C++'s STL sort METHOD AND ARE PROVIDING
	// A CUSTOM MEANS FOR COMPARISON
	sort(sortedSweptShapes[LEFT_EDGE]->begin(),		sortedSweptShapes[LEFT_EDGE]->end(),	SweptShapesComparitorByLeft());
	sort(sortedSweptShapes[RIGHT_EDGE]->begin(),	sortedSweptShapes[RIGHT_EDGE]->end(),	SweptShapesComparitorByRight());

	// RECORD SORTED POSITIONS WITH EACH SPRITE. THEY NEED TO KNOW WHERE
	// THEY ARE IN THOSE DATA STRUCTURES SUCH THAT WE CAN JUMP INTO
	// THOSE DATA STRUCTURES TO TEST COLLISIONS WITH NEIGHBORS
	updateSweptShapeIndices();

	// YOU'LL NEED TO TEST FOR SPRITE-TO-SPRITE COLLISIONS HERE

	// *** LOOP STARTS HERE. WE'LL DO THIS UNTIL THERE ARE NO
	// MORE COLLISIONS TO RESOLVE FOR THIS FRAME
	while (activeCollisions.size() > 0)
	{
		// SORT COLLISION OBJECTS BY TIME OF COLLISION
		// NOTE THAT I'M JUST EMPLOYING THE STL'S List
		// CLASS' SORT METHOD BY PROVIDING MY OWN
		// MEANS FOR COMPARING Collision OBJECTS
		activeCollisions.sort(CollisionComparitor());

		// GET FIRST COLLISION - NOTE THAT WE HAVE THE COLLISIONS SORTED
		// IN DESCENDING ORDER, SO TO TAKE THE EARLIEST ONE, WE REMOVE IT
		// FOM THE BACK OF THE SORTED LIST
		Collision *earliestCollision = activeCollisions.back();
		activeCollisions.pop_back();
		float collisionTime = earliestCollision->getTimeOfCollision();

		// MOVE ALL SPRITES UP TO TIME OF FIRST COLLISION USING
		// APPROPRIATELY SCALED VELOCITIES
		moveAllSpritesUpToBufferedTimeOfCollision(earliestCollision);

		// AND ADVANCE COLLISION TIME
		currentCollisionTime = collisionTime;

		// AND UPDATE THE VELOCITIES OF THE SPRITE(S) INVOLVED IN THE COLLISION
		performCollisionResponse(earliestCollision);

		// EXECUTE COLLISION EVENT CODE
		// TEST TO SEE TYPES OF OBJECTS AND APPROPRIATE RESPONSE
		// ACCORDING TO CUSTOMIZED COLLISION EVENT HANDLER
		collisionListener->respondToCollision(game, earliestCollision);

		// FOR THE TWO OBJECTS INVOLVED IN THE COLLISION
		// REMOVE ALL OTHER COLLISIONS INVOLVING THEM
		// SINCE THEY ARE NOW OBSOLETE. THE REASON BEING
		// THE OBJECT COLLISION NOW LIKELY HAS A 
		// DIFFERENT VECTOR
		// UPDATE THEIR SWEPT SHAPES
		// TEST THEM AGAINST TILES AGAIN
		CollidableObject *co1 = earliestCollision->getCO1();
		CollidableObject *co2 = earliestCollision->getCO2();
		removeActiveCOCollisions(co1);
		co1->updateSweptShape(1.0f - currentCollisionTime);
		getAllTileCollisionsForAGivenSprite(world, co1, 1.0f - currentCollisionTime);

		// ONLY DO IT FOR THE SECOND ONE IF IT'S NOT A TILE
		if (!earliestCollision->isCollisionWithTile())
		{
			removeActiveCOCollisions(co2);
			co2->updateSweptShape(1.0f - currentCollisionTime);
			getAllTileCollisionsForAGivenSprite(world, co2, 1.0f - currentCollisionTime);
		}
		else
		{
			spriteToTileCollisionsThisFrame[co1].insert(earliestCollision->getTile());
			recycledCollidableObjectsList.push_back(co2);
		}

		// NOW WE NEED TO SEE IF THE SPRITES INVOLVED IN THE JUST
		// RESOLVED COLLISION ARE GOING TO BE INVOLVED IN ANY MORE
		// WITH OTHER SPRITES BUT WE DON'T WANT TO CHECK ALL OF THEM,
		// WE ONLY WANT TO CHECK NEIGHBORS, BUT FIRST WE HAVE TO
		// MAKE SURE THE SPRITE(S) THAT WE JUST RESOLVED ARE IN THEIR
		// PROPER SWEPT SHAPE LOCATIONS WITHOUT HAVING TO RESORT EVERTYHING

		// IF IT WAS ONLY ONE SPRITE WITH A TILE THIS IS EASY TO DO
		if (earliestCollision->isCollisionWithTile())
		{
			reorderCollidableObject(co1);
		}
		// YOU'LL HAVE TO WORRY ABOUT REORDERING STUFF FOR COLLISIONS
		// BETWEEN TWO SPRITES

		// NOW TEST NEIGHBORS OF SPRITES INVOLVED IN RESOLVED COLLISION
		// AGAINST NEIGHBORS IN SWEPT SHAPE DATA STRUCTURES. YOU'LL HAVE
		// TO FIGURE OUT HOW TO DO THIS AND HOW TO RESOLVE SUCH COLLISIONS

		// RECYCLE THE COLLISION SINCE WE'RE NOW DONE WITH IT
		recycledCollisions.push_back(earliestCollision);
	}

	// APPLY THE REMAINING TIME TO MOVE THE SPRITES. NOTE THAT
	// THIS IS ACTUALLY A VERY RISKY, TRICKY STEP BECAUSE IT COULD
	// MOVE OBJECTS ALMOST TO THE POINT OF COLLISION, WHICH MAY THEN
	// BE DETECTED ALMOST AT TIME 0 NEXT FRAME. THERE ARE OTHER TRICKY
	// ISSUES RELATED TO OUR BUFFER AS WELL, SO WE CHEAT A LITTLE HERE
	// AND SCALE THE TIME REMAINING DOWN A LITTE
	if (currentCollisionTime < 1.0f)
		moveAllSpritesToEndOfFrame();

	// INIT TILE COLLISION INFO
	// SET ON TILE LAST FRAME USING ON TILE THIS FRAME
	// SET ON TILE THIS FRAME TO FALSE
	spritesIt = sortedSweptShapes[LEFT_EDGE]->begin();
	while (spritesIt != sortedSweptShapes[LEFT_EDGE]->end())
	{
		CollidableObject *sprite = (*spritesIt);
		sprite->advanceOnTileStatus();
		spritesIt++;
	}
//	while(!colliding){
	for (b2Contact* contact = game->getbworld()->GetContactList(); contact; contact = contact->GetNext()) {
		b2Body* a = contact->GetFixtureA()->GetBody(); 
		b2Body* b = contact->GetFixtureB()->GetBody();

		AnimatedSprite* c = (AnimatedSprite*) a->GetUserData(); 
		AnimatedSprite* d = (AnimatedSprite*) b->GetUserData();

		unsigned int x = c->getSpriteType()->getSpriteTypeID(); 
		unsigned int y = d->getSpriteType()->getSpriteTypeID();
		
		switch(x){
		case 0: // player 
			break;
		case 1: // 
			break;
		case 2:
			GarbageMon *e; 
			e= (GarbageMon*)c;
			//co.remove(e);
			//game->getbworld()->DestroyBody(e->getBody());
			//e->collisionResponse(game);
			break;
		case 4:
			//Trash *f = (Trash*)c;
			//f->collisionResponse(game);
			break;
		}
		
		switch(y){
		//	if (x == 0) {
				case 0: // player 
					break;
				case 1: // 
					break;
				case 2:
		//			colliding = true;
					GarbageMon *g;
					g= (GarbageMon*)d;
					co.push_back(g);
					co.remove(g);
					//g->setCurrentState(L"DYING");
					g->getPhysicalProperties()->setPosition(9999.9f, 9999.9f);
					game->playExplosion();
					//wstring s = c->getCurrentState();
					g->getBody()->ApplyLinearImpulse(b2Vec2(99999.9f, 0.0f), g->getBody()->GetPosition(), true);
					//game->getbworld()->DestroyBody(g->getBody());
					//g->getBody()->DestroyFixture(g->getBody()->GetFixtureList());
					//g->getBody()->GetWorld()->DestroyBody(g->getBody());
					g->collisionResponse(game);
					//colliding = false;
					break;
				case 5:
					Trash *h = (Trash*)d;
					co.remove(h);
					//h->collisionResponse(game);
					break;
			}
		}
	//}
	//}
	//update sprites according to box2d thingies
	list<CollidableObject*>::iterator i = co.begin();

	while (i != co.end()) {
		CollidableObject* c = *i;

		PhysicalProperties* p = c->getPhysicalProperties();
		p->setX(c->getBody()->GetPosition().x * pikachu);
		p->setY(c->getBody()->GetPosition().y * pikachu);

		i++;
	}

	float32 time = 1.0f/1.25f;
	int32 vel = 8;
	int32 pos = 3;
	game->getbworld()->Step (time, vel, pos);

	for (b2Contact* contact = game->getbworld()->GetContactList(); contact; contact = contact->GetNext()) {
		b2Fixture* a = contact->GetFixtureA();
		b2Fixture* b = contact->GetFixtureB();
		AnimatedSprite* a2 = (AnimatedSprite*) a->GetBody()->GetUserData();
		AnimatedSprite* b2 = (AnimatedSprite*) b->GetBody()->GetUserData();
		if(a2->getSpriteType()->getSpriteTypeID() == 0 && b2->getSpriteType()->getSpriteTypeID() == 2){
			b->GetBody()->ApplyLinearImpulse(a->GetBody()->GetWorldVector(b2Vec2(0,-2)), b->GetBody()->GetPosition(), true);
			b->GetBody()->SetLinearVelocity(b2Vec2 (0,0));
			SpriteManager *sm = game->getGSM()->getSpriteManager();
			int health = (int) _wtoi(sm->getHealthBar()->getCurrentState().c_str());
			if (health <= 10){
				// WHEN PLAYER RUNS OUT OF HEALTH, SKIP TO NEXT DAY
				// PENALTY LIES IN THE PLAYER NOT ACHIEVING THE DAY'S GOALS
				// AND HAVE TO SUFFER INCREASE IN POLLUTION BAR
				sm->getHealthBar()->setCurrentState(to_wstring(100));
			}
			else{
				//OutputDebugStringW(L"HI");
				sm->getHealthBar()->setCurrentState(to_wstring(health - 10));
			}
		}

		//contact->GetFixtureB()->GetBody()->DestroyFixture(a);
	}

	// WE'RE NOT GOING TO ALLOW MULTIPLE COLLISIONS TO HAPPEN IN A FRAME
	// BETWEEN THE SAME TWO OBJECTS
	spriteToTileCollisionsThisFrame.clear();
}
Пример #23
0
void Physics::update(Game *game)
{
	// REMEMBER, AT THIS POINT, ALL PLAYER INPUT AND AI
	// HAVE ALREADY BEEN PROCESSED AND BOT AND PLAYER
	// STATES, VELOCITIES, AND ACCELERATIONS HAVE ALREADY
	// BEEN UPDATED. NOW WE HAVE TO PROCESS THE PHYSICS
	// OF ALL THESE OBJECTS INTERACTING WITH EACH OTHER
	// AND THE STATIC GAME WORLD. THIS MEANS WE NEED TO
	// DETECT AND RESOLVE COLLISIONS IN THE ORDER THAT
	// THEY WILL HAPPEN, AND WITH EACH COLLISION, EXECUTE
	// ANY GAMEPLAY RESPONSE CODE, UPDATE VELOCITIES, AND
	// IN THE END, UPDATE POSITIONS

	// FIRST, YOU SHOULD START BY ADDING ACCELERATION TO ALL 
	// VELOCITIES, WHICH INCLUDES GRAVITY, NOTE THE EXAMPLE
	// BELOW DOES NOT DO THAT


	// FOR NOW, WE'LL JUST ADD THE VELOCITIES TO THE
	// POSITIONS, WHICH MEANS WE'RE NOT APPLYING GRAVITY OR
	// ACCELERATION AND WE ARE NOT DOING ANY COLLISION 
	// DETECTION OR RESPONSE
	float timer = 0;

	GameStateManager *gsm = game->getGSM();
	SpriteManager *sm = gsm->getSpriteManager();
	World *w = gsm->getWorld();
	GameRules* gR = game->getGameRules();
	vector<WorldLayer*> *layers = w->getLayers();

	AnimatedSprite *player;
	PhysicalProperties *pp;
	TiledLayer *tL;
	list<Collision*> collisions;
	
	//finding TileLayer
	for(unsigned int i = 0; i < layers->size(); i++)
	{
		WorldLayer *currentLayer = (*layers)[i];
		if(currentLayer->hasCollidableTiles() == true)
		{
			tL = dynamic_cast<TiledLayer*>(currentLayer);
			if(tL != 0)
			{
				i = layers->size();
			}//end if
		}//end if
	}


	player = sm->getPlayer();
	pp = player->getPhysicalProperties();

	//UPDATING ALL VELOCITIES AND DOING TILE COLLISION
	pp->incVelocity(this,pp->getAccelerationX(), pp->getAccelerationY() + gravity); 
	collideTestWithTiles(player, tL, &collisions);

	list<Bot*>::iterator botIterator = sm->getBotsIterator();
	while (botIterator != sm->getEndOfBotsIterator())
	{			
		Bot *bot = (*botIterator);
		pp = bot->getPhysicalProperties();
		pp->incVelocity(this, pp->getAccelerationX(), pp->getAccelerationY());
		if(pp->isGravAffected() == true)
			pp->incVelocity(this, 0, gravity);
		collideTestWithTiles(bot, tL, &collisions);
		botIterator++;
	}

	//HERE, COLLIDE SPRITES WITH OTHER SPRITES
	collideTestWithSprites(game, player, &collisions);
	botIterator = sm->getBotsIterator();
	while (botIterator != sm->getEndOfBotsIterator())
	{			
		Bot *bot = (*botIterator);
		if(bot->isCurrentlyCollidable() == true);
			collideTestWithSprites(game, bot, &collisions);
		botIterator++;
	}

	//SORT COLLISIONS
	collisions.sort(compare_collisionTime);

	//RESOLVING ALL THE COLLISIONS
	while(collisions.empty() == false)
	{
		Collision* currentCollision = collisions.front();
		collisions.pop_front();
		float colTime = currentCollision->getTOC();
		CollidableObject* co1 = currentCollision->getCO1();
		CollidableObject* co2 = currentCollision->getCO2();

		if(colTime >= 0 && colTime <= 1)
		{
			
			pp = co1->getPhysicalProperties();
			//pp->setVelocity(pp->getVelocityX()*9.99f,pp->getVelocityY()*9.99f);
			pp = co2->getPhysicalProperties();
			//pp->setVelocity(pp->getVelocityX()*9.99f,pp->getVelocityY()*9.99f);

			pp = player->getPhysicalProperties();
			pp->setPosition(pp->getX() + (pp->getVelocityX()*(colTime-timer)),pp->getY() + (pp->getVelocityY()*(colTime-timer)));
			botIterator = sm->getBotsIterator();
			while (botIterator != sm->getEndOfBotsIterator())
			{			
				Bot *bot = (*botIterator);
				pp = bot->getPhysicalProperties();
				pp->setPosition(pp->getX() + (pp->getVelocityX()*(colTime-timer)), pp->getY() + (pp->getVelocityY()*(colTime-timer)));
				botIterator++;
			}

			gsm->updateViewport(game, colTime-timer);

			resolveCollision(game, currentCollision);
			gR->gameSpecificResolve(game, currentCollision);
			
			boolean deleteLast = false;
			list<Collision*>::iterator cIterator = collisions.begin();
			list<Collision*>::iterator lastIterator;
			while(cIterator != collisions.end())
			{
				if(deleteLast == true)
				{
					collisions.erase(lastIterator);
				}
				deleteLast = false;
				Collision* check = (*cIterator);
				if(check->contains(co1) || check->contains(co2))
				{
					CollidableObject* checkStatic = check->getCO2();
					if(checkStatic->isStaticObject())
					{
						coStackCounter ++;
						coStack[coStackCounter] = checkStatic;
					}

					collisionStackCounter ++;
					collisionStack[collisionStackCounter] = check;

					lastIterator = cIterator;
					deleteLast = true;
				}
				else
				{
					//check->calculateTimes();
				}

				cIterator++;
			}

			if(deleteLast == true)
			{
				collisions.erase(lastIterator);
			}

			collideTestWithTiles(co1, tL, &collisions);
			collideTestWithSprites(game, co1, &collisions);

			if(co2->isStaticObject() == false)
			{
				collideTestWithTiles(co2, tL, &collisions);
				collideTestWithSprites(game, co2, &collisions);
			}

			collisions.sort(compare_collisionTime);

			timer += (colTime-timer);
		}//end if


		if(co2->isStaticObject() == true)
		{
			coStackCounter ++;
			coStack[coStackCounter] = co2;
		}

		collisionStackCounter ++;
		collisionStack[collisionStackCounter] = currentCollision;
	
	}
	
	if(timer < 1)
	{
		gsm->updateViewport(game, 1-timer);
		pp = player->getPhysicalProperties();
		pp->setPosition(pp->getX() + (pp->getVelocityX()*(1-timer)),pp->getY() + (pp->getVelocityY()*(1-timer)));
		//pp->setVelocity(0.0f, pp->getVelocityY());
		botIterator = sm->getBotsIterator();
		while (botIterator != sm->getEndOfBotsIterator())
		{			
			Bot *bot = (*botIterator);
			pp = bot->getPhysicalProperties();
			pp->setPosition(pp->getX() + (pp->getVelocityX()*(1-timer)), pp->getY() + (pp->getVelocityY()*(1-timer)));
			botIterator++;
		}
		gsm->updateViewport(game, 1-timer);
	}
	
	pp = player->getPhysicalProperties();
	if(pp->getX() < 0)
	{
		pp->setX(0);
	}
	if(pp->getY() < 0)
	{
		pp->setY(0);
	}
	//pp->setVelocity(0.0f, pp->getVelocityY());
	/*pp->setPosition(pp->getX() + pp->getVelocityX(), pp->getY() + pp->getVelocityY());

	// FOR NOW THE PLAYER IS DIRECTLY CONTROLLED BY THE KEYBOARD,
	// SO WE'LL NEED TO TURN OFF ANY VELOCITY APPLIED BY INPUT
	// SO THE NEXT FRAME IT DOESN'T GET ADDED
	pp->setVelocity(0.0f, pp->getVelocityY());

	// AND NOW MOVE ALL THE BOTS
	list<Bot*>::iterator botIterator = sm->getBotsIterator();
	while (botIterator != sm->getEndOfBotsIterator())
	{			
		Bot *bot = (*botIterator);
		pp = bot->getPhysicalProperties();
		pp->setPosition(pp->getX() + pp->getVelocityX(), pp->getY() + pp->getVelocityY());
		botIterator++;
	}*/

	
}
Пример #24
0
void renderScene(void) {
    mainPlane.manageHealth();
    
    //GLfloat lightpos[] = {-x,-z,-y};
    //glTranslatef(lightpos[0], lightpos[1], lightpos[2]);
    glColor3f(1, 1, 1);
    //glutSolidSphere(30, 20, 20);
    //glTranslatef(-lightpos[0], -lightpos[1], -lightpos[2]);
    //glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
	if (deltaMove)
		moveMeFlat(deltaMove);
	if (deltaAngle) {
		angle += deltaAngle;
		orientMe(angle);
        //rotateMe(angle);
	}
    if (rotationAngleDelta) {
        rotationAngle+=rotationAngleDelta;
        rotationAngleDelta=0;
        rotateMe(rotationAngle);
    }
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // Draw ground
    glPushMatrix();
    //glLoadIdentity();
    //glTranslatef(x, y, z);
    //glRotatef(rotationAngle+90, 0, 1, 0);
    explosives.drawExplosions();
    //glTranslatef(-x, -y, -z);
    glPopMatrix();
	
    float minX=200000,maxX=0,minY=20000,maxY=0;
    glBegin(GL_QUADS);
    for (int i = 20; i <tiles.size()-20; i++) {
        for (int j = 20; j <tiles.size()-20; j++) {
            if(tiles[i][j].xMax>maxX) maxX = tiles[i][j].xMax;
            if(tiles[i][j].yMax>maxY) maxY = tiles[i][j].yMax;
            if(tiles[i][j].x<minX) minX = tiles[i][j].x;
            if(tiles[i][j].y<minY) minY = tiles[i][j].y;
            if (tiles[i][j].z>-.7) {
                tiles[i][j].drawTile();
            }
            
            
        }
    }
    drawWater(maxX*40,maxY*40,minX*40,minY*40);
	glEnd();
    
    drawTrees();
    drawBuildings();
    advanceLevel();
    drawPlane();
    
    
    //drawSilos();
    drawCarrierGroup();
    
    
    calculateFPS();
	glutSwapBuffers();
    //std::cout<<"hello";
    indexer++;
    if (loadBuildings) {
        loadBuildings = 0;
        cDetector.buildings = &buildings;
    }
    cDetector.detectCollisions();
    //glLoadIdentity();
    
    
}
Пример #25
0
int main()
{
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
	
	glfwInit();
	
	glfwWindowHint(GLFW_SAMPLES, 4);
	window = glfwCreateWindow(WWIDTH, WHEIGHT, "GL Framework", NULL, NULL);
	glfwSetWindowSizeCallback(window, glfw_window_size_callback);
	
	glfwMakeContextCurrent(window);

	// start GLEW extension handler
	glewExperimental = GL_TRUE;
	glewInit();

	glViewport(0, 0, g_gl_width, g_gl_height);	

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_BLEND);


	// Initializam spriteManagerul
	CSpriteManager::Get()->Init();

	// Initializam PlayerEntity si creem sprite-ul asociat
	PlayerTest PlayerEntity;


	CSprite *back = CSpriteManager::Get()->AddSprite("sky0000.png", background);

	
	for (int k = 0; k < 3; k++){
		lives.push_back(CSpriteManager::Get()->AddSprite("mini.png", mini));
		lives[lives.size() - 1]->SetPosition(glm::vec3(3 + k*0.3f, 3.4f, -19));
	}

	CSprite* lifeSprite = CSpriteManager::Get()->AddSprite("life.png", textLife);
	lifeSprite->SetPosition(glm::vec3(3 - 0.6f, 3.4f, -19));



	CSprite *playerSprite = CSpriteManager::Get()->AddSprite("player0000.png", player);
	
	back->SetPosition(glm::vec3(-4, -4, -20));

	assert(playerSprite);
	PlayerEntity.Init(playerSprite);
//	back->PlayAnimation("Sky");

	EnemyTest vec[100];
	int number_of_enemy =5;
	//vector de inamici
	vector<CSprite*> enemies;
	float x,y;
	for (int i = 0; i< number_of_enemy; i++)
	{
		
		CSprite *RandomRocket = CSpriteManager::Get()->AddSprite("PlayerRocket.png",enemy);
		x = -3.0f - i;
		y = RandomRocket->getFirstParabolaY(x);
		RandomRocket->SetPosition(glm::vec3(x, y, -11));
		vec[i].Init(RandomRocket);
		enemies.push_back(RandomRocket);


	}


	float t = 0.0f;
	float dt = 0.01f;

	float prevTime =(float) glfwGetTime();
	float accumulator = 0.0f;

	Collision *collide = new Collision();
	

	bool hit = false;
	bool hit2 = false;
	int i;
	while (!glfwWindowShouldClose(window))
	{

		_update_fps_counter(window);

		float newTime =(float) glfwGetTime();
		float deltaTime = (float)(newTime - prevTime);
		

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glViewport(0, 0, g_gl_width, g_gl_height);


		if (deltaTime > 0.25f)
			deltaTime = 0.25f;
		prevTime = newTime;

		accumulator += deltaTime;

		while (accumulator >= dt)
		{
			// update logic pentru player
			PlayerEntity.Update(dt);

			// update animatie
			CSpriteManager::Get()->Update(dt);

			//update enemies
			int nr = 0;
			for (int i = 0; i < number_of_enemy; i++)
			{
				if (enemies[i]->life>0){
					vec[i].Update(dt, nr);
				}
			}
			t += dt;
			accumulator -= dt;
		}

		// desenare
		CSpriteManager::Get()->Draw();

		//verificare coliziune intre player si inamic
		for ( i = 0; i< number_of_enemy; i++)
		{
			collide->ResolveCollisionPlayer(playerSprite,enemies[i]);
			if (collide->getStatusPlayer() == true){
				if (playerSprite->life>=0){
					CSpriteManager::Get()->RemoveSprite(lives[lives.size() - 1]->index);
					lives.erase(lives.end() - 1);
				}
				

			}



			//verificare coliziune intre player si proiectile inamici
			vec[i].Collide(playerSprite, collide);

			if (playerSprite->life == 0){
				playerSprite->SetPosition(glm::vec3(-5.0f, -5.0f, playerSprite->GetPosition().z));
			}

			if (enemies[i]->life == 0){
				enemies[i]->life = 2;
			}

		}


		//verificare coliziune intre inamic si proiectilul player-ului
		collide->ResolveCollisionEnemy(CSpriteManager::Get()->projectiles, enemies );

		glfwPollEvents();
		glfwSwapBuffers(window);

		if (GLFW_PRESS == glfwGetKey(window, GLFW_KEY_ESCAPE))
		{
			glfwSetWindowShouldClose(window, 1);
		}

	}

	delete collide;
	glfwTerminate();
	return 0;
}
Пример #26
0
Collision* RayTracer::trace(Eigen::Vector3f start, Eigen::Vector3f ray, bool unit) {
   Collision* c = new Collision();   
   c->detectRayCollision(start, ray, objects, -1, unit);
   return c;
}
Пример #27
0
int main() {

  ServiceLocator::Initialize();

  ComponentFactory factory;
  RegisterFactories(&factory);

  ConsoleHandler console(80, 50, "Pong", ConsoleProc );
  GameClock clock;

  EntityManager manager;
  ServiceLocator::ProvideEntityManager(&manager);

  //Deprecated code in favour of using XML to automate generation of entities.
  /*
  //one ball
  unsigned int ball = manager->CreateEntity();
  manager.AddComponent( ball, new Ball() );

  //two paddles
  unsigned int player = manager.CreateEntity();
  manager.AddComponent( player, new Paddle(true) );
  manager.AddComponent( player, new Score() );

  unsigned int ai = manager.CreateEntity();
  manager.AddComponent( ai, new Paddle(false) );
  manager.AddComponent( ai, new Score() );

  //4 borders
  //top
  Vector2 pos = { 50.0f, 99.0f };
  Border* border = new Border( pos, true, 2 );
  unsigned int border_ent = manager.CreateEntity();
  manager.AddComponent( border_ent, border );
  //bottom
  pos.y = 1.0f;
  border = new Border( pos, true, 1 );
  border_ent = manager.CreateEntity();
  manager.AddComponent( border_ent, border );
  //left
  pos.x = 1.0f;
  pos.y = 50.0f;
  border = new Border( pos, false, 2 );
  border_ent = manager.CreateEntity();
  manager.AddComponent( border_ent, border );
  //right
  pos.x = 99.0f;
  border = new Border( pos, false, 1 );
  border_ent = manager.CreateEntity();
  manager.AddComponent( border_ent, border );
  */

  {
    //get the document
    pugi::xml_document doc;
    pugi::xml_parse_result result = doc.load_file( string(LOCAL_DATA + "pong.xml").c_str() );

    if( !result) {
      cout << "XML loading error: " << result.description() << endl;
    }
    else {
      //get the <entities /> tag
      pugi::xml_node entities = doc.child("entities");

      //iterate through each child of the tag to find each <entity /> tag
      for( pugi::xml_node entity = entities.first_child(); entity; entity = entity.next_sibling() ) {
        //create a new entity for each child
        unsigned int entity_id = manager.CreateEntity();

        //iterate through each component of a given entity
        for( pugi::xml_node component = entity.first_child(); component; component = component.next_sibling() ) {
          
          //get the type
          string type = component.attribute("type").value();
          
          //throw it at our component factory
          IComponent* new_component = factory.Create( type );
          if( new_component ) {
            //deserialize any pertinent XML data
            new_component->Deserialize(component);
            //add it to our entity
            manager.AddComponent( entity_id, new_component );
          }
        }
      }
    }

    //document goes out of scope and is destroyed
  }

  //Get game systems
  AIPaddleDriver ai_paddle_driver;
  BallDriver ball_driver;
  Collision collision;
  PlayerPaddleDriver player_paddle_driver;

  while(g_app_running) {
    //start timing the frame
    clock.StartFrame();

    //take care of any events
    console.CheckEvents();

    //run all of our systems to update components, passing the delta_time value for timing
    ball_driver.Process(clock.delta_time());
    ai_paddle_driver.Process(clock.delta_time());
    player_paddle_driver.Process(clock.delta_time());
    collision.Process(clock.delta_time());

    //draw components
    Draw(&console);

    //swap buffers
    console.Present();

    //finish timing frame and update delta time
    clock.EndFrame();
  }

  return 0;
}
Пример #28
0
void Physics::collideTestWithTiles(CollidableObject *c,TiledLayer *tL, list<Collision*> *collisions)
{
	BoundingVolume *bv = c->getBoundingVolume();
	float toRight= bv->getWidth()/2;
	float toBottom = bv->getHeight()/2;

	PhysicalProperties *pp = c->getPhysicalProperties();
	float x = pp->getX()+bv->getX();
	float y = pp->getY()+bv->getY();
	float xVel = pp->getVelocityX();
	float yVel = pp->getVelocityY();
	float minX = x - toRight;
	float maxX = x + toRight;
	float minY = y - toBottom;
	float maxY = y + toBottom;

	if(xVel > 0)
		maxX += xVel;
	else
		minX += xVel;
	if(yVel > 0)
		maxY += yVel;
	else
		minY += yVel;

	 int tW = tL->getTileWidth();
	 int tH = tL->getTileHeight();

	int firstCol = minX/tW;
	int lastCol = maxX/tW;
	int firstRow = minY/tH;
	int lastRow = maxY/tH;

	if(firstCol < 0)
		firstCol = 0;
	if(firstRow < 0)
		firstRow = 0;
	if(lastCol >= tL->getColumns())
		lastCol = tL->getColumns() - 1;
	if(lastRow >= tL->getRows())
		lastRow = tL->getRows() - 1;

	for(int i = firstRow; i <= lastRow; i++)
	{
		for(int j = firstCol; j <= lastCol; j++)
		{
			Tile* current = tL->getTile(i,j);
			if(current->collidable == true)
			{
				if( !( (i+1)*tH < minY || i*tH > maxY || (j+1)*tW < minX || j*tW > maxX)  )
				{
					CollidableObject* tileCO = coStack[coStackCounter];
					coStackCounter --;
					BoundingVolume *bv = tileCO->getBoundingVolume();
					bv->setWidth(tW);
					bv->setHeight(tH);
					bv->setX(tW/2);
					bv->setY(tW/2);
					pp = tileCO->getPhysicalProperties();
					pp->setPosition(j*tW,i*tH);
					

					/*
					Collision* currentCollision = collisionStack.top();
					collisionStack.pop();*/
					Collision* currentCollision = collisionStack[collisionStackCounter];
					collisionStackCounter --;


					currentCollision->setCO1(c);
					currentCollision->setCO2(tileCO);
					currentCollision->calculateTimes();

					collisions->push_back(currentCollision);
				}
			}
		}
	}
	
}
Пример #29
0
void Physics::simulate(PodState* pods[POD_COUNT*2]) {
    // Update counters.
    for(int i = 0; i < POD_COUNT*2; i++) {
        pods[i]->turnsSinceCP++;
        pods[i]->turnsSinceShield++;
    }
    float time = 0;
    vector<PassedCheckpoint> pCPEvents;
    PassedCheckpoint cpEvent;
    Collision earliest;
    int earliestIdx[2];
    int skip[2] = {-1, -1};
    bool started = false;
    bool hasCollision = false;
    bool occurred = false;
    Collision collision;
    while(time < 1) {
        for (int i = 0; i < POD_COUNT*2; i++) {
            // Collision or checkpoint passing first?
            for (int j = i + 1; j < POD_COUNT*2; j++) {
                // Shortcut for performance: the previous two to collide can't collide next.
                if (skip[0] == i && skip[1] == j) {
                    continue;
                }
                // These two had the previous collision.
                occurred = Collision::testForCollision(*pods[i], *pods[j], &collision);
                // TODO: can the second zero time collision be ignored?

                if (occurred && collision.time() + time < 1.0 &&
                    (!hasCollision || earliest.time() > collision.time())) {
                    hasCollision = true;
                    earliest = collision;
                    earliestIdx[0] = i;
                    earliestIdx[1] = j;
                }
            }
            // Can optimize by keeping list of pc events and resolving all those before the earliest collision.
            occurred = PassedCheckpoint::testForPassedCheckpoint(*pods[i], race, &cpEvent, 1 > 1);
            if (occurred && cpEvent.time() + time < 1.0) {
                pCPEvents.push_back(cpEvent);
            }
        }
        for (auto& pcp : pCPEvents) {
            if (!hasCollision || pcp.time() < earliest.time()) {
                pcp.resolve();
            }
        }
        pCPEvents.clear();
        float moveTime = hasCollision ? earliest.time() : 1.0 - time;
        for(int i = 0; i < POD_COUNT*2; i++) {
            pods[i]->pos.x += pods[i]->vel.x * moveTime;
            pods[i]->pos.y += pods[i]->vel.y * moveTime;
        }
        if (hasCollision) {
            earliest.resolve();
            hasCollision = false;
            skip[0] = earliestIdx[0];
            skip[1] = earliestIdx[1];
        }
        time += moveTime;
    }
    // Drag and rounding.
    for(int i = 0; i < POD_COUNT*2; i++) {
        pods[i]->vel.x *= DRAG;
        pods[i]->vel.y *= DRAG;
        pods[i]->vel.x = (int) pods[i]->vel.x;
        pods[i]->vel.y = (int) pods[i]->vel.y;
        // The instructions say that position is rounded, however, on inspection, truncating seems to be closer
        // to reality. In addition, rounding is a non-insignificant performance cost.
        pods[i]->pos.x = (int) pods[i]->pos.x;
        pods[i]->pos.y = (int) pods[i]->pos.y;
        pods[i]->pos.resetLengths();
        pods[i]->vel.resetLengths();
    }
}
Пример #30
0
//FOR NOW, TESTS SPRITES AGAINST ALL OTHER SPRITES. IF I HAVE TIME, I WILL IMPLEMENT SWEEP AND PRUNE
void Physics::collideTestWithSprites(Game* game, CollidableObject* c, list<Collision*> *collisions)
{
	SpriteManager *sm = game->getGSM()->getSpriteManager();
	AnimatedSprite* player = sm->getPlayer();

	if(c != player)
	{
		if(player->isCurrentlyCollidable() == true)
		{
			if(willObjectsCollide(player, c) == true)
			{
				Collision* currentCollision = collisionStack[collisionStackCounter];
				collisionStackCounter --;
				currentCollision->setCO1(player);
				currentCollision->setCO2(c);
				currentCollision->calculateTimes();

				if(currentCollision->getTOC() > 0 && currentCollision->getTOC() <= 1)
				{
					collisions->push_back(currentCollision);
				}
				else
				{
					collisionStackCounter ++;
					collisionStack[collisionStackCounter] = currentCollision;
				}
			}//end if
		}//end if
	}//end if
	else
	{
		list<Bot*>::iterator botIterator = sm->getBotsIterator();
		while (botIterator != sm->getEndOfBotsIterator())
		{			
			Bot *bot = (*botIterator);
			if(c != bot && bot->isCurrentlyCollidable() == true)
			{
				if(willObjectsCollide(c, bot) == true)
				{
					Collision* currentCollision = collisionStack[collisionStackCounter];
					collisionStackCounter --;
					currentCollision->setCO1(c);
					currentCollision->setCO2(bot);
					currentCollision->calculateTimes();

					if(currentCollision->getTOC() > 0 && currentCollision->getTOC() <= 1)
					{
						collisions->push_back(currentCollision);
					}
					else
					{
						collisionStackCounter ++;
						collisionStack[collisionStackCounter] = currentCollision;
					}
				}//end if
			}//end if
			botIterator++;
		}//end while
		
	}
	/*Collision* currentCollision = collisionStack[collisionStackCounter];
	collisionStackCounter --;


	currentCollision->setCO1(c);
	currentCollision->setCO2(tileCO);
	currentCollision->calculateTimes();

	collisions->push_back(currentCollision);*/

}