#### /Samples/CarGame2D/Car.cs

#
C# | 98 lines | 85 code | 10 blank | 3 comment | 6 complexity | 9514290873e2562d7f41b7cebe9014a6 MD5 | raw file
1using DeltaEngine.Commands;
2using DeltaEngine.Core;
3using DeltaEngine.Datatypes;
4using DeltaEngine.Entities;
5using DeltaEngine.Extensions;
6using DeltaEngine.Rendering2D;
7
8namespace CarGame2D
9{
10	/// <summary>
11	/// Handle our car and the simple physics we need for driving around the track.
12	/// </summary>
13	public sealed class Car : Sprite, Updateable
14	{
15		public Car(Vector2D startPosition, Track setTrack)
16			: base("CarImage", new Rectangle(startPosition, new Size(0.075f, 0.05f)))
17		{
18			track = setTrack;
19			velocity = new Vector2D(1f, 0f);
20			collisionRadius = DrawArea.Width / 2;
21			NextTrackIndex = 0;
22			new Command(Command.MoveLeft,
23				() => velocity = velocity.Rotate(-speed * RotationStep * Time.Delta));
24			new Command(Command.MoveRight,
25				() => velocity = velocity.Rotate(speed * RotationStep * Time.Delta));
26			new Command(Command.MoveUp, () => speed += Time.Delta * 2);
27		}
28
30		private Vector2D velocity;
32		public int NextTrackIndex { get; private set; }
33		private float speed;
34		private const float RotationStep = 100.0f;
35
36		public void Update()
37		{
38			ReduceSpeedAutomaticallyAndLimitIt();
39			CalculateNextTrackIndex();
40			velocity = CalculateVelocity();
41			Center += (velocity * speed) * Time.Delta * 0.2f;
42			float oldRotation = Rotation;
43			Rotation = velocity.GetRotation();
44			if ((oldRotation - Rotation).Abs() > 50)
45				SetWithoutInterpolation(Rotation);
46		}
47
48		private void ReduceSpeedAutomaticallyAndLimitIt()
49		{
50			speed -= Time.Delta;
51			speed = speed.Clamp(0f, MaxSpeed);
52		}
53
54		private const float MaxSpeed = 1.75f;
55
56		private void CalculateNextTrackIndex()
57		{
58			float distanceToNext = (Center - track.Positions[NextTrackIndex]).LengthSquared;
59			if (distanceToNext <= lastDistanceToNext)
60				return;
61			NextTrackIndex++;
62			NextTrackIndex %= track.Positions.Length;
63			lastDistanceToNext = (Center - track.Positions[NextTrackIndex]).LengthSquared;
64		}
65
66		private float lastDistanceToNext;
67
68		private Vector2D CalculateVelocity()
69		{
70			Vector2D carBackward = Center - (velocity * collisionRadius);
71			Vector2D carForward = Center + (velocity * collisionRadius);
72			for (int index = 0; index < track.Positions.Length - 1; index++)
73			{
74				Vector2D inner1 = track.TrackInnerBounds[index];
75				Vector2D inner2 = track.TrackInnerBounds[index + 1];
76				if (MathExtensions.IsLineIntersectingWith(carBackward, carForward, inner1, inner2))
77					return GetVelocityAfterTrackLineCollision(inner1, inner2);
78				Vector2D outer1 = track.TrackOuterBounds[index];
79				Vector2D outer2 = track.TrackOuterBounds[index + 1];
80				if (MathExtensions.IsLineIntersectingWith(carBackward, carForward, outer1, outer2))
81					return GetVelocityAfterTrackLineCollision(outer1, outer2);
82			}
83			return velocity;
84		}
85
86		private Vector2D GetVelocityAfterTrackLineCollision(Vector2D inner1, Vector2D inner2)
87		{
88			SlowDownIfAboveOneThirdOfMaxSpeed();
89			return Vector2D.Normalize(inner2 - inner1);
90		}
91
92		private void SlowDownIfAboveOneThirdOfMaxSpeed()
93		{
94			if (speed > MaxSpeed / 3)
95				speed /= 2.0f;
96		}
97	}
98}