Exemplo n.º 1
0
void entityPhysicsApply(struct Entity* entity, double delta_time) {
    entity->ephysics.acceleration = vector2dAdd(entity->ephysics.acceleration, vector2dScalarMult(delta_time, entity->ephysics.jerk));
    entity->ephysics.speed = vector2dAdd(entity->ephysics.speed, vector2dScalarMult(delta_time, entity->ephysics.acceleration));

    entity->ephysics.prev_position = entity->position;
    entity->position = vector2dAdd(entity->position, vector2dScalarMult(delta_time, entity->ephysics.speed));
}
Exemplo n.º 2
0
void volleyballUpdate(struct VolleyballWorld* world, double delta_time) {
	//gravity
	for (struct EntityListNode* node = world->super.entities; node != NULL; node = node->next) {
		if (!node->entity->ephysics.b_static) {
			node->entity->ephysics.speed = vector2dAdd(node->entity->ephysics.speed, vector2dScalarMult(delta_time, world->wphysics.gravity));
		}
	}

	//apply entity physics
	for (struct EntityListNode* node = world->super.entities; node != NULL; node = node->next) {
		if (node->entity == world->ball && node->entity->position.y > 50 - (world->ball->sprite->h)) {
			node->entity->ephysics.speed.y *= -1.0;
			//node->entity->position.y = 50 - node->entity->sprite->h - 0.1;
		}

		if (node->entity == world->ball && node->entity->position.x < 0) {
			node->entity->ephysics.speed.x *= -1.0;
			//node->entity->position.x = 0.1;
		}

		if (node->entity == world->ball && node->entity->position.x > 80 - world->ball->sprite->w) {
			node->entity->ephysics.speed.x *= -1.0;
			//node->entity->position.x = 80 - node->entity->sprite->w - 0.1;
		}



		if (!node->entity->ephysics.b_static) {
			entityPhysicsApply(node->entity, delta_time);
		}

		if (node->entity == world->player1 || node->entity == world->player2) {
			if (node->entity->position.y > 40.0) {
				node->entity->position.y = 40.0;
				struct Vector2d zero_vector = { 0.0, 0.0 };
				node->entity->ephysics.jerk = zero_vector;
				node->entity->ephysics.acceleration = zero_vector;
				node->entity->ephysics.speed = zero_vector;
			}
		}
	}

	for (struct Entity* entity = world->player1; ; entity = world->player2) {
		struct Entity* ball = world->ball;

		struct Vector2d g_ball_center = vector2dAdd(ball->ephysics.center, ball->position);
		struct Vector2d g_entity_center = vector2dAdd(entity->ephysics.center, entity->position);
		struct Vector2d distance = vector2dSubtract(g_ball_center, g_entity_center);
		if (vector2dMagnitude(distance) < (ball->ephysics.radius + entity->ephysics.radius)) {
			struct Vector2d mov_vector = vector2dSubtract(ball->position, ball->ephysics.prev_position);
			struct Vector2d ret_vector = vector2dNormalize(vector2dSymmetry(distance, mov_vector));

			ball->ephysics.speed = vector2dScalarMult(vector2dMagnitude(ball->ephysics.speed), ret_vector);
			ball->ephysics.acceleration = vector2dScalarMult(vector2dMagnitude(ball->ephysics.acceleration), ret_vector);
		}

		if (entity == world->player2) {
			break;
		}
	}

	/*for (struct Entity* entity = world->player1; ; entity = world->player2) {
		struct Entity* ball = world->ball;

		struct Vector2d g_ball_center = vector2dAdd(ball->ephysics.center, ball->position);
		struct Vector2d g_entity_center = vector2dAdd(entity->ephysics.center, entity->position);
		struct Vector2d distance = vector2dSubtract(g_ball_center, g_entity_center);
		if (vector2dMagnitude(distance) < (ball->ephysics.radius + entity->ephysics.radius)) {
			double alpha = atan2(g_ball_center.y - g_entity_center.y, g_ball_center.x - g_entity_center.x);
			double beta = atan2(ball->ephysics.speed.y, ball->ephysics.speed.x);
			double new_beta = 2 * alpha - beta + M_PI;
			double length_beta = vector2dMagnitude(ball->ephysics.speed);

			double ball_speed_x_old = ball->ephysics.speed.x;
			//ball->ephysics.speed.x = -cos(new_beta)
			ball->ephysics.speed.x = -cos(new_beta) * length_beta;
			ball->ephysics.speed.y = sin(new_beta) * length_beta;

			if (ball->ephysics.speed.x + ball_speed_x_old <= 4e-8 && ball->ephysics.speed.x + ball_speed_x_old >= -4e-8) {
				ball->ephysics.speed.x = ball_speed_x_old;
			}

			ball->position.x = g_entity_center.x - ball->ephysics.radius + (cos(alpha) * (entity->ephysics.radius + ball->ephysics.radius));
			ball->position.y = g_entity_center.y - ball->ephysics.radius  - (sin(alpha) * (entity->ephysics.radius + ball->ephysics.radius));
		}

		if (entity == world->player2) {
			break;
		}
	}*/

	//ball <> player1
	/*
	distance2 = GetDistance2(collision_ball.x, collision_ball.y, collision_p1.x, collision_p1.y);
	if (distance2 < collision_distance2)
	{
		alpha = atan2(collision_ball.y - collision_p1.y, collision_ball.x - collision_p1.x);
		beta = atan2(ball->GetSpeedY(), ball->GetSpeedX());
		new_beta = alpha + alpha - beta + pi;
		length_beta = sqrt((ball->GetSpeedX()  ball->GetSpeedX()) + (ball->GetSpeedY()  ball->GetSpeedY()));
		ball_vector_x_old = ball->GetSpeedX();

		ball->SetAngularVelocity((beta - new_beta + pi) / pi  180  0.01);
		ball->SetAngularVelocity(ball->GetAngularVelocity() * ball->GetAngularVelocity());

		ball->SetSpeedX(-cos(new_beta)  length_beta + (player1_vector_x  inh_vector));
		ball->SetSpeedY(sin(new_beta)  length_beta + (player1->GetSpeedY()  inh_vector));
		if (ball->GetSpeedX() + ball_vector_x_old <= vector_tolerance && ball->GetSpeedX() + ball_vector_x_old >= -vector_tolerance)
			ball->SetSpeedX(ball_vector_x_old);
		ball->SetposX(collision_p1.x - ballRadius + (cos(alpha) * (playerRadius + ballRadius)));
		ball->SetposY(ScreenHeight - collision_p1.y - ballRadius - (sin(alpha) * (playerRadius + ballRadius)));
	}
	*/
	//check for collisions multiple times in case collision handling creates new collisions
	/*for (int i = 0; i < 1; i++) {
		for (struct EntityListNode* node1 = world->super.entities; node1 != NULL; node1 = node1->next) {
			for (struct EntityListNode* node2 = node1->next; node2 != NULL; node2 = node2->next) { // ARON SHAME: node2 = node2 = node2->next
				if (!(node1->entity->ephysics.b_collides && node2->entity->ephysics.b_collides)) {
					continue;
				}

				struct Entity* entity1 = node1->entity;
				struct Entity* entity2 = node2->entity;

				unsigned int points_len;
				struct Vector2d* collision_points = collisionPixelPerfect(entity1, entity2, &points_len);

				//if collision
				if (collision_points != NULL) {
					//failsafe - not sure if ever used
					bool e1_failsafe = false;
					bool e2_failsafe = false;

					//if more than one collision point
					if (points_len > 1) {
						//make trend line (tl) based on the collision points - our bouncing line
						struct Vector2d tl_vector = vector2dTrendLine(collision_points, points_len);
						struct Vector2d tl_start = vector2dCenterOfMass(collision_points, points_len);

						//check if entities are affected by collisions
						//bouncing

						//entity1
						if (!entity1->ephysics.b_static && entity1->ephysics.b_affected_by_collisions) {
							//prev position -> position = displacement vector; displacement (ds)
							//magic
							struct Vector2d displacement_vector = vector2dSubtract(entity1->position, entity1->ephysics.prev_position);

							if (vector2dMagnitude(displacement_vector) > 0.000001) {

								struct Vector2d tl_ds_intersection = vector2dLineLineIntersection(tl_start, tl_vector, entity1->ephysics.prev_position, displacement_vector, &e1_failsafe);

								if (!e1_failsafe) {
									struct Vector2d new_vector = vector2dNormalize(vector2dReflection(tl_vector, displacement_vector));

									double collision_distance = vector2dPointPointDistance(entity1->position, tl_ds_intersection);

									entity1->ephysics.prev_position = entity1->position;
									entity1->position = vector2dAdd(tl_ds_intersection, vector2dScalarMult(collision_distance, new_vector));

									entity1->ephysics.jerk = vector2dScalarMult(entity1->ephysics.bounciness*vector2dMagnitude(entity1->ephysics.jerk), new_vector);
									entity1->ephysics.acceleration = vector2dScalarMult(entity1->ephysics.bounciness*vector2dMagnitude(entity1->ephysics.acceleration), new_vector);
									entity1->ephysics.speed = vector2dScalarMult(entity1->ephysics.bounciness*vector2dMagnitude(entity1->ephysics.speed), new_vector);
								}
							}

						}

						//entity2
						if (!entity2->ephysics.b_static && entity2->ephysics.b_affected_by_collisions) {
							struct Vector2d displacement_vector = vector2dSubtract(entity2->position, entity2->ephysics.prev_position);

							if (vector2dMagnitude(displacement_vector) > 0.000001) {

								struct Vector2d tl_ds_intersection = vector2dLineLineIntersection(tl_start, tl_vector, entity2->ephysics.prev_position, displacement_vector, &e1_failsafe);

								if (!e1_failsafe) {
									struct Vector2d new_vector = vector2dNormalize(vector2dReflection(tl_vector, displacement_vector));

									double collision_distance = vector2dPointPointDistance(entity2->position, tl_ds_intersection);

									entity2->ephysics.prev_position = entity2->position;
									entity2->position = vector2dAdd(tl_ds_intersection, vector2dScalarMult(collision_distance, new_vector));

									entity2->ephysics.jerk = vector2dScalarMult(entity2->ephysics.bounciness*vector2dMagnitude(entity2->ephysics.jerk), new_vector);
									entity2->ephysics.acceleration = vector2dScalarMult(entity2->ephysics.bounciness*vector2dMagnitude(entity2->ephysics.acceleration), new_vector);
									entity2->ephysics.speed = vector2dScalarMult(entity2->ephysics.bounciness*vector2dMagnitude(entity2->ephysics.speed), new_vector);
								}
							}

						}

					}
					if (points_len == 1 || e1_failsafe || e2_failsafe) {
						struct Vector2d cp_CoM = vector2dCenterOfMass(collision_points, points_len); // center of mass of collision points

						if ((!entity1->ephysics.b_static && entity1->ephysics.b_affected_by_collisions) && (points_len == 1 || e1_failsafe)) {
							struct Vector2d speed_normalized = vector2dNormalize(entity1->ephysics.speed);
							struct Vector2d pos_cp_CoM_normalized = vector2dNormalize(vector2dSubtract(cp_CoM, entity1->position)); //position -> cp_CoM
							struct Vector2d virtual_tl_vector = vector2dNormal(vector2dAdd(speed_normalized, pos_cp_CoM_normalized)); //virtual trend line vector

							struct Vector2d displacement_vector = vector2dSubtract(entity1->position, entity1->ephysics.prev_position);

							if (vector2dMagnitude(displacement_vector) > 0.000001) {

								struct Vector2d tl_ds_intersection = vector2dLineLineIntersection(cp_CoM, virtual_tl_vector, entity1->ephysics.prev_position, displacement_vector, &e1_failsafe);

								if (!e1_failsafe) {
									struct Vector2d new_vector = vector2dNormalize(vector2dReflection(virtual_tl_vector, displacement_vector));

									double collision_distance = vector2dPointPointDistance(entity1->position, tl_ds_intersection);

									entity1->ephysics.prev_position = entity1->position;
									entity1->position = vector2dAdd(cp_CoM, vector2dScalarMult(collision_distance, new_vector));

									entity1->ephysics.jerk = vector2dScalarMult(entity1->ephysics.bounciness*vector2dMagnitude(entity1->ephysics.jerk), new_vector);
									entity1->ephysics.acceleration = vector2dScalarMult(entity1->ephysics.bounciness*vector2dMagnitude(entity1->ephysics.acceleration), new_vector);
									entity1->ephysics.speed = vector2dScalarMult(entity1->ephysics.bounciness*vector2dMagnitude(entity1->ephysics.speed), new_vector);
								}
							}
						}

						if ((!entity2->ephysics.b_static && entity2->ephysics.b_affected_by_collisions) && (points_len == 1 || e2_failsafe)) {
							struct Vector2d speed_normalized = vector2dNormalize(entity1->ephysics.speed);
							struct Vector2d pos_cp_CoM_normalized = vector2dNormalize(vector2dSubtract(cp_CoM, entity1->position)); //position -> cp_CoM
							struct Vector2d virtual_tl_vector = vector2dNormal(vector2dAdd(speed_normalized, pos_cp_CoM_normalized)); //virtual trend line vector

							struct Vector2d displacement_vector = vector2dSubtract(entity2->position, entity2->ephysics.prev_position);

							if (vector2dMagnitude(displacement_vector) > 0.000001) {

								struct Vector2d tl_ds_intersection = vector2dLineLineIntersection(cp_CoM, virtual_tl_vector, entity2->ephysics.prev_position, displacement_vector, &e1_failsafe);

								if (!e1_failsafe) {
									struct Vector2d new_vector = vector2dNormalize(vector2dReflection(virtual_tl_vector, displacement_vector));

									double collision_distance = vector2dPointPointDistance(entity2->position, tl_ds_intersection);

									entity2->ephysics.prev_position = entity2->position;
									entity2->position = vector2dAdd(cp_CoM, vector2dScalarMult(collision_distance, new_vector));

									entity2->ephysics.jerk = vector2dScalarMult(entity2->ephysics.bounciness*vector2dMagnitude(entity2->ephysics.jerk), new_vector);
									entity2->ephysics.acceleration = vector2dScalarMult(entity2->ephysics.bounciness*vector2dMagnitude(entity2->ephysics.acceleration), new_vector);
									entity2->ephysics.speed = vector2dScalarMult(entity2->ephysics.bounciness*vector2dMagnitude(entity2->ephysics.speed), new_vector);
								}
							}
						}
					}

					//no need to call it on NULL ptr
					free(collision_points);
				}
			}
		}
	}*/
}