Jypeli  5
The simple game programming library
Oscillator.cs
Siirry tämän tiedoston dokumentaatioon.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 
6 namespace Jypeli.GameObjects
7 {
11  internal abstract class Oscillator : Updatable, Destroyable
12  {
13  protected double t = 0;
14 
15  public IGameObject Object;
16  public Waveform Waveform;
17 
18  public bool IsUpdated { get { return true; } }
19  public bool IsDestroyed { get; private set; }
20 
21  public event Action Destroyed;
22 
23  public Oscillator( IGameObject obj, Waveform waveform )
24  {
25  this.Object = obj;
26  this.Waveform = waveform;
27  }
28 
29  public void Update( Time time )
30  {
31  double dt = time.SinceLastUpdate.TotalSeconds;
32  if ( dt == 0 ) return;
33 
34  t += dt;
35 
36  if ( Waveform.GetDampingMultiplier( t ) < 1e-12 )
37  {
38  Stop();
39  Destroy();
40  }
41 
42  Apply( dt );
43  }
44 
45  protected abstract void Apply( double dt );
46 
47  public void Destroy()
48  {
49  IsDestroyed = true;
50  if ( Destroyed != null ) Destroyed();
51  }
52 
53  public abstract void Stop();
54  }
55 
59  internal class LinearOscillator : Oscillator
60  {
61  public Vector Center;
62  public Vector Axis;
63 
64  public LinearOscillator( IGameObject obj, Vector axis, Waveform waveform )
65  : base( obj, waveform )
66  {
67  this.Axis = axis.Normalize();
68  this.Center = obj.Position - Axis * waveform.Amplitude * Math.Sin( waveform.Phase );
69  this.t = -Game.Time.SinceLastUpdate.TotalSeconds;
70 
71  /*if ( Object is PhysicsObject )
72  {
73  ( (PhysicsObject)obj ).Velocity = Axis * waveform.GetDerivative( 0, Game.Time.SinceLastUpdate.TotalSeconds );
74  }*/
75  }
76 
77  public Vector GetOffset()
78  {
79  return Axis * Waveform.GetValue( t );
80  }
81 
82  protected override void Apply( double dt )
83  {
84  if ( Object is PhysicsObject )
85  {
86  PhysicsObject physObj = (PhysicsObject)Object;
87  double otherVel = physObj.Velocity.ScalarProjection( Axis.LeftNormal );
88  physObj.Velocity = otherVel * Axis.LeftNormal + Axis * Waveform.GetDerivative( t, dt );
89  }
90  else
91  {
92  Object.Position = Center + GetOffset();
93  }
94  }
95 
96  public override void Stop()
97  {
98  if ( Object is PhysicsObject )
99  {
100  ( (PhysicsObject)Object ).StopAxial( Axis );
101  }
102  }
103  }
104 
108  internal class AngularOscillator : Oscillator
109  {
110  public double Direction;
111  public double Center;
112  public Waveform Waveform;
113 
114  public AngularOscillator( IGameObject obj, double dir, Waveform waveform )
115  : base( obj, waveform )
116  {
117  this.Direction = Math.Sign( dir );
118  this.Waveform = waveform;
119  this.Center = obj.Angle.Radians;
120  }
121 
122  protected override void Apply( double dt )
123  {
124  if ( Object is PhysicsObject )
125  {
126  PhysicsObject physObj = (PhysicsObject)Object;
127  physObj.AngularVelocity = Direction * Waveform.GetDerivative( t, dt );
128  }
129  else
130  {
131  Object.Angle = Angle.FromRadians( Center + Direction * Waveform.GetValue( t ) );
132  }
133  }
134 
135  public override void Stop()
136  {
137  if ( Object is PhysicsObject )
138  {
139  ( (PhysicsObject)Object ).StopAngular();
140  }
141  }
142  }
143 }