Exemple #1
0
        public void InputLogic(AdvancerConfigBasic2d config, InputBasic2d action, SnapHistory <NentBasic2d, NentStaticBasic2d> h, ref NentBasic2d snap, byte pid, float delta)
        {
            // process the inputs for this action
            snap.XVel = RMathF.Clamp(action.Horizontal, -1f, 1f) * config.PlayerSpeed;
            snap.YVel = RMathF.Clamp(action.Vertical, -1f, 1f) * config.PlayerSpeed;

            // set our rotation, but only if we're not mid-dash
            if (snap.Free1 <= 0)
            {
                snap.Rot = action.Rotation;
            }

            // dash action
            if ((action.Inputs & InputBasic2d.INPUT_A) != 0 &&
                snap.Free1 == 0)
            {
                // if input A is pressed, dash forward according to rotation
                // we use Free1 to store the dash timer. We can only begin a
                // dash if Free1 is equal to 0 (e.g. dash is over).
                snap.Free1 = config.DashTimerMax;

                // we don't need to set XVel/YVel here because this is done
                // in AdvanceLogic
            }

            // finally, do AdvanceLogic over the delta window
            AdvanceLogic(config, h, ref snap, delta);
        }
Exemple #2
0
        private void InputLogic(InputBasic2d action, SnapHistory <NentBasic2d, NentStaticBasic2d> h, byte pid, float delta)
        {
            // process the inputs for this action
            h.Shots[h.CurrentIndex].XVel = RMathF.Clamp(action.Horizontal, -1f, 1f) * PlayerSpeed;
            h.Shots[h.CurrentIndex].YVel = RMathF.Clamp(action.Vertical, -1f, 1f) * PlayerSpeed;

            // set our rotation, but only if we're not mid-dash
            if (h.Shots[h.CurrentIndex].Free1 <= 0)
            {
                h.Shots[h.CurrentIndex].Rot = action.Rotation;
            }

            // dash action
            if ((action.Inputs & InputBasic2d.INPUT_A) != 0 &&
                h.Shots[h.CurrentIndex].Free1 == 0)
            {
                // if input A is pressed, dash forward according to rotation
                // we use Free1 to store the dash timer. We can only begin a
                // dash if Free1 is equal to 0 (e.g. dash is over).
                h.Shots[h.CurrentIndex].Free1 = DashTimerMax;

                // we don't need to set XVel/YVel here because this is done
                // in AdvanceLogic
            }

            // finally, do AdvanceLogic over the delta window
            AdvanceLogic(h, delta);
        }
Exemple #3
0
        public void AngleBlendTest()
        {
            void test(float dega, float degb, float degresult, float percent)
            {
                // check extrema
                AssertFloatEqualsRadians(RMathF.ToRad(dega),
                                         RMathF.AngleBlend(RMathF.ToRad(dega), RMathF.ToRad(degb),
                                                           0));
                AssertFloatEqualsRadians(RMathF.ToRad(degb),
                                         RMathF.AngleBlend(RMathF.ToRad(dega), RMathF.ToRad(degb),
                                                           1f));

                // check midpoint
                AssertFloatEqualsRadians(
                    RMathF.AngleMidpoint(RMathF.ToRad(dega), RMathF.ToRad(degb)),
                    RMathF.AngleBlend(RMathF.ToRad(dega), RMathF.ToRad(degb),
                                      0.5f));

                AssertFloatEqualsRadians(RMathF.ToRad(degresult),
                                         RMathF.AngleBlend(RMathF.ToRad(dega), RMathF.ToRad(degb),
                                                           percent));
            }

            test(100f, 200f, 125f, 0.25f);
            test(200f, 100f, 125f, 0.75f);
            test(100f, 200f, 175f, 0.75f);
            test(200f, 100f, 175f, 0.25f);

            test(350f, 10f, 355f, 0.25f);
            test(10f, 350f, 355f, 0.75f);
            test(350f, 10f, 5f, 0.75f);
            test(10f, 350f, 5f, 0.25f);
        }
Exemple #4
0
        private void AdvanceLogic(SnapHistory <NentBasic2d, NentStaticBasic2d> h, float delta)
        {
            if (h.StaticData.Id2 == NENT_PLAYEROBJ)
            {
                // some special considerations for the playerobject
                if (h.Shots[h.CurrentIndex].Free1 > 0)
                {
                    // if Free1 is over 0, we're in the middle of a dash
                    // this means we're moving quickly in the direction
                    // of our rotation

                    // we're expecting the client to provide rotation in
                    // radians, for the record
                    h.Shots[h.CurrentIndex].XVel = DashSpeed * RMathF.Cos(h.Shots[h.CurrentIndex].Rot);
                    h.Shots[h.CurrentIndex].YVel = DashSpeed * RMathF.Sin(h.Shots[h.CurrentIndex].Rot);

                    // reduce the dash timer
                    h.Shots[h.CurrentIndex].Free1 -= delta;
                    // if we cross 0, set up the cooldown timer
                    if (h.Shots[h.CurrentIndex].Free1 <= 0)
                    {
                        h.Shots[h.CurrentIndex].Free1 = -DashCooldownMax;
                    }

                    // note: something we're not really handling here
                    // is that on the tick that the dash ends, we may
                    // get a few ms of "extra" dash b/c if it has say
                    // 10ms remaining and we have 16ms in the tick,
                    // you're dashing for the full 16ms even though
                    // you should only have 10ms of dash.

                    // you could probably fix this issue if precision
                    // matters in your use case. but for this demo
                    // I think it's outside the scope
                }
                else if (h.Shots[h.CurrentIndex].Free1 < 0)
                {
                    // if we're negative, we're on cooldown
                    // count back up to 0, when we get to 0
                    // the dash is available again.
                    h.Shots[h.CurrentIndex].Free1 += delta;
                    if (h.Shots[h.CurrentIndex].Free1 >= 0)
                    {
                        h.Shots[h.CurrentIndex].Free1 = 0;
                    }
                }
            }

            h.Shots[h.CurrentIndex].X += h.Shots[h.CurrentIndex].XVel * delta;
            h.Shots[h.CurrentIndex].Y += h.Shots[h.CurrentIndex].YVel * delta;
        }
Exemple #5
0
        public void AngleMidpointTest()
        {
            void test(float dega, float degb, float degresult)
            {
                AssertFloatEqualsRadians(RMathF.ToRad(degresult),
                                         RMathF.AngleMidpoint(RMathF.ToRad(dega), RMathF.ToRad(degb)));
                AssertFloatEqualsRadians(RMathF.ToRad(degresult),
                                         RMathF.AngleMidpoint(RMathF.ToRad(degb), RMathF.ToRad(dega)));
            }

            test(45f, 135f, 90f);
            test(30f, 340f, 5f);
            test(200f, 100f, 150f);
            test(10f, 200f, 285f);
        }
Exemple #6
0
        private void InterpolateLogic(SnapHistory <NentBasic2d, NentStaticBasic2d> h, float delta)
        {
            // interpolate from Current forward delta ms
            float tickpercent    = delta / NetSnapper.TickMSTarget;
            float invtickpercent = 1.0f - tickpercent;

            // we don't adjust IDs at all

            // pos/vel is simple, just blend
            h.Shots[h.CurrentIndex].X    = (h.Shots[h.CurrentIndex].X * invtickpercent) + (h.Shots[h.NextIndex].X * tickpercent);
            h.Shots[h.CurrentIndex].Y    = (h.Shots[h.CurrentIndex].Y * invtickpercent) + (h.Shots[h.NextIndex].Y * tickpercent);
            h.Shots[h.CurrentIndex].XVel = (h.Shots[h.CurrentIndex].XVel * invtickpercent) + (h.Shots[h.NextIndex].XVel * tickpercent);
            h.Shots[h.CurrentIndex].YVel = (h.Shots[h.CurrentIndex].YVel * invtickpercent) + (h.Shots[h.NextIndex].YVel * tickpercent);

            // it makes sense to blend Free1 as well since we just
            // use it as a timer, but in other cases this might not
            // be appropriate
            h.Shots[h.CurrentIndex].Free1 = (h.Shots[h.CurrentIndex].Free1 * invtickpercent) + (h.Shots[h.NextIndex].Free1 * tickpercent);

            // rotation is more complicated to blend
            h.Shots[h.CurrentIndex].Rot = RMathF.AngleBlend(h.Shots[h.CurrentIndex].Rot, h.Shots[h.NextIndex].Rot, tickpercent);
        }
Exemple #7
0
        public void BlendLogic(SnapHistory <NentBasic2d, NentStaticBasic2d> h,
                               ref NentBasic2d shot, NentBasic2d blendTarget, float factor)
        {
            // interpolate from Current forward delta ms
            float invfactor = 1.0f - factor;

            // we don't adjust IDs at all

            // pos/vel is simple, just blend
            shot.X    = (shot.X * invfactor) + (blendTarget.X * factor);
            shot.Y    = (shot.Y * invfactor) + (blendTarget.Y * factor);
            shot.XVel = (shot.XVel * invfactor) + (blendTarget.XVel * factor);
            shot.YVel = (shot.YVel * invfactor) + (blendTarget.YVel * factor);

            // it makes sense to blend Free1 as well since we just
            // use it as a timer, but in other cases this might not
            // be appropriate
            shot.Free1 = (shot.Free1 * invfactor) + (blendTarget.Free1 * factor);

            // rotation is more complicated to blend
            shot.Rot = RMathF.AngleBlend(shot.Rot, blendTarget.Rot, factor);
        }
Exemple #8
0
        private void InterpolateSnapLogic(SnapHistory <NentBasic2d, NentStaticBasic2d> h)
        {
            // interpolates from Prev to Next to create Current
            h.Shots[h.CurrentIndex] = h.Shots[h.PrevIndex];

            // always inherit ids from previous
            //h.Prev.Id1 = h.Prev.Id1;
            //h.Prev.Id2 = h.Prev.Id2;

            // pos/vel is easy, just average them
            h.Shots[h.CurrentIndex].X    = (h.Shots[h.NextIndex].X + h.Shots[h.CurrentIndex].X) / 2f;
            h.Shots[h.CurrentIndex].Y    = (h.Shots[h.NextIndex].Y + h.Shots[h.CurrentIndex].Y) / 2f;
            h.Shots[h.CurrentIndex].XVel = (h.Shots[h.NextIndex].XVel + h.Shots[h.CurrentIndex].XVel) / 2f;
            h.Shots[h.CurrentIndex].YVel = (h.Shots[h.NextIndex].YVel + h.Shots[h.CurrentIndex].YVel) / 2f;

            // in our case, we use Free1 as a timer, so it makes
            // sense to average this as well. May not be the case
            // if Free1 is used for a different kind of value
            h.Shots[h.CurrentIndex].Free1 = (h.Shots[h.NextIndex].Free1 + h.Shots[h.CurrentIndex].Free1) / 2f;

            // rotation is more complicated to find the midpoint
            h.Shots[h.CurrentIndex].Rot = RMathF.AngleMidpoint(h.Shots[h.CurrentIndex].Rot, h.Shots[h.NextIndex].Rot);
        }
Exemple #9
0
 public void ClampTest()
 {
     Assert.AreEqual(30f, RMathF.Clamp(20f, 30f, 50f));
     Assert.AreEqual(50f, RMathF.Clamp(90f, 30f, 50f));
     Assert.AreEqual(40f, RMathF.Clamp(40f, 30f, 50f));
 }