🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Implementing a 2d top down door using hinges

Started by
0 comments, last by Ghost_RacCooN 3 years, 11 months ago

So I've been trying to implement a 2d top down door that I want to behave like the doors in the game Darkwood but I'm having trouble getting it to feel even remotely right. So there's a few things to note: the player is an AABB and the door is an OBB, I'm using SAT to detect collisions from them and get the minimum translation vector (mtv) and then I use a simple check to get the collisions points, and after that I translate the player:

		CollisionData collided = CheckIfDoorAgentCollided(&door, player);

		std::vector<vec2<float>> collisionPoints;
		if (collided.collided)
		{
			collisionPoints = GetPointsInsideDoor(&door, player);
			player += V2(collided.mtv.x, collided.mtv.y);
		}

So far so good, I should note that the player does not have any acceleration or anything I just instantly move the player by a fixed velocity when a key is pressed (I suspect this might be a problem). Anyway here's the code I'm struggling with:

		float dt = 0.0005f;
		if (collided.collided)
		{
			if (collisionPoints.size() > 0)
			{
				//Apply the force in the opposite way of the minimum translation vector
				vec2<float> force = -collided.mtv * 3500.0f;
				vec2<float> centerOfMass = door.hingePosition;
				vec2<float> momentArm = collisionPoints[0] - centerOfMass;

				float inertia = 10.0f;
				float torque = Cross(momentArm, force);

				door.angularVelocity += door.angularAcceleration * dt;
				door.angularAcceleration += (torque / inertia) * dt;		

				if (door.angularAcceleration > 20.0f)
				{
					door.angularAcceleration = 20.0f;
				}
				if (door.angularAcceleration < -20.0f)
				{
					door.angularAcceleration = -20.0f;
				}
				door.active = true;
			}
		}

		if (door.active)
		{
			//If we're close to 0 we stop
			if (fabsf(door.angularAcceleration) < 0.0000001f)
			{
				door.angularAcceleration = 0.0f;
				door.angularVelocity = 0.0f;
				door.active = false;
			}
			else
			{
				//I think this is where something more sophisticated is needed
				float fakeFriction = -door.angularAcceleration * 0.08f;
				door.angularAcceleration += fakeFriction;
				door.angularVelocity += door.angularAcceleration * dt;
			}
		}

		door.rotationRadians += door.angularVelocity * dt;

		RotateDoorRadians(&door, door.rotationRadians);

Ignoring all those random float values, its just me trying to find a way to make everything seem more natural. Currently getting the door to stop after no force is applied looks very stiff and I can't find the right values for the player to not start sliding along the door which leads me to believe my approach is wrong, here's how it looks:

As you can see it's very stiff and “slidey”, so I was wondering what else I'd need to make the door more realistic? I'd prefer not having to use something like box2d since I'll only need physics for this one thing.

This topic is closed to new replies.

Advertisement