source: 2014/24/EemeliK/Zombieland/Jypeli/GameObjects/PhysicsObject/Movement.cs @ 5974

Revision 5974, 9.6 KB checked in by empaheik, 4 years ago (diff)
Line 
1#region MIT License
2/*
3 * Copyright (c) 2009 University of Jyväskylä, Department of Mathematical
4 * Information Technology.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#endregion
25
26/*
27 * Authors: Tero Jäntti, Tomi Karppinen, Janne Nikkanen.
28 */
29
30using System;
31using Physics2DDotNet.Shapes;
32using AdvanceMath;
33using Physics2DDotNet;
34namespace Jypeli
35{
36    public partial class PhysicsObject
37    {
38        private double _maxAngularV = double.PositiveInfinity;
39        private double _maxLinearV = double.PositiveInfinity;
40
41        /// <summary>
42        /// Olion nopeus.
43        /// </summary>
44        [Save]
45        public Vector Velocity
46        {
47            get
48            {
49                Vector2D v = Body.State.Velocity.Linear;
50                return new Vector( v.X, v.Y );
51            }
52            set { Body.State.Velocity.Linear = new Vector2D( value.X, value.Y ); }
53        }
54
55        /// <summary>
56        /// Olion kulmanopeus.
57        /// </summary>
58        [Save]
59        public double AngularVelocity
60        {
61            get { return Body.State.Velocity.Angular; }
62            set { Body.State.Velocity.Angular = value; }
63        }
64
65        /// <summary>
66        /// Suurin nopeus, jonka olio voi saavuttaa.
67        /// </summary>
68        [Save]
69        public double MaxVelocity
70        {
71            get { return _maxLinearV; }
72            set { _maxLinearV = value; IsUpdated = true; }
73        }
74
75        /// <summary>
76        /// Suurin kulmanopeus, jonka olio voi saavuttaa.
77        /// </summary>
78        [Save]
79        public double MaxAngularVelocity
80        {
81            get { return _maxAngularV; }
82            set { _maxAngularV = value; IsUpdated = true; }
83        }
84
85        /// <summary>
86        /// Olion kiihtyvyys.
87        /// </summary>
88        [Save]
89        public Vector Acceleration
90        {
91            get
92            {
93                Vector2D v = Body.State.Acceleration.Linear;
94                return new Vector( v.X, v.Y );
95            }
96            set { Body.State.Acceleration.Linear = new Vector2D( value.X, value.Y ); }
97        }
98
99        /// <summary>
100        /// Olion kulmakiihtyvyys.
101        /// </summary>
102        [Save]
103        public double AngularAcceleration
104        {
105            get { return Body.State.Acceleration.Angular; }
106            set { Body.State.Acceleration.Angular = value; }
107        }
108
109        [Save]
110        internal Vector ForceAccumulator
111        {
112            get { return new Vector( Body.State.ForceAccumulator.Linear.X, Body.State.ForceAccumulator.Linear.Y ); }
113            set { Body.State.ForceAccumulator.Linear = new Vector2D( value.X, value.Y ); }
114        }
115
116        [Save]
117        internal double AngularForceAccumulator
118        {
119            get { return Body.State.ForceAccumulator.Angular; }
120            set { Body.State.ForceAccumulator.Angular = value; }
121        }
122
123        /// <summary>
124        /// Työntää oliota.
125        /// </summary>
126        /// <param name="force">Voima, jolla oliota työnnetään.</param>
127        public virtual void Push( Vector force )
128        {
129            Body.ApplyForce( new Vector2D( force.X, force.Y ) );
130        }
131
132        /// <summary>
133        /// Työntää oliota tietyn ajan tietyllä voimalla.
134        /// </summary>
135        /// <param name="force">Voima, jolla oliota työnnetään sekunnissa.</param>
136        /// <param name="time">Aika, kuinka kauan voimaa pidetään yllä.</param>
137        public virtual void Push( Vector force, TimeSpan time )
138        {
139            IsUpdated = true;
140            Body.ApplyForce( new Vector2D( force.X, force.Y ) );
141            ActiveForces.Add( new Force( force, time ) );
142        }
143
144        /// <summary>
145        /// Kohdistaa kappaleeseen impulssin. Tällä kappaleen saa nopeasti liikkeeseen.
146        /// </summary>
147        public virtual void Hit( Vector impulse )
148        {
149            Body.ApplyImpulse( new Vector2D( impulse.X, impulse.Y ) );
150        }
151
152        /// <summary>
153        /// Kohdistaa kappaleeseen vääntövoiman. Voiman suunta riippuu merkistä.
154        /// </summary>
155        /// <param name="torque">Vääntövoima.</param>
156        public virtual void ApplyTorque( double torque )
157        {
158            Body.ApplyTorque( torque );
159        }
160
161        /// <summary>
162        /// Pysäyttää olion.
163        /// </summary>
164        public override void Stop()
165        {
166            Body.ClearForces();
167            Body.State.Acceleration = ALVector2D.Zero;
168            Body.State.Velocity = ALVector2D.Zero;
169            Body.State.ForceAccumulator = ALVector2D.Zero;
170            base.Stop();
171        }
172
173        /// <summary>
174        /// Pysäyttää olion liikkeen vaakasuunnassa.
175        /// </summary>
176        public void StopHorizontal()
177        {
178            StopAxial( Vector.UnitX );
179        }
180
181        /// <summary>
182        /// Pysäyttää olion liikkeen pystysuunnassa.
183        /// </summary>
184        public void StopVertical()
185        {
186            StopAxial( Vector.UnitY );
187        }
188
189        /// <summary>
190        /// Pysäyttää liikkeen akselin suunnassa.
191        /// </summary>
192        /// <param name="axis">Akseli vektorina (ei väliä pituudella)</param>
193        public void StopAxial( Vector axis )
194        {
195            StopMoveTo();
196
197            // TODO: Distinguish between horizontal and vertical oscillations
198            ClearOscillations();
199
200            Acceleration = Acceleration.Project( axis.LeftNormal );
201            Velocity = Velocity.Project( axis.LeftNormal );
202
203            Vector oldForce = new Vector( Body.State.ForceAccumulator.Linear.X, Body.State.ForceAccumulator.Linear.Y );
204            Vector newForce = oldForce.Project( axis.LeftNormal );
205            double aForce = Body.State.ForceAccumulator.Angular;
206            Body.State.ForceAccumulator = new ALVector2D( aForce, newForce.X, newForce.Y );
207        }
208
209        /// <summary>
210        /// Pysäyttää kaiken pyörimisliikkeen.
211        /// </summary>
212        public void StopAngular()
213        {
214            Body.State.Acceleration.Angular = 0;
215            Body.State.Velocity.Angular = 0;
216            Body.State.ForceAccumulator.Angular = 0;
217        }
218
219        /// <summary>
220        /// Siirtää oliota.
221        /// </summary>
222        /// <param name="movement">Vektori, joka määrittää kuinka paljon siirretään.</param>
223        public override void Move( Vector movement )
224        {
225            Vector dv = movement - this.Velocity;
226            Hit( Mass * dv );
227        }
228
229        protected override void MoveToTarget()
230        {
231            if ( !moveTarget.HasValue )
232            {
233                Stop();
234                moveTimer.Stop();
235                return;
236            }
237
238            Vector d = moveTarget.Value - AbsolutePosition;
239            double vt = moveSpeed * moveTimer.Interval;
240
241            if ( d.Magnitude < vt )
242            {
243                Vector targetLoc = moveTarget.Value;
244                Stop();
245                moveTimer.Stop();
246                moveTarget = null;
247
248                if ( arrivedAction != null )
249                    arrivedAction();
250            }
251            else
252            {
253                Vector dv = Vector.FromLengthAndAngle( moveSpeed, d.Angle ) - this.Velocity;
254                Hit( Mass * dv );
255            }
256        }
257
258        protected virtual void PrepareThrowable( PhysicsObject obj, Angle angle, double force, double distanceDelta, double axialDelta )
259        {
260            double d = ( this.Width + obj.Width ) / 2 + distanceDelta;
261            Angle a = this.AbsoluteAngle + angle;
262            obj.Position = this.AbsolutePosition + a.GetVector() * d + (a + Angle.RightAngle).GetVector() * axialDelta;
263            obj.Hit( Vector.FromLengthAndAngle( force, a ) );
264        }
265
266        /// <summary>
267        /// Heittää kappaleen hahmon rintamasuuntaa kohti.
268        /// </summary>
269        /// <param name="obj">Heitettävä kappale</param>
270        /// <param name="angle">Suhteellinen kulma (0 astetta suoraan, 90 ylös)</param>
271        /// <param name="force">Heiton voimakkuus</param>
272        /// <param name="distOffset">Offset ammuksen etäisyydelle</param>
273        /// <param name="layer">Pelimaailman kerros</param>
274        /// <param name="axialOffset">Offset ammuksen akselin suuntaiselle paikalle</param>
275        public void Throw( PhysicsObject obj, Angle angle, double force, double distOffset = 0, int layer = 0, double axialOffset = 0 )
276        {
277            PrepareThrowable( obj, angle, force, distOffset, axialOffset );
278            Game.Add( obj, layer );
279        }
280    }
281}
Note: See TracBrowser for help on using the repository browser.