src/proto2/Physics.cc
branchno-netsession
changeset 35 e21cfda0edde
child 41 ca80cd67785d
equal deleted inserted replaced
34:1ea6554d703e 35:e21cfda0edde
       
     1 
       
     2 #include "Physics.hh"
       
     3 #include "Engine.hh"
       
     4 
       
     5 #include <algorithm>
       
     6 #include <functional>
       
     7 
       
     8 PhysicsWorld::PhysicsWorld (Vector gravity, Vector dimensions)
       
     9     : tick_timer(PHYSICS_TICK_MS), gravity(gravity), dimensions(dimensions) {
       
    10 
       
    11     slots.connect(tick_timer.sig_timer(), this, &PhysicsWorld::tick);
       
    12     tick_timer.enable();
       
    13 }
       
    14 
       
    15 void PhysicsWorld::addObject (PhysicsObject *object) {
       
    16     objects.push_back(object);
       
    17 }
       
    18 
       
    19 void PhysicsWorld::tick () {
       
    20 //    Engine::log(DEBUG, "physics.apply_force") << "*tick*";
       
    21 
       
    22 	for (std::vector<PhysicsObject*>::iterator i = objects.begin(); i != objects.end(); i++) {
       
    23        	(*i)->tick(); 
       
    24   	}
       
    25 }
       
    26 
       
    27 PhysicsObject::PhysicsObject (PhysicsWorld &world, float mass, Vector position, Vector velocity)
       
    28     : world(world), mass(mass), position(position), velocity(velocity) {
       
    29 
       
    30     world.addObject(this);
       
    31 }
       
    32     
       
    33 void PhysicsObject::updatePosition () {
       
    34 
       
    35 	// Check if the player is moving on the ground
       
    36 	/*if (this->velocity.y == 0 && (position.y >= world.dimensions.y - 3)) {
       
    37     	position.x += 50 * velocity.x * (PHYSICS_TICK_MS / 1000.0);
       
    38 		velocity.x = 0;
       
    39 		return;
       
    40 	}*/
       
    41 
       
    42 	// If not moving on the ground, apply normal physics
       
    43 
       
    44     // Calculate gravity's influence on the velocity vector
       
    45     this->velocity += world.gravity * (PHYSICS_TICK_MS / 1000.0);
       
    46         
       
    47     Vector newPosition = position + velocity * (PHYSICS_TICK_MS / 1000.0);
       
    48 
       
    49     //TODO Handle the object as a square or a polygon
       
    50     
       
    51 //    Engine::log(DEBUG, "physics.update_position") << "position=" << newPosition << ", velocity=" << velocity;
       
    52 
       
    53     bool collided = false;
       
    54      
       
    55     if (newPosition.x < 0 || (newPosition.x > world.dimensions.x)) {
       
    56         // CRASH!
       
    57         this->velocity.x *= -0.5;
       
    58 		
       
    59 		// If the velocity drops under some fixed constant we decide it is zero.
       
    60 		// This is to prevent the object from bouncing eternally.
       
    61 		if (abs(this->velocity.x) < 0.1)
       
    62 			this->velocity.x = 0;
       
    63 
       
    64         collided = true;
       
    65     } else {
       
    66         this->position.x = newPosition.x;
       
    67     }
       
    68     
       
    69     if (newPosition.y <= 0 || (newPosition.y >= world.dimensions.y)) {
       
    70 		this->velocity.y *= -0.3;
       
    71 
       
    72 		
       
    73  
       
    74 		if (abs(this->velocity.y) < 0.1) {
       
    75 			this->velocity.y = 0;
       
    76 			// Friction
       
    77 			this->velocity.x *= 0.95;
       
    78 		} else {
       
    79         	// Bigger friction
       
    80 			this->velocity.x *= 0.75;
       
    81 		}
       
    82 
       
    83         collided = true;
       
    84 	} else {
       
    85         this->position.y = newPosition.y;
       
    86 	}
       
    87     
       
    88     if(!collided) {
       
    89         this->position = newPosition;
       
    90     }
       
    91 }
       
    92 
       
    93 void PhysicsObject::applyForce (Vector force, uint16_t dt) {
       
    94     Vector oldVelocity = velocity;
       
    95 
       
    96     this->velocity += force * dt / 1000 / mass;  // The last factor denotes the time.
       
    97     // It should be scaled somehow.
       
    98     
       
    99 //    Engine::log(DEBUG, "physics.apply_force") << "force=" << force << ", velocity " << oldVelocity << " -> " << velocity;
       
   100 }
       
   101 
       
   102 void PhysicsObject::updatePhysics (Vector position, Vector velocity) {
       
   103     this->position = position;
       
   104     this->velocity = velocity;
       
   105 }
       
   106     
       
   107 Vector PhysicsObject::getPosition () {
       
   108     return this->position;
       
   109 }
       
   110 
       
   111 void PhysicsObject::tick () {
       
   112     this->updatePosition();
       
   113 }
       
   114