Beispiel #1
0
        public override void Update_Active(object sender, FrameUpdateEventArgs e)
        {
            //sinex += WobbleSpeed * e.ElapsedMilliseconds; // frame rate independend
            sinex += WobbleSpeed * 25;  // used for nonuniformly continuous behavior

            IElasticBody ESprite = Sprite as IElasticBody;

            if (ESprite != null)
            {
                Vector dpos = new Vector(Math.Sin(sinex) * 2, Math.Sin(sinex) * 5);
                dpos *= WobbleAmplitude;
                Vector dsize = new Vector(dpos.X / 2.0, -dpos.Y);

                ESprite.Deformation = new Rect(ESprite.Deformation.Location + dpos,
                                               (Vector)ESprite.Deformation.Size + dsize);
            }
        }
Beispiel #2
0
 public override void Update_Active(object sender, FrameUpdateEventArgs e)
 {
     if (Sprite.IsMovable)
     {
         Vector       nSpeed  = new Vector();
         IElasticBody ESprite = Sprite as IElasticBody;
         if (ESprite != null)
         {
             ESprite.Deformation = new Rect(0, 0, 1, 1);
         }
         // check collisions first
         if (Sprite.IsObstacle)
         {
             (Sprite as IGFXObject).ParentContainer.Collider.Check(Sprite as IGameObject, e);
         }
         // speed threshold in order to avoid oscillations
         nSpeed.X = (Math.Abs(Sprite.NormSpeed.X) < 0.1) ? 0 : Sprite.NormSpeed.X;
         nSpeed.Y = (Math.Abs(Sprite.NormSpeed.Y) < 0.1) ? 0 : Sprite.NormSpeed.Y;
         Vector dpos = GFXAnimation.NormToPixelSpeed(nSpeed) * (e.ElapsedMilliseconds / 1000);
         Sprite.Position += dpos;
         // Reset deformation
     }
 }
Beispiel #3
0
        public void ProcessCollision(IGameObject me, IGameObject other, Rect overlap, Rect rme, Rect rother, double dt)
        {
            double eps      = 1;
            Vector voverlap = new Vector(overlap.Width, overlap.Height);
            Vector dx       = new Vector(0, 0);

            if ((int)overlap.Width == (int)rme.Width)
            {
                dx = voverlap;
                if (rme.Top < rother.Top)
                {
                    dx *= -1;
                }
                dx.X = 0;
            }
            else if ((int)overlap.Height == (int)rme.Height)
            {
                dx = voverlap;
                if (rme.Left < rother.Left)
                {
                    dx *= -1;
                }
                dx.Y = 0;
            }
            else
            {
                Vector v1 = rme.TopLeft - rother.TopLeft;
                Vector v2 = rme.TopRight - rother.BottomLeft;
                Vector v3 = rme.BottomRight - rother.TopLeft;
                Vector v4 = rme.BottomLeft - rother.TopRight;

                if (Math.Abs(voverlap.Length - v3.Length) < eps)
                {
                    dx = -v3;
                }
                else if (Math.Abs(voverlap.Length - v4.Length) < eps)
                {
                    dx = -v4;
                }
                else if (Math.Abs(voverlap.Length - v2.Length) < eps)
                {
                    dx = -v2;
                }
                else if (Math.Abs(voverlap.Length - v1.Length) < eps)
                {
                    dx = -v1;
                }
                // avoid insane jumping off cliffs
                dx = new Vector(Math.Sign(dx.X) * Math.Min(Math.Abs(dx.X), Math.Abs(dx.Y)),
                                Math.Sign(dx.Y) * Math.Min(Math.Abs(dx.X), Math.Abs(dx.Y)));
            }

            #region Animation
            // animation
            if (other.IsMovable)
            {
                if (me is IElasticBody)
                {
                    IElasticBody mel = (me as IElasticBody);
                    //if mel.IsMovable
                    double SpringC = mel.SpringC;
                    double Damping = mel.DampingC;
                    bool   liquid  = false;

                    // me - other; Position is COG;
                    Vector dCOG = me.Position - other.Position;
                    if (dCOG.Length > 0)
                    {
                        dCOG.Normalize();
                    }

                    if (other is IElasticBody)
                    {
                        IElasticBody otherel = (other as IElasticBody);
                        SpringC = 1 / ((1 / SpringC) + (1 / otherel.SpringC));
                        Damping = (Damping + otherel.DampingC) / 2;
                        liquid  = otherel.IsLiquid;
                        if (otherel.isPointMass)
                        {
                            dx = dCOG * dx.Length;
                            // force
                            Vector df = dx * SpringC;
                            mel.NormSpeed += df * dt / me.Weight;

                            // damping
                            double fdamp = Vector.Multiply(other.NormSpeed - me.NormSpeed, dCOG) * Damping; //  force against me
                            Vector vdamp = dCOG * fdamp * dt / me.Weight;
                            mel.NormSpeed += vdamp;
                        }
                        else
                        {
                            dCOG = dx;
                            if (dx.Length > 0)
                            {
                                double fme    = (other.Weight / (me.Weight + other.Weight));
                                double fother = (me.Weight / (me.Weight + other.Weight));
                                me.Position += dx * fme;
                                dx.Normalize();
                                me.NormSpeed    -= -Math.Abs(Vector.Multiply(me.NormSpeed, dx)) * dx * fme;
                                other.NormSpeed += -Math.Abs(Vector.Multiply(other.NormSpeed, dx)) * dx * fother;
                            }
                        }
                    }
                    else
                    {
                        dCOG = dx;
                    }



                    // deformation:
                    double bend = dx.Length / ((Vector)me.Shape.Size).Length;
                    if (bend > 0.2)
                    {
                        bend = 0.2;             // maximales eindellen
                    }
                    // choose one axis to avoid shrinking
                    if (Math.Abs(dCOG.X) > Math.Abs(dCOG.Y))
                    {
                        dCOG = new Vector(dCOG.X, 0);
                    }
                    else
                    {
                        dCOG = new Vector(0, dCOG.X);
                    }
                    if (mel.IsDeformable)
                    {
                        mel.Deformation = new Rect(mel.Deformation.X + Math.Min(0, dCOG.X * bend), mel.Deformation.Y + Math.Min(0, dCOG.Y * bend),     // change position is force from top/left (dCOG*bend >0)
                                                   mel.Deformation.Width - Math.Abs(dCOG.X * bend), mel.Deformation.Height - Math.Abs(dCOG.Y * bend)); // size shrinks always
                    }
                }
            }
            else // not Movable:
            {
                if (me is IElasticBody)
                {
                    IElasticBody mel = (me as IElasticBody);
                    //if mel.IsMovable
                    double SpringC = mel.SpringC;
                    double Damping = mel.DampingC;
                    bool   liquid  = false;
                    if (other is IElasticBody)
                    {
                        IElasticBody otherel = (other as IElasticBody);
                        SpringC = 1 / ((1 / SpringC) + (1 / otherel.SpringC));
                        Damping = (Damping + otherel.DampingC) / 2;
                        liquid  = otherel.IsLiquid;

                        if (dx.Length > 0)
                        {
                            //Vector deform = new Vector(dx.X, dx.Y);
                            mel.NormSpeed += dx * dt * SpringC; // masse ignorieren
                            double bend = dx.Length / ((Vector)me.Shape.Size).Length;
                            if (bend > 0.5)
                            {
                                bend = 0.5;             // maximales eindellen
                            }
                            dx.Normalize();
                            if (liquid)
                            {
                                // Water animator
                                Vector vdamp = -Math.Abs(Vector.Multiply(mel.NormSpeed, dx)) * Damping * dt * mel.NormSpeed / mel.NormSpeed.Length; // masse ignoriert
                                mel.NormSpeed += vdamp;
                            }
                            else
                            {
                                // Ground animator
                                Vector vdamp = -(Vector.Multiply(mel.NormSpeed, dx)) * Damping * dt * (dx / dx.Length); // masse ignoriert
                                mel.NormSpeed += vdamp;
                                if (mel.IsDeformable)
                                {
                                    mel.Deformation = new Rect(mel.Deformation.X, mel.Deformation.Y, mel.Deformation.Width + (dx.X * bend), mel.Deformation.Height + (dx.Y * bend));
                                }
                            }
                        }
                    }
                    else  // RigidBody:
                    {
                        if (dx.Length > 0)
                        {
                            me.Position += dx;
                            dx.Normalize();
                            me.NormSpeed -= -Math.Abs(Vector.Multiply(me.NormSpeed, dx)) * dx;
                        }
                    }
                }
            }
            #endregion
        }