Exemplo n.º 1
0
        public override void Update(GameTime gameTime, GameEngine.TeeEngine engine)
        {
            // Get the Hero player for interaction purposes.
            Hero player = (Hero)engine.GetEntity("Player");
            Vector2 prevPos = Pos;
            AttackTarget = player;

            // Check if this Bat has died.
            if (HP <= 0)
            {
                this.Opacity -= 0.02f;
                this.Drawables.ResetState(CurrentDrawableState, gameTime);
                if (this.Opacity < 0)
                {
                    if (!_goldGiven) SpawnCoins(engine);
                    engine.RemoveEntity(this);
                }
            }
            else
            {
                // ATTACKING LOGIC.
                if (Stance == AttackStance.Attacking)
                {
                    this.Pos.X -= (float)(Math.Cos(_attackAngle) * _attackSpeed);
                    this.Pos.Y -= (float)(Math.Sin(_attackAngle) * _attackSpeed);
                    this._attackHeight.Y += 30.0f / ATTACK_COUNTER_LIMIT;
                    this.Drawables.SetGroupProperty("Body", "Offset", _attackHeight);

                    onAttack(engine, gameTime);

                }
                // ATTACK PREPERATION LOGIC.
                else if (Stance == AttackStance.Preparing)
                {
                    _attackHeight.Y -= 2;

                    if (_attackHeight.Y < -40)
                    {
                        _attackHeight.Y = -40;
                        _attackAngle = Math.Atan2(
                            this.Pos.Y - player.Pos.Y,
                            this.Pos.X - player.Pos.X
                            );
                        Stance = AttackStance.Attacking;
                        _attackCounter = 0;
                    }

                    Drawables.SetGroupProperty("Body", "Offset", _attackHeight);
                }
                // NON-ATTACKING LOGIC. PATROL AND APPROACH.
                else if (Stance == AttackStance.NotAttacking)
                {
                    double distance = Vector2.Distance(player.Pos, this.Pos);

                    if (distance < AggroDistance && player.HP > 0)
                    {
                        // Move towards the player for an attack move.
                        double angle = Math.Atan2(
                            player.Pos.Y - this.Pos.Y,
                            player.Pos.X - this.Pos.X
                            );

                        // Approach Function.
                        double moveValue;
                        if (distance < AttackDistance)
                        {
                            Stance = AttackStance.Preparing;
                            moveValue = 0;
                        }
                        else
                            moveValue = _moveSpeed;

                        Pos.X += (float)(Math.Cos(angle) * moveValue);
                        Pos.Y += (float)(Math.Sin(angle) * moveValue);
                    }
                    else
                    {
                        // Perform a standard patrol action.
                        Pos.X += (float)(Math.Cos(gameTime.TotalGameTime.TotalSeconds - _randomModifier * 90) * 2);
                    }
                }
                else if (Stance == AttackStance.Retreating)
                {
                    double distance = Vector2.Distance(player.Pos, this.Pos);

                    if (distance < AggroDistance * 1.10)
                    {
                        if (_attackHeight.Y < -10)
                        {
                            _attackHeight.Y += 0.4f;
                            if (_attackHeight.Y > -10)
                                _attackHeight.Y = -10;

                            Drawables.SetGroupProperty("Body", "Offset", _attackHeight);
                        }

                        double angle = Math.Atan2(
                            player.Pos.Y - this.Pos.Y,
                            player.Pos.X - this.Pos.X
                            );

                        Pos.X += (float)(Math.Cos(angle) * -(_moveSpeed * 0.8f));
                        Pos.Y += (float)(Math.Sin(angle) * -(_moveSpeed * 0.8f));
                    }
                    else
                    {
                        Stance = AttackStance.NotAttacking;
                        if (_attackHeight.Y < -10) _attackHeight.Y = -10;
                        Drawables.SetGroupProperty("Body", "Offset", _attackHeight);
                    }
                }

                // Determine the animation based on the change in position.
                if (Math.Abs(prevPos.X - Pos.X) > Math.Abs(prevPos.Y - Pos.Y))
                {
                    if (prevPos.X < Pos.X)
                        this.CurrentDrawableState = Prefix + "Right";
                    if (prevPos.X > Pos.X)
                        this.CurrentDrawableState = Prefix + "Left";
                }
                else
                {
                    if (prevPos.Y < Pos.Y)
                        this.CurrentDrawableState = Prefix + "Down";
                    if (prevPos.Y > Pos.Y)
                        this.CurrentDrawableState = Prefix + "Up";
                }
            }

            base.Update(gameTime, engine);
        }