コード例 #1
0
ファイル: ParticleGenerator.cs プロジェクト: rcorre/MSH-win8
        private Particle newParticle(Vector2 pos, float angle, Vector2 sourceVelocity)
        {
            Particle particle = new Particle();

            particle.Position = pos;
            float directionAngle = (float)MathHelper.ToRadians((XnaHelper.RandomAngle(angle, _arc)));
            float speed          = applyVariance(_particleSpeed, _speedVariance);

            particle.Velocity = speed * XnaHelper.VectorFromAngle(directionAngle);
            particle.Scale    = applyVariance(_particleScale, _scaleVariance);
            particle.Angle    = angle;
            particle.LifeTime = TimeSpan.FromSeconds(applyVariance((float)_particleLife.TotalSeconds, _particleLifeVariance));

            if (Reversed)
            {
                float secondsAlive = (float)particle.LifeTime.TotalSeconds;
                //start at the end
                particle.Position = particle.Position + particle.Velocity * secondsAlive;
                //comment above and uncomment below for a cool effect (unintentional side effect while working on particles.
                //not sure why it looks so awesome, but it does)
                //particle.Position = particle.Position + particle.Velocity * secondsAlive * (1 - _particleDecelerationFactor);

                //movce in reverse
                particle.Velocity = Vector2.Negate(particle.Velocity);
                //start at end scale
                particle.Scale = _particleScale + _scaleRate * secondsAlive;
                //start at end rotation
                particle.Angle = _particleRotationSpeed * secondsAlive;
            }

            particle.Velocity += sourceVelocity;
            return(particle);
        }
コード例 #2
0
        protected void lookThisWay(Vector2 direction)
        {
            SpriteState spriteDirection;

            float angle = XnaHelper.RadiansFromVector(direction);

            if (angle > -Math.PI / 4 && angle < Math.PI / 4)
            {
                spriteDirection = SpriteState.FaceUp;
            }
            else if (angle >= Math.PI / 4 && angle < 3 * Math.PI / 4)
            {
                spriteDirection = SpriteState.FaceRight;
            }
            else if (angle > 3 * Math.PI / 4 || angle < -3 * Math.PI / 4)
            {
                spriteDirection = SpriteState.FaceDown;
            }
            else
            {
                spriteDirection = SpriteState.FaceLeft;
            }

            _sprite.AnimationState = (int)spriteDirection;
        }
コード例 #3
0
        private void handleInput(InputManager input)
        {
            if (input.Exit)
            {
                this.PopState = true;
            }

            if (_blackHole.State == BlackHole.BlackHoleState.Exhausted)
            {
                return;
            }

            _player.MoveDirection = input.MoveDirection;
            _player.LookDirection = XnaHelper.DirectionBetween(_player.Center, input.MouseLocation);

            if (input.FirePrimary && _player.UnitLifeState == PhysicalUnit.LifeState.Living)
            {
                _primaryWeapon.Trigger(_player.Position, input.MouseLocation);
            }
            if (input.FireSecondary && _player.UnitLifeState == PhysicalUnit.LifeState.Living)
            {
                _secondaryWeapon.Trigger(_player.Position, input.MouseLocation);
            }

            if (input.TriggerGadget1)
            {
                _primaryGadget.Trigger();
            }

            if (input.DebugKey)
            {
                _blackHole.Explode();
            }
        }
コード例 #4
0
        public void CheckAndApplyUnitCollision(PhysicalUnit other)
        {
            if (!Collides)
            {
                return;     //don't check collision if unit shouldn't collide
            }
            //special shattered collision detection
            if (_lifeState == LifeState.Shattered)
            {
                tempRec.Width  = _hitRect.Width / ICE_DIVISIONS;
                tempRec.Height = _hitRect.Height / ICE_DIVISIONS;
                for (int i = 0; i < ICE_DIVISIONS; i++)
                {
                    for (int j = 0; j < ICE_DIVISIONS; j++)
                    {
                        tempRec.X = (int)(_fragments[i, j].Position.X - tempRec.Width / 2);
                        tempRec.Y = (int)(_fragments[i, j].Position.Y - tempRec.Height / 2);
                        if (tempRec.Intersects(other.HitRect))
                        {
                            Vector2 fVel  = _fragments[i, j].Velocity;
                            float   fMass = (float)Mass / (ICE_DIVISIONS * ICE_DIVISIONS);
                            temp            = other.Velocity;
                            other._velocity = (other._velocity * (other.Mass - fMass) + 2 * fMass * fVel) /
                                              (fMass + other.Mass);
                            _fragments[i, j].Velocity = (fVel * (fMass - other.Mass) + 2 * other.Mass * temp) /
                                                        (fMass + other.Mass);
                        }
                    }
                }
                return; //ignore normal collision detection
            }

            //check if fire should be transferred
            float dist = XnaHelper.DistanceBetweenRects(HitRect, other.HitRect);

            if (dist < FIRE_SPREAD_DISTANCE)
            {
                if (_statusEffects.Fire > other._statusEffects.Fire)
                {
                    StatEffect transfer = new StatEffect()
                    {
                        Fire = FIRE_SPREAD_FACTOR * dist / FIRE_SPREAD_DISTANCE * _statusEffects.Fire
                    };
                    other.ApplyStatus(transfer);
                    ApplyStatus(transfer * -FIRE_SPREAD_LOSS);
                }
            }

            if (XnaHelper.RectsCollide(HitRect, other.HitRect))
            {
                temp = other._velocity; //temp is a static reusable vector

                other._velocity = (other._velocity * (other.Mass - this.Mass) + 2 * this.Mass * this._velocity) /
                                  (this.Mass + other.Mass);
                this._velocity = (this._velocity * (this.Mass - other.Mass) + 2 * other.Mass * temp) /
                                 (this.Mass + other.Mass);
            }
        }
コード例 #5
0
        protected override void UpdateWeapon(GameTime gameTime)
        {
            switch (_hookState)
            {
            case (HookState.Idle):
            {
                if (_firing)
                {
                    _hookState    = HookState.Fired;
                    _hookPosition = _owner.Position;
                    _hookAngle    = XnaHelper.RadiansFromVector(_fireDirection);
                    _hookVelocity = _fireDirection * HOOK_SPEED;
                }
                break;
            }

            case (HookState.Fired):
            {
                if (!(_firing) &&
                    Vector2.Distance(_hookPosition, _owner.Position) < MAX_RANGE)
                {
                    _hookPosition += _hookVelocity;
                    _hookHitRect.X = (int)_hookPosition.X;
                    _hookHitRect.Y = (int)_hookPosition.Y;
                }
                else
                {
                    _hookState = HookState.Retracting;
                }

                break;
            }

            case (HookState.Retracting):
            {
                _hookPosition -= HOOK_SPEED * Vector2.Normalize(_hookPosition - _owner.Center);
                if (XnaHelper.PointInRect(_hookPosition, _owner.HitRect))
                {
                    _hookState = HookState.Idle;
                }
                break;
            }

            case (HookState.Attached):
            {
                _hookPosition = _hookedUnit.Center;
                Vector2 pullForce = HOOK_FORCE * XnaHelper.DirectionBetween(_owner.Position, _hookedUnit.Position);
                _owner.ApplyForce(pullForce);
                _hookedUnit.ApplyForce(Vector2.Negate(pullForce));

                if (_firing)
                {
                    _hookState = HookState.Idle;
                }
                break;
            }
            }
        }
コード例 #6
0
 /// <summary>
 /// Move the sprite in the given direction based on its moveForce property
 /// </summary>
 /// <param name="direction">Direction to move. Should be normalized for normal movement.</param>
 private void moveThisWay(Vector2 direction, GameTime gameTime)
 {
     //apply movement force, taking into account cryo effect (which slows)
     ApplyForce(_moveForce * direction * (1 - _statusEffects.Cryo / MAX_STAT_EFFECT));
     if (_movementParticleEffect != null)
     {
         _movementParticleEffect.Spawn(Center, XnaHelper.DegreesFromVector(-direction), gameTime.ElapsedGameTime, _velocity);
     }
 }
コード例 #7
0
        public bool PositionInLight(Vector2 position)
        {
            // if the angle isn't zero, then it's a cone-shaped light TODO: this isn't actually true
            if (Angle != 0)
            {
                return(XnaHelper.IsPointInsideTriangle(GetVertices(), position));
            }

            return(false);
        }
コード例 #8
0
        private void setPosition(Vector2 blackHolePosition, Vector2 playerPosition, int levelWidth, int levelHeight)
        {   //set bounds on new spawn location
            bool leftSide = (XnaHelper.RandomInt(0, 1) == 0);

            _position.X   = leftSide ? 0 : levelWidth;
            _hitRect.X    = leftSide ? 0 : levelWidth - _hitRect.Width;
            _sprite.FlipH = !leftSide;
            _position.Y   = XnaHelper.RandomInt(0, levelHeight);
            _hitRect.Y    = (int)_position.Y;
        }
コード例 #9
0
ファイル: HookShot.cs プロジェクト: rcorre/MSH-win8
 public override void CheckAndApplyCollision(PhysicalUnit unit, TimeSpan time)
 {
     if (_hookState == HookState.Fired || _hookState == HookState.Retracting)
     {
         if (XnaHelper.RectsCollide(_hookHitRect, unit.HitRect))
         {
             _hookedUnit = unit;
             _hookState  = HookState.Attached;
         }
     }
 }
コード例 #10
0
        protected override void UpdateWeapon(GameTime gameTime)
        {
            if (_firing)
            {
                _attackParticleEffect.Spawn(_owner.Center, XnaHelper.DegreesFromVector(_fireDirection),
                                            gameTime.ElapsedGameTime, _owner.Velocity);
                //recoil
                _owner.ApplyImpact(-_recoil * _fireDirection, 1);
            }

            _attackParticleEffect.Update(gameTime);
        }
コード例 #11
0
        /// <summary>
        /// Attempt to fire a weapon.
        /// Only fires if enough time has passed since the last fire and enough ammo is available
        /// </summary>
        /// <param name="firePosition"></param>
        /// <param name="targetPosition"></param>
        public void Trigger(Vector2 firePosition, Vector2 targetPosition)
        {
            if (_currentAmmo >= _ammoConsumption && _tillNextFire.TotalSeconds <= 0)
            {
                _firing            = true;
                _fireDirection     = XnaHelper.DirectionBetween(firePosition, targetPosition);
                _targetDestination = targetPosition;

                _currentAmmo -= _ammoConsumption;
                _tillNextFire = _fireDelay;
            }
        }
コード例 #12
0
        private void setPosition(Vector2 blackHolePosition, int levelWidth, int levelHeight)
        {   //set bounds on new spawn location
            int minX, maxX, minY, maxY;

            //spawn in bounds -- default for burst wave
            minX = 0;
            maxX = levelWidth;
            minY = 0;
            maxY = levelHeight;

            if (_isTrickleWave)     //spawn out of bounds
            {
                switch (XnaHelper.RandomInt(0, 3))
                {
                case 0:         //top
                    minX = -OUT_OF_BOUNDS_SPAWN_BUFFER;
                    maxX = levelWidth + OUT_OF_BOUNDS_SPAWN_BUFFER;
                    minY = -OUT_OF_BOUNDS_SPAWN_BUFFER;
                    maxY = 0;
                    break;

                case 1:         //right
                    minX = levelWidth;
                    maxX = levelWidth + OUT_OF_BOUNDS_SPAWN_BUFFER;
                    minY = -OUT_OF_BOUNDS_SPAWN_BUFFER;
                    maxY = levelHeight + OUT_OF_BOUNDS_SPAWN_BUFFER;
                    break;

                case 2:         //bottom
                    minX = -OUT_OF_BOUNDS_SPAWN_BUFFER;
                    maxX = levelWidth + OUT_OF_BOUNDS_SPAWN_BUFFER;
                    minY = levelHeight;
                    maxY = levelHeight + OUT_OF_BOUNDS_SPAWN_BUFFER;
                    break;

                case 3:         //left
                    minX = -OUT_OF_BOUNDS_SPAWN_BUFFER;
                    maxX = 0;
                    minY = -OUT_OF_BOUNDS_SPAWN_BUFFER;
                    maxY = levelHeight + OUT_OF_BOUNDS_SPAWN_BUFFER;
                    break;
                }
            }

            XnaHelper.RandomizeVector(ref _spawnLocation, minX, maxX, minY, maxY);

            //if spawned too close to black hole, try again
            if ((_spawnLocation - blackHolePosition).Length() < MIN_BLACKHOLE_SPAWN_DISTANCE)
            {
                setPosition(blackHolePosition, _levelBounds.Width, _levelBounds.Height);
            }
        }
コード例 #13
0
ファイル: Weapon.cs プロジェクト: rcorre/MSH-win8
        /// <summary>
        /// Attempt to fire a weapon. Return true if successfull
        /// Only fires if enough time has passed since the last fire
        /// </summary>
        /// <param name="firePosition"></param>
        /// <param name="targetPosition"></param>
        public bool Trigger(Vector2 firePosition, Vector2 targetPosition)
        {
            if (_tillNextFire.TotalSeconds <= 0)
            {
                _firing            = true;
                _fireDirection     = XnaHelper.DirectionBetween(firePosition, targetPosition);
                _targetDestination = targetPosition;

                _tillNextFire = _fireDelay;
                return(true);
            }
            return(false);
        }
コード例 #14
0
        public void Update(GameTime gameTime, Rectangle levelBounds, Vector2 blackHolePosition)
        {
            if (_lifeState == LifeState.Dormant)
            {
                _startTime -= gameTime.ElapsedGameTime;
                if (_startTime <= TimeSpan.Zero)
                {
                    _lifeState  = LifeState.Living;
                    CanInteract = true;
                    setWaypoint(blackHolePosition, levelBounds.Width, levelBounds.Height);
                    setPosition(blackHolePosition, levelBounds.Width, levelBounds.Height);
                }
            }
            else if (_lifeState == LifeState.Living)
            {
                _duration -= gameTime.ElapsedGameTime;
                if (_duration < TimeSpan.Zero)
                {
                    _lifeState  = LifeState.Ghost;
                    CanInteract = false;
                }
                if (Vector2.Distance(_nextWaypoint, Position) < MIN_WAYPOINT_DISTANCE)
                {
                    setWaypoint(blackHolePosition, levelBounds.Width, levelBounds.Height);
                }

                MoveDirection = XnaHelper.DirectionBetween(Position, _nextWaypoint);
            }
            else if (_lifeState == LifeState.Ghost)
            {
                MoveDirection       = XnaHelper.DirectionBetween(Position, _nextWaypoint);
                _leaveTimer        -= gameTime.ElapsedGameTime;
                _sprite.ScaleFactor = MathHelper.Lerp(0.0f, 1.0f, (float)_leaveTimer.TotalSeconds / LEAVE_LEVEL_TIME);
                _sprite.Shade       = Color.Lerp(Color.Transparent, Color.White, (float)_leaveTimer.TotalSeconds / LEAVE_LEVEL_TIME);
                if (_leaveTimer < TimeSpan.Zero)
                {
                    _lifeState = LifeState.Destroyed;
                }
            }


            if (Vector2.Distance(_nextWaypoint, Position) < MIN_WAYPOINT_DISTANCE)
            {
                setWaypoint(blackHolePosition, levelBounds.Width, levelBounds.Height);
            }

            base.Update(gameTime, levelBounds);
        }
コード例 #15
0
        private void setWaypoint(Vector2 blackHolePosition, int levelWidth, int levelHeight)
        {   //set bounds on new spawn location
            int minX, maxX, minY, maxY;

            //spawn in bounds
            minX = 0;
            maxX = levelWidth;
            minY = 0;
            maxY = levelHeight;

            //keep reselecting position until find a position far enough from black hole
            do
            {
                XnaHelper.RandomizeVector(ref _nextWaypoint, minX, maxX, minY, maxY);
            }while (Vector2.Distance(blackHolePosition, _nextWaypoint) < MIN_BLACKHOLE_DISTANCE);
        }
コード例 #16
0
        public override void CheckAndApplyCollision(PhysicalUnit unit, TimeSpan time)
        {
            if (!_firing || !unit.Collides)
            {
                return;     //don't check collisions if not firing
            }
            float fireAngle = XnaHelper.RadiansFromVector(_fireDirection);

            if (XnaHelper.RectangleIntersectsArc(unit.HitRect, _owner.Center, _range, fireAngle, _hitArc))
            {
                _tempVector = unit.Center - _owner.Center;
                _tempVector.Normalize();
                unit.ApplyImpact(_force * _tempVector, 1);
                unit.ApplyDamage(_damage);
            }
        }
コード例 #17
0
ファイル: Enemy.cs プロジェクト: rcorre/MSH-win8
        public virtual void Update(GameTime gameTime, Vector2 playerPosition, Vector2 blackHolePosition, Rectangle levelBounds)
        {
            Vector2 directionToPlayer = XnaHelper.DirectionBetween(Position, playerPosition);

            MoveDirection = directionToPlayer;
            LookDirection = directionToPlayer;
            if (_meleeWeapon != null)
            {
                _meleeWeapon.Update(gameTime);

                if ((playerPosition - Position).Length() <= _meleeWeapon.Range && _lifeState == LifeState.Living)
                {
                    _meleeWeapon.Trigger(Center, playerPosition);
                }
            }
            base.Update(gameTime, levelBounds);
        }
コード例 #18
0
        private void setPosition(Vector2 blackHolePosition, int levelWidth, int levelHeight)
        {   //set bounds on new spawn location
            int minX, maxX, minY, maxY;

            //spawn in bounds -- default for burst wave
            minX = 0;
            maxX = levelWidth;
            minY = 0;
            maxY = levelHeight;

            switch (XnaHelper.RandomInt(0, 3))
            {
            case 0:         //top
                minX = -OUT_OF_BOUNDS_SPAWN_BUFFER;
                maxX = levelWidth + OUT_OF_BOUNDS_SPAWN_BUFFER;
                minY = -OUT_OF_BOUNDS_SPAWN_BUFFER;
                maxY = 0;
                break;

            case 1:         //right
                minX = levelWidth;
                maxX = levelWidth + OUT_OF_BOUNDS_SPAWN_BUFFER;
                minY = -OUT_OF_BOUNDS_SPAWN_BUFFER;
                maxY = levelHeight + OUT_OF_BOUNDS_SPAWN_BUFFER;
                break;

            case 2:         //bottom
                minX = -OUT_OF_BOUNDS_SPAWN_BUFFER;
                maxX = levelWidth + OUT_OF_BOUNDS_SPAWN_BUFFER;
                minY = levelHeight;
                maxY = levelHeight + OUT_OF_BOUNDS_SPAWN_BUFFER;
                break;

            case 3:         //left
                minX = -OUT_OF_BOUNDS_SPAWN_BUFFER;
                maxX = 0;
                minY = -OUT_OF_BOUNDS_SPAWN_BUFFER;
                maxY = levelHeight + OUT_OF_BOUNDS_SPAWN_BUFFER;
                break;
            }

            do
            {
                XnaHelper.RandomizeVector(ref _position, minX, maxX, minY, maxY);
            }while (Vector2.Distance(blackHolePosition, _position) < MIN_BLACKHOLE_DISTANCE);
        }
コード例 #19
0
 private void shatter()
 {
     _lifeState = LifeState.Shattered;
     for (int row = 0; row < ICE_DIVISIONS; row++)
     {
         for (int col = 0; col < ICE_DIVISIONS; col++)
         {
             _fragments[row, col].Health     = FRAGMENT_HEALTH * _statusEffects.Cryo / MAX_STAT_EFFECT;
             _fragments[row, col].Position.X = Position.X + (0.5f + _sprite.Width * (float)col / ICE_DIVISIONS);
             _fragments[row, col].Position.Y = Position.Y + (0.5f + _sprite.Height * (float)row / ICE_DIVISIONS);
             XnaHelper.RandomizeVector(ref _fragments[row, col].Velocity, -FRAGMENT_MAX_VELOCITY, FRAGMENT_MAX_VELOCITY,
                                       -FRAGMENT_MAX_VELOCITY, FRAGMENT_MAX_VELOCITY);
             Vector2.Add(ref _fragments[row, col].Velocity, ref _velocity, out _fragments[row, col].Velocity);
             Vector2.Multiply(ref _fragments[row, col].Velocity, FRAGMENT_VELOCITY_FACTOR, out _fragments[row, col].Velocity);
             _fragments[row, col].Angle           = 0f;
             _fragments[row, col].AngularVelocity = XnaHelper.RandomAngle(0.0f, FRAGMENT_MAX_ANGULAR_VELOCITY);
             _fragments[row, col].ScaleFactor     = 1f;
             _fragments[row, col].Active          = true;
         }
     }
 }
コード例 #20
0
        public List <Vector2> GetFarseerVertices()
        {
            // create a list of vectors
            List <Vector2> vertices = new List <Vector2>();

            Vector2 a = Vector2.Zero;

            // the second vector is the first endpoint, which should take into account angle and range, where angle takes into account where the light is aimed
            Vector2 b = Engine.Physics.PositionToPhysicsWorld(new Vector2(Range / 1.5f, Range / 1.5f));

            b = XnaHelper.RotateVector2(b, Angle - MathHelper.PiOver2 + 0.17f, a);

            // the third vector is the second endpoint, which should take into account angle, range, and the light's "fov", or the light's interior angle
            Vector2 c = XnaHelper.RotateVector2(b, Fov, Vector2.Zero);

            vertices.Add(a);
            vertices.Add(b);
            vertices.Add(c);

            return(vertices);
        }
コード例 #21
0
        public List <Vector2> GetVertices()
        {
            // create a list of vectors
            List <Vector2> vertices = new List <Vector2>();

            // the first vector is the light's position
            Vector2 a = Position;

            // the second vector is the first endpoint, which should take into account angle and range, where angle takes into account where the light is aimed
            Vector2 b = Position + new Vector2(Range / 1.5f, Range / 1.5f);

            b = XnaHelper.RotateVector2(b, Angle - MathHelper.PiOver2 + 0.17f, a);

            // the third vector is the second endpoint, which should take into account angle, range, and the light's "fov", or the light's interior angle
            Vector2 c = XnaHelper.RotateVector2(b, Fov, a);

            vertices.Add(a);
            vertices.Add(b);
            vertices.Add(c);

            return(vertices);
        }
コード例 #22
0
ファイル: ProjectileWeapon.cs プロジェクト: rcorre/MSH-win8
        protected override void UpdateWeapon(GameTime gameTime)
        {
            _contactEffect.Update(gameTime);
            _destinationEffect.Update(gameTime);
            _proximityEffect.Update(gameTime);

            int projectilesToSpawn = _firing ? _projectilesPerFire : 0;

            foreach (Projectile p in _projectiles)
            {
                if (p.ProjectileState == Projectile.State.Dormant &&
                    projectilesToSpawn > 0)
                {
                    float rotAngle = XnaHelper.RandomAngle(0, _spread);
                    Matrix.CreateRotationZ(MathHelper.ToRadians(rotAngle), out tempMatrix);
                    p.Initialize(_owner.Position, Vector2.Transform(_fireDirection, tempMatrix),
                                 _projectileInfo, _targetDestination, _owner.Velocity,
                                 _contactEffect, _destinationEffect,
                                 _proximityEffect);
                    projectilesToSpawn--;
                }

                p.Update(gameTime);
            }

            System.Diagnostics.Debug.Assert(projectilesToSpawn == 0, "did not spawn all projectiles", "Number left: " + projectilesToSpawn,
                                            new object[] { this });

            if (_fireParticleEffect != null)
            {
                if (_firing)
                {
                    _fireParticleEffect.Spawn(
                        _owner.Position, XnaHelper.DegreesFromVector(_fireDirection),
                        gameTime.ElapsedGameTime, _owner.Velocity);
                }
                _fireParticleEffect.Update(gameTime);
            }
        }
コード例 #23
0
        public virtual void Update(GameTime gameTime, Rectangle levelBounds)
        {
            switch (_lifeState)
            {
            case LifeState.Living:
            case LifeState.Ghost:
            {
                if (Panicked)
                {
                    _panicTimer -= gameTime.ElapsedGameTime;
                    if (_panicTimer <= TimeSpan.Zero)
                    {
                        _panicTimer = TimeSpan.FromSeconds(PANIC_DIRECTION_CHANGE_FREQUENCY);
                        XnaHelper.RandomizeVector(ref _moveDirection, -1, 1, -1, 1);
                        _lookDirection = _moveDirection;
                    }
                }
                lookThisWay(LookDirection);
                if (MoveDirection.Length() > 0)
                {
                    moveThisWay(MoveDirection, gameTime);
                }

                //handle burning
                ApplyDamage(_statusEffects.Fire * (float)gameTime.ElapsedGameTime.TotalSeconds * FIRE_DPS);

                break;
            }

            case LifeState.Disabled:
            case LifeState.Frozen:
            {
                if (_statusEffects.Cryo <= 0)
                {
                    _lifeState = LifeState.Living;
                    //still cold after defrosting
                    _statusEffects.Cryo = MAX_STAT_EFFECT / 2;
                }
                break;
            }

            case LifeState.Shattered:
            {
                for (int y = 0; y < ICE_DIVISIONS; y++)
                {
                    for (int x = 0; x < ICE_DIVISIONS; x++)
                    {
                        _fragments[x, y].Angle       += _fragments[x, y].AngularVelocity * (float)gameTime.ElapsedGameTime.TotalSeconds;
                        _fragments[x, y].Position    += _fragments[x, y].Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;
                        _fragments[x, y].Velocity    += _fragments[x, y].Acceleration * (float)gameTime.ElapsedGameTime.TotalSeconds;
                        _fragments[x, y].Acceleration = Vector2.Zero;
                        _fragments[x, y].Health      -= FRAGMENT_MELT_RATE * (float)gameTime.ElapsedGameTime.TotalSeconds;
                        _fragments[x, y].ScaleFactor  = _fragments[x, y].Health / FRAGMENT_HEALTH * FRAGMENT_SCALE_FACTOR;
                        XnaHelper.ClampVector(ref _fragments[x, y].Velocity, FRAGMENT_MAX_VELOCITY, out _fragments[x, y].Velocity);
                        if (_fragments[x, y].BeingEaten)
                        {
                            _fragments[x, y].Health -= FRAGMENT_EAT_RATE * (float)gameTime.ElapsedGameTime.TotalSeconds;
                        }
                    }
                }
                return;
            }

            case LifeState.BeingEaten:
            {
                _sprite.ScaleFactor -= BLACK_HOLE_EAT_SCALE_FACTOR * (float)gameTime.ElapsedGameTime.TotalSeconds;
                if (_sprite.ScaleFactor <= 0)
                {
                    _lifeState = LifeState.Destroyed;
                }
                break;
            }

            case LifeState.Destroyed:
            default:
            {
                return;             //don't update anything
            }
            }

            stayInBounds(levelBounds.Width, levelBounds.Height);
            _velocity += _acceleration * (float)gameTime.ElapsedGameTime.TotalSeconds;
            Position  += _velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;
            controlVelocity(_maxSpeed, gameTime.ElapsedGameTime);
            _sprite.Angle += _angularVelocity * (float)gameTime.ElapsedGameTime.TotalSeconds;

            LookDirection = Vector2.Zero;
            MoveDirection = Vector2.Zero;
            _acceleration = Vector2.Zero;

            if (_movementParticleEffect != null)
            {
                _movementParticleEffect.Update(gameTime);
            }

            //burning visual effect
            _burningParticleEffect.Spawn(Position, 0.0f, gameTime.ElapsedGameTime, _velocity);
            _burningParticleEffect.IntensityFactor = _statusEffects.Fire / MAX_STAT_EFFECT;
            _burningParticleEffect.Update(gameTime);

            //cryo visual effect
            if (_statusEffects.Cryo > 0 && _lifeState != LifeState.Disabled)
            {
                _sprite.Shade = Color.Lerp(Color.White, Color.Blue, _statusEffects.Cryo / MAX_STAT_EFFECT);
            }

            _hitRect.X = (int)Position.X - _hitRect.Width / 2;
            _hitRect.Y = (int)Position.Y - _hitRect.Height / 2;

            //manage stat effects
            if (_statusEffects.Cryo >= MAX_STAT_EFFECT && _lifeState != LifeState.Frozen)
            {
                _lifeState          = LifeState.Frozen;
                _iceIntegrity       = maxHealth * ICE_INTEGRITY_FACTOR;
                _statusEffects.Fire = 0;    //stop burning if frozen
            }

            //decrement every stat effect based on status resist
            _statusEffects -= _statusResist * (float)gameTime.ElapsedGameTime.TotalSeconds;
            _statusEffects.Clamp(0, MAX_STAT_EFFECT);

            _sprite.Update(gameTime);
        }
コード例 #24
0
        public void Update(GameTime gameTime, Rectangle levelBounds, Vector2 blackHolePos, Vector2 targetPos, Rectangle playerRect)
        {
            _standingEffect.Update(gameTime);
            _chargeEffect.Update(gameTime);
            _explodeEffect.Update(gameTime);
            _sprite.Update(gameTime);

            switch (_state)
            {
            case State.Dormant:
                if (SpawnEnable)
                {
                    _timer -= gameTime.ElapsedGameTime;
                }

                if (_timer <= TimeSpan.Zero)
                {
                    setPosition(blackHolePos, targetPos, levelBounds.Width, levelBounds.Height);
                    _gravity.Position = _position;
                    _state            = State.Appearing;
                    _timer            = TimeSpan.FromSeconds(APPEAR_TIME);
                }
                break;

            case State.Appearing:
                _timer -= gameTime.ElapsedGameTime;
                if (_timer <= TimeSpan.Zero)
                {
                    _timer        = TimeSpan.FromSeconds(MAX_SCAN_TIME);
                    _lockOnTimer  = TimeSpan.FromSeconds(LOCK_ON_TIME);
                    _state        = State.Scanning;
                    _sprite.Shade = Color.White;
                }
                else
                {
                    _standingEffect.Spawn(_position, XnaHelper.DegreesFromVector(_direction), gameTime.ElapsedGameTime, Vector2.Zero);
                    _sprite.Shade = Color.Lerp(Color.Transparent, Color.White,
                                               (APPEAR_TIME - (float)_timer.TotalSeconds) / APPEAR_TIME);
                }
                break;

            case State.Scanning:
                _timer -= gameTime.ElapsedGameTime;
                _standingEffect.Spawn(_position, XnaHelper.DegreesFromVector(_direction), gameTime.ElapsedGameTime, Vector2.Zero);
                _position.Y += scanVelocity(targetPos.Y - _position.Y) * (float)gameTime.ElapsedGameTime.TotalSeconds;
                _hitRect.Y   = (int)_position.Y - _hitRect.Height / 2;
                //scan for player
                //check if player found or scan time up
                if (_hitRect.Top < targetPos.Y && targetPos.Y < _hitRect.Bottom)
                {
                    _lockOnTimer -= gameTime.ElapsedGameTime;
                }
                if (_lockOnTimer < TimeSpan.Zero || _timer < TimeSpan.Zero)
                {
                    _timer     = TimeSpan.FromSeconds(CHARGE_TIME);
                    _state     = State.Locked;
                    _direction = _sprite.FlipH ? -Vector2.UnitX : Vector2.UnitX;
                }
                break;

            case State.Locked:
                _timer -= gameTime.ElapsedGameTime;
                if (_timer < TimeSpan.Zero)
                {
                    _state = State.Charging;
                    Vector2.Multiply(ref _direction, MOVE_SPEED, out _velocity);
                }
                break;

            case State.Charging:
                //trace movement path
                for (int i = 0; i < PARTICLE_SPAWN_GRANULARITY; i++)
                {
                    _position.X += _velocity.X * (float)gameTime.ElapsedGameTime.TotalSeconds / PARTICLE_SPAWN_GRANULARITY;
                    float angle = (_sprite.FlipH) ? 90 : -90;
                    _chargeEffect.Spawn(_position, angle, gameTime.ElapsedGameTime, Vector2.Zero);
                }
                _hitRect.X = (int)_position.X - _hitRect.Width;

                _gravity.Position = _position;
                if (outOfBounds(levelBounds.Width, levelBounds.Height))
                {
                    _sprite.Reset();
                    _timer = _spawnTime;
                    _state = State.Dormant;
                }
                break;

            case State.BeingEaten:
                _timer -= gameTime.ElapsedGameTime;
                //_explodeEffect.Spawn(_position, 0.0f, gameTime.ElapsedGameTime, Vector2.Zero);
                if (_timer <= TimeSpan.Zero)
                {
                    _state = State.Dormant;
                    _timer = _spawnTime;
                }
                break;
            }
        }