Exemplo n.º 1
0
 public void MakeSplash(double position)
 {
     _wave.MakeSplash(position);
 }
Exemplo n.º 2
0
        public void Update(double dt, IWave wave)
        {
            if (!_alive)
            {
                _deathTime += dt;
                return;
            }

            if (_idleThingTimer > 0)
            {
                _idleThingTimer -= dt;
                if (_idleThingTimer <= 0)
                {
                    _idleThingTimer = -(Rnd.NextDouble() + 0.5) * 4;
                }
            }
            else
            {
                if (_currentFrame != 0)
                {
                    _idleThingTimer = -Math.Max(3, -_idleThingTimer);
                }
                _idleThingTimer += dt;
                if (_idleThingTimer >= 0)
                {
                    _idleThingTimer = 2;
                }
            }

            if (_blinkTimer > 0)
            {
                _blinkTimer -= dt;
                if (_blinkTimer <= 0)
                {
                    if (Rnd.Next(5) == 0)
                    {
                        _blinkTimer = -0.3;
                    }
                    else
                    {
                        _blinkTimer = -(Rnd.NextDouble() + 0.5) * 3;
                    }
                }
            }
            else
            {
                _blinkTimer += dt;
                if (_blinkTimer >= 0)
                {
                    _blinkTimer = 0.02 * 5;
                }
            }

            double prev  = wave.GetHeight(_position.X - HalfInterval);
            double next  = wave.GetHeight(_position.X + HalfInterval);
            double water = wave.GetHeight(_position.X);

            bool isInWater = _position.Y < water;

            if (!_snapped)
            {
                double rot = dt * 3;
                if (_angle < -rot && _wobbleTimer <= 0)
                {
                    _angle += rot;
                }
                else if (_angle > rot && _wobbleTimer <= 0)
                {
                    _angle -= rot;
                }
                else
                {
                    _wobbleTimer += dt * 13;
                    _angle        = Math.Sin(_wobbleTimer) * 0.16;
                }
            }
            else
            {
                _wobbleTimer = 0;
            }

            if (_keepSnap >= 0)
            {
                _keepSnap -= dt;
            }

            if (_snapped && prev < next - 80 && _keepSnap <= 0)
            {
                _snapped = false;
            }

            if (_snapped)
            {
                double newVelY = (water - _position.Y) / dt;
                if (newVelY < _velocity.Y - 80 && _keepSnap <= 0)
                {
                    _snapped  = false;
                    _keepSnap = 0.15;
                }
                else
                {
                    _velocity.Y = newVelY;
                }

                if (prev > next)
                {
                    _angle = Math.Atan2(prev - next, HalfInterval * 2);
                    double alpha  = (prev - next) / (2 * HalfInterval);
                    double accelX = 1000 * alpha / (alpha * alpha + 1);
                    _velocity.X += dt * accelX;
                }
            }
            else
            {
                if (isInWater != _wasInWater)
                {
                    if (!_wasInWater)
                    {
                        wave.MakeSplash(_position.X);
                    }
                    _velocity.Y /= 3;
                    _wasInWater  = isInWater;
                }

                if (_position.Y < water - 20)
                {
                    _velocity.Y += dt * 1300;
                    _velocity.Y /= Math.Pow(1.2, dt);
                }
                else if (_position.Y > water + 20)
                {
                    _velocity.Y -= dt * 1000;
                }

                if (_velocity.Y > 0 && Math.Abs(water - _position.Y) < 10 && _wasInWater && _keepSnap <= 0)
                {
                    _position.Y = water;
                    _velocity.Y = 0;
                    _snapped    = true;
                    _keepSnap   = 0.3;
                }
            }

            double reduce = Math.Abs(_velocity.X) * dt * 0.45;

            if (!_snapped && _position.Y > water)
            {
                reduce = 0;
            }

            if (_velocity.X > reduce)
            {
                _velocity.X -= reduce;
            }
            else if (_velocity.X < -reduce)
            {
                _velocity.X += reduce;
            }
            else
            {
                _velocity.X = 0;
            }

            _position += _velocity * dt;

            int targetFrame = Math.Min(15, Math.Max(-15, (int)Math.Round(_angle * 15 * 1.2)));

            if (!_snapped)
            {
                targetFrame = -15;
            }
            if (targetFrame < -4)
            {
                targetFrame += 4;
            }
            else if (targetFrame > 4)
            {
                targetFrame -= 4;
            }
            else
            {
                targetFrame = 0;
            }

            _frameTimeLeft -= dt;
            if (_frameTimeLeft <= 0)
            {
                _frameTimeLeft = 0;
                if (targetFrame < _currentFrame)
                {
                    _frameTimeLeft = FrameTime;
                    _currentFrame--;
                }
                else if (targetFrame > _currentFrame)
                {
                    _frameTimeLeft = FrameTime;
                    _currentFrame++;
                }
            }

            // _currentFrame = -11;
        }