示例#1
0
        /// <summary>
        /// It will process the A.I. which has been registered to the list.
        /// When the current A.I. is updated and then, when ActiveTime, 
        /// which is specified in the current A.I., 
        /// becomes zero, it will be replaced with the next-to-be-executed A.I.
        /// </summary>
        protected override void OnUpdate(GameTime gameTime)
        {
            if ((ActiveAI == null && NextAI == null) || !activeOn) return;

            //  Change to next AI
            if (ActiveAI == null)
            {
                PlayAI(NextAI, NextAI.ActiveTime);
            }
            else if (NextAI != null && ActiveAI.ActiveTime == 0.0f)
            {
                PlayAI(NextAI, NextAI.ActiveTime);
                nextAI = null;
            }
            else
            {
                //  Process to current AI
                if (ActiveAI != null)
                {
                    ActiveAI.Update(gameTime);

                    if (ActiveAI.ActiveTime > 0.0f)
                        ActiveAI.ActiveTime -= 
                                    (float)gameTime.ElapsedGameTime.TotalSeconds;
                    
                    if( ActiveAI.ActiveTime < 0.0f)
                        ActiveAI.ActiveTime = 0.0f;
                }
            }
        }
示例#2
0
        /// <summary>
        /// by using the index of the registered A.I.,
        /// it specifies the next-to-be-executed A.I.
        /// The active time of the next-to-be-executed A.I. is specified by activeTime.
        /// </summary>
        public void SetNextAI(int index, float activeTime)
        {
            if (!activeOn)
            {
                return;
            }

            nextAI = FindAI(index);

            nextAI.ActiveTime = activeTime;
        }
示例#3
0
        /// <summary>
        /// The specified A.I. will be played.
        /// The active time of the A.I. is specified by activeTime.
        /// The A.I., which has been active so far, will call the
        /// Finish event handler and will be replaced by the newly specified A.I.
        /// When the newly specified A.I. start activating,
        /// Start event handler is called.
        /// </summary>
        private void PlayAI(int index, float activeTime)
        {
            if (!activeOn)
            {
                return;
            }

            AIBase aiBase = FindAI(index);

            PlayAI(aiBase, activeTime);
        }
示例#4
0
        /// <summary>
        /// A new A.I. will be played.
        /// The active time of the A.I. is specified by activeTime.
        /// The A.I., which has been active so far, will be ignored.
        /// </summary>
        public void StartAI(int index, float activeTime)
        {
            if (!activeOn)
            {
                return;
            }

            activeAI = null;
            nextAI   = null;

            PlayAI(index, activeTime);
        }
示例#5
0
        /// <summary>
        /// it adds an A.I. with the specified name to the list.
        /// </summary>
        public int AddAI(string name, AIBase aiBase)
        {
            if (!activeOn)
            {
                return(-1);
            }

            aiBase.Name = name;
            aiList.Add(aiBase);

            return(aiList.IndexOf(aiBase));
        }
示例#6
0
        /// <summary>
        /// The specified A.I. will be played.
        /// The active time of the A.I. is specified by activeTime.
        /// The A.I., which has been active so far, will call the
        /// Finish event handler and will be replaced by the newly specified A.I.
        /// When the newly specified A.I. start activating,
        /// Start event handler is called.
        /// </summary>
        private void PlayAI(AIBase aiBase, float activeTime)
        {
            if (!activeOn)
            {
                return;
            }

            //  Call the finish event of the previous A.I.
            if (activeAI != null)
            {
                activeAI.AIFinish();
            }

            //  Set to new active A.I.
            activeAI            = aiBase;
            activeAI.ActiveTime = activeTime;

            //  Call start event of new A.I.
            activeAI.AIStart();
        }
示例#7
0
        /// <summary>
        /// It will process the A.I. which has been registered to the list.
        /// When the current A.I. is updated and then, when ActiveTime,
        /// which is specified in the current A.I.,
        /// becomes zero, it will be replaced with the next-to-be-executed A.I.
        /// </summary>
        protected override void OnUpdate(GameTime gameTime)
        {
            if ((ActiveAI == null && NextAI == null) || !activeOn)
            {
                return;
            }

            //  Change to next AI
            if (ActiveAI == null)
            {
                PlayAI(NextAI, NextAI.ActiveTime);
            }
            else if (NextAI != null && ActiveAI.ActiveTime == 0.0f)
            {
                PlayAI(NextAI, NextAI.ActiveTime);
                nextAI = null;
            }
            else
            {
                //  Process to current AI
                if (ActiveAI != null)
                {
                    ActiveAI.Update(gameTime);

                    if (ActiveAI.ActiveTime > 0.0f)
                    {
                        ActiveAI.ActiveTime -=
                            (float)gameTime.ElapsedGameTime.TotalSeconds;
                    }

                    if (ActiveAI.ActiveTime < 0.0f)
                    {
                        ActiveAI.ActiveTime = 0.0f;
                    }
                }
            }
        }
示例#8
0
 public virtual void OnAISearchEvent(AIBase aiBase) {}
示例#9
0
        /// <summary>
        /// it adds an A.I. with the specified name to the list.
        /// </summary>
        public int AddAI(string name, AIBase aiBase)
        {
            if (!activeOn) return -1;

            aiBase.Name = name;
            aiList.Add(aiBase);

            return aiList.IndexOf(aiBase);
        }
示例#10
0
 public virtual void OnAIAttackEvent(AIBase aiBase, GameTime gameTime) { }
示例#11
0
 public virtual void OnAIMoveEvent(AIBase aiBase, GameTime gameTime) { }
示例#12
0
 public virtual void OnAITurnRightEvent(AIBase aiBase) { }
示例#13
0
 public virtual void OnAITurnLeftEvent(AIBase aiBase) {}
示例#14
0
        /// <summary>
        /// boss's A.I. function.
        /// turns the body left.
        /// </summary>
        /// <param name="aiBase">current A.I.</param>
        /// <param name="gameTime"></param>
        public override void OnAITurnLeftEvent(AIBase aiBase)
        {
            MoveStop();

            if (aiBase.IsActive)
            {
                float fTurnAngleSpeed = SpecData.TurnAngle;

                //  Turning left
                Rotate(new Vector2(fTurnAngleSpeed, 0.0f));
                ActionTurn(fTurnAngleSpeed);
            }
            else
            {
                if (isMoveBlocked)
                {
                    CollideSphere collideSphere = Collide as CollideSphere;

                    float movingTime = 
                            (float)HelperMath.Randomi(2) + HelperMath.RandomNormal();

                    Vector3 simulateAmount = movingTime *
                        new Vector3(0.0f, 0.0f, SpecData.MoveSpeed);

                    simulateAmount = CalculateVelocity(simulateAmount);

                    Vector3 start = WorldTransform.Translation + 
                                    (WorldTransform.Up * 1.0f);

                    //  Test collision
                    CollisionResult result = HitTestWithWorld(start, Direction);

                    // Is moving way clear?
                    if (result != null)
                    {
                        float moveDistance = (SpecData.MoveSpeed * movingTime);
                        float resultDistance = result.distance - collideSphere.Radius;

                        if (resultDistance > 0.0f)
                        {
                            if (resultDistance < moveDistance)
                            {
                                //  Recalculate moving time for move and stop
                                movingTime *= resultDistance / moveDistance;

                                isMoveBlocked = true;
                            }
                            else
                            {
                                isMoveBlocked = false;
                            }
                        }
                        //  Can't move
                        else
                        {
                            isMoveBlocked = true;
                        }
                    }
                    else
                    {
                        isMoveBlocked = false;
                    }

                    if (isMoveBlocked)
                    {
                        //  turn right
                        SetNextAI(AIType.TurnRight, 90.0f / SpecData.TurnAngle);
                    }
                    else
                    {
                        SetNextAI(AIType.Move, movingTime);
                    }
                }
                else
                    SetNextAI(AIType.Search, 0.2f);
            }
        }
示例#15
0
        /// <summary>
        /// creates and initializes all base A.I.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            //  Entry patrol update function in AI
            AIBase aiSearch = new AIBase();
            aiSearch.Updating += 
                new EventHandler<AIBase.AIUpdateEventArgs>(OnSearchUpdateEvent);
            indexAiSearch = AIContext.AddAI("Search", aiSearch);

            //  Entry move update function in AI
            AIBase aiMove = new AIBase();
            aiMove.Updating += 
                new EventHandler<AIBase.AIUpdateEventArgs>(OnMoveUpdateEvent);
            indexAiMove = AIContext.AddAI("Move", aiMove);

            //  Entry attack update function in AI
            AIBase aiAttack = new AIBase();
            aiAttack.Updating +=
                new EventHandler<AIBase.AIUpdateEventArgs>(OnAttackUpdateEvent);
            indexAiAttack = AIContext.AddAI("Attack", aiAttack);

            //  Entry left turn update function in AI
            AIBase aiTurnLeft = new AIBase();
            aiTurnLeft.Updating += 
                new EventHandler<AIBase.AIUpdateEventArgs>(OnTurnLeftUpdateEvent);
            indexAiTurnLeft = AIContext.AddAI("TurnLeft", aiTurnLeft);

            //  Entry right turn update function in AI
            AIBase aiTurnRight = new AIBase();
            aiTurnRight.Updating += 
                new EventHandler<AIBase.AIUpdateEventArgs>(OnTurnRightUpdateEvent);
            indexAiTurnRight = AIContext.AddAI("TurnRight", aiTurnRight);

            WorldTransform = SpawnPoint;

            //  Remove a collision
            if (colLayerEnemyMech != null)
            {
                if (colLayerEnemyMech.IsContain(Collide))
                    colLayerEnemyMech.RemoveCollide(Collide);
            }

            //  Remove a collision
            if (colLayerAllMech != null)
            {
                if (colLayerAllMech.IsContain(Collide))
                    colLayerAllMech.RemoveCollide(Collide);
            }
        }
示例#16
0
        /// <summary>
        /// tank's A.I. function.
        /// moves to the position and stops when collides with others.
        /// </summary>
        /// <param name="aiBase">current A.I.</param>
        /// <param name="gameTime"></param>
        public override void OnAIMoveEvent(AIBase aiBase, GameTime gameTime)
        {
            if (aiBase.IsActive)
            {
                Vector3 vMoveVelocity = new Vector3(0.0f, 0.0f, SpecData.MoveSpeed);

                CollisionResult result = MoveHitTest(gameTime, vMoveVelocity);
                if (result != null)
                {
                    if (GameSound.IsPlaying(soundMove))
                        GameSound.Stop(soundMove);

                    MoveStop();     //  Cannot move                   
                }
                else
                {
                    Move(vMoveVelocity);

                    if (!GameSound.IsPlaying(soundMove))
                        soundMove = GameSound.Play3D(SoundTrack.TankMove, this);
                }
            }
            else
            {
                if (GameSound.IsPlaying(soundMove))
                    GameSound.Stop(soundMove);

                MoveStop();

                turretAngleSpeed = 0.0f;

                SetNextAI(AIType.Search, HelperMath.RandomNormal());
            }
        }
示例#17
0
        /// <summary>
        /// boss's A.I. function.
        /// attacks when the attack objective is within the shooting range.
        /// Otherwise, it searches for an attack object again.
        /// </summary>
        /// <param name="aiBase">current A.I.</param>
        /// <param name="gameTime"></param>
        public override void OnAIAttackEvent(AIBase aiBase, GameTime gameTime)
        {
            bool fired = false;

            MoveStop();

            //  The enmey weapon reloading
            if (CurrentWeapon.CurrentAmmo == 0 && !IsFiring && !IsReloading)
            {
                ActionReload(CurrentWeapon);
            }
            else if (CurrentWeapon.IsPossibleToFire())
            {
                //  Attack action
                if (currentAction == Action.Melee)
                {
                    //  Waiting for ready to first fire
                    if (this.actionElapsedTime >= 
                                    CurrentWeapon.SpecData.FireDelayTimeTillFirst)
                    {
                        this.actionElapsedTime = 0.0f;
                        
                        WeaponFire();

                        fired = true;
                    }
                    else
                    {
                        this.actionElapsedTime +=
                                        (float)gameTime.ElapsedGameTime.TotalSeconds;
                    }
                }
                else
                {
                    ActionMelee();

                    CurrentWeapon.StopFireSound();
                }
            }

            if (!aiBase.IsActive && fired)
            {
                SetNextAI(AIType.Search, 0.2f);
            }
        }
示例#18
0
        /// <summary>
        /// tank's A.I. function.
        /// checks whether an attack objective is within shooting range.
        /// if it is within shooting range, attacks.  Otherwise, moves.
        /// </summary>
        /// <param name="aiBase">current A.I.</param>
        /// <param name="gameTime"></param>
        public override void OnAISearchEvent(AIBase aiBase)
        {
            if (!aiBase.IsActive)
            {
                //  Searching Player inside fire range
                float distanceBetweenPlayer = 
                    Vector3.Distance(RobotGameGame.SinglePlayer.Position, Position);

                Vector3 targetDirection = 
                    Vector3.Normalize(RobotGameGame.SinglePlayer.Position - Position);

                Vector3 turretDirection = BoneTransforms[indexTurretBone].Forward;

                float dot = Vector3.Dot(turretDirection, targetDirection);
                float angleDiff = MathHelper.ToDegrees(dot);

                if (Math.Abs(angleDiff) < 3.0f)
                {
                    //  Firing inside fire range
                    if (distanceBetweenPlayer <= CurrentWeapon.SpecData.FireRange)
                    {
                        SetNextAI(AIType.Attack, 1.0f);
                    }
                    else
                    {
                        SetNextAI(AIType.Search, 1.0f);
                    }
                }
                else
                {
                    //  Turning right 
                    if (angleDiff > 3.0f)
                    {
                        SetNextAI(AIType.TurnRight, 
                            Math.Abs(angleDiff) / SpecData.TurnAngle);
                    }
                    //  Turning left
                    else if (angleDiff < -3.0f)
                    {
                        SetNextAI(AIType.TurnLeft, 
                            Math.Abs(angleDiff) / SpecData.TurnAngle);
                    }
                    else
                    {
                        throw new InvalidOperationException("Invalid processing");
                    }
                }

                turretAngleSpeed = 0.0f;
            }

            MoveStop();
        }
示例#19
0
 /// <summary>
 /// call attack A.I.
 /// </summary>
 internal void OnAttackUpdateEvent(object sender, AIBase.AIUpdateEventArgs e)
 {
     OnAIAttackEvent(sender as AIBase, e.GameTime);
 }
示例#20
0
 /// <summary>
 /// call turn left A.I.
 /// </summary>
 internal void OnTurnLeftUpdateEvent(object sender, AIBase.AIUpdateEventArgs e)
 {
     OnAITurnLeftEvent(sender as AIBase);
 }
示例#21
0
 /// <summary>
 /// call movement A.I.
 /// </summary>
 internal void OnMoveUpdateEvent(object sender, AIBase.AIUpdateEventArgs e)
 {
     OnAIMoveEvent(sender as AIBase, e.GameTime);
 }
示例#22
0
 /// <summary>
 /// call search A.I.
 /// </summary>
 internal void OnSearchUpdateEvent(object sender, AIBase.AIUpdateEventArgs e)
 {
     OnAISearchEvent(sender as AIBase);
 }
示例#23
0
 /// <summary>
 /// tank's A.I. function.
 /// turns the body left.
 /// </summary>
 /// <param name="aiBase">current A.I.</param>
 /// <param name="gameTime"></param>
 public override void OnAITurnLeftEvent(AIBase aiBase)
 {
     if (aiBase.IsActive)
     {
         turretAngleSpeed = SpecData.TurnAngle;
     }
     else
     {
         SetNextAI(AIType.Search, HelperMath.RandomNormal());
     }
 }
示例#24
0
        /// <summary>
        /// by using the index of the registered A.I., 
        /// it specifies the next-to-be-executed A.I.
        /// The active time of the next-to-be-executed A.I. is specified by activeTime.
        /// </summary>
        public void SetNextAI(int index, float activeTime)
        {
            if (!activeOn) return;

            nextAI = FindAI(index);

            nextAI.ActiveTime = activeTime;
        }
示例#25
0
        /// <summary>
        /// tank's A.I. function.
        /// attacks when the attack objective is within the shooting range.
        /// Otherwise, it searches for an attack object again.
        /// </summary>
        /// <param name="aiBase">current A.I.</param>
        /// <param name="gameTime"></param>
        public override void OnAIAttackEvent(AIBase aiBase, GameTime gameTime)
        {
            MoveStop();

            //  The enmey weapon reloading
            if (CurrentWeapon.CurrentAmmo == 0 && !IsFiring && !IsReloading)
            {
                ActionReload(CurrentWeapon);
            }
            else if (CurrentWeapon.IsPossibleToFire())
            {
                //  If weapon fired, just action fire
                ActionFire();

                WeaponFire();
            }

            turretAngleSpeed = 0.0f;
            SetNextAI(AIType.Search, HelperMath.RandomNormal());
        }
示例#26
0
        /// <summary>
        /// A new A.I. will be played.
        /// The active time of the A.I. is specified by activeTime.
        /// The A.I., which has been active so far, will be ignored.
        /// </summary>
        public void StartAI(int index, float activeTime)
        {
            if (!activeOn) return;

            activeAI = null;
            nextAI = null;

            PlayAI(index, activeTime);
        }
示例#27
0
        /// <summary>
        /// boss's A.I. function.
        /// checks whether there’s an enemy within shooting range.
        /// If there’s an enemy within the shooting range, it will fire, otherwise, 
        /// it moves.
        /// </summary>
        /// <param name="aiBase">current A.I.</param>
        /// <param name="gameTime"></param>
        public override void OnAISearchEvent(AIBase aiBase)
        {
            if (!aiBase.IsActive)
            {
                CollideSphere collideSphere = Collide as CollideSphere;

                //  Searching Player inside fire range
                float distanceBetweenPlayer =
                    Vector3.Distance(RobotGameGame.SinglePlayer.Position, Position);

                Vector3 vTargetDirection =
                    Vector3.Normalize(RobotGameGame.SinglePlayer.Position - Position);

                float dotRight = Vector3.Dot(Right, vTargetDirection);
                float dotDirection = Vector3.Dot(Direction, vTargetDirection);
                float angle = MathHelper.ToDegrees(dotRight);
                
                //  Forward area
                if (dotDirection > 0.0f)
                {
                    //  Turning right 
                    if (angle > 5.0f)
                    {
                        SetNextAI(AIType.TurnRight, Math.Abs(angle) / 
                            SpecData.TurnAngle);
                    }
                    //  Turning left
                    else if (angle < -5.0f)
                    {
                        SetNextAI(AIType.TurnLeft, Math.Abs(angle) / 
                            SpecData.TurnAngle);
                    }
                    else
                    {
                        //  Firing inside fire range
                        if (distanceBetweenPlayer <= CurrentWeapon.SpecData.FireRange)
                        {
                            SetNextAI(AIType.Attack, 1.0f);
                        }
                        // Trace to player
                        else
                        {
                            float movingTime = (float)HelperMath.Randomi(2) +
                                HelperMath.RandomNormal();

                            Vector3 simulateAmount = movingTime *
                                new Vector3(0.0f, 0.0f, SpecData.MoveSpeed);

                            simulateAmount = CalculateVelocity(simulateAmount);

                            Vector3 start = WorldTransform.Translation +
                                            (WorldTransform.Up * 1.0f);

                            //  Test collision
                            CollisionResult result = HitTestWithWorld(start, Direction);

                            // clear moving way ?
                            if (result != null)
                            {
                                float moveDistance = (SpecData.MoveSpeed * movingTime);
                                float resultDistance = 
                                    result.distance - collideSphere.Radius;

                                if (resultDistance > 0.0f)
                                {
                                    if (resultDistance < moveDistance)
                                    {
                                        //  Recalculate moving time for move and stop
                                        movingTime = resultDistance / moveDistance;

                                        isMoveBlocked = true;
                                    }
                                    else
                                    {
                                        isMoveBlocked = false;
                                    }
                                }
                                //  Can't move
                                else
                                {
                                    isMoveBlocked = true;
                                }
                            }
                            else
                            {
                                isMoveBlocked = false;
                            }

                            if (isMoveBlocked)
                            {
                                //  turn
                                if (dotRight > 1.0f)
                                {
                                    SetNextAI(AIType.TurnRight,
                                        90.0f / SpecData.TurnAngle);
                                }
                                else
                                {
                                    SetNextAI(AIType.TurnLeft,
                                        90.0f / SpecData.TurnAngle);
                                }
                            }
                            else
                            {
                                SetNextAI(AIType.Move, movingTime);
                            }
                        }
                    }
                }
                //  Behind area
                else
                {
                    //  turn
                    if (dotRight > 1.0f)
                        SetNextAI(AIType.TurnRight, 90.0f / SpecData.TurnAngle);
                    else
                        SetNextAI(AIType.TurnLeft, 90.0f / SpecData.TurnAngle);
                }

                if (this.CurrentAction != Action.Idle)
                    ActionIdle();

                MoveStop();
            }
        }
示例#28
0
        /// <summary>
        /// The specified A.I. will be played.
        /// The active time of the A.I. is specified by activeTime.
        /// The A.I., which has been active so far, will call the 
        /// Finish event handler and will be replaced by the newly specified A.I.
        /// When the newly specified A.I. start activating, 
        /// Start event handler is called.
        /// </summary>
        private void PlayAI(AIBase aiBase, float activeTime)
        {
            if (!activeOn) return;

            //  Call the finish event of the previous A.I.
            if (activeAI != null)
                activeAI.AIFinish();

            //  Set to new active A.I.
            activeAI = aiBase;
            activeAI.ActiveTime = activeTime;

            //  Call start event of new A.I.
            activeAI.AIStart();
        }
示例#29
0
        /// <summary>
        /// boss's A.I. function.
        /// moves to the position and stops when collides with others.
        /// </summary>
        /// <param name="aiBase">current A.I.</param>
        /// <param name="gameTime"></param>
        public override void OnAIMoveEvent(AIBase aiBase, GameTime gameTime)
        {
            if (aiBase.IsActive)
            {
                Vector3 moveVelocity = new Vector3(0.0f, 0.0f, SpecData.MoveSpeed);

                Vector3 simulateAmount = 
                                CalculateVelocityPerFrame(gameTime, moveVelocity);

                //  Check moving area
                CollisionResult result = MoveHitTestWithMech(simulateAmount);

                //  If moving way is blocked
                if (result != null)
                {
                    MoveStop();

                    Vector3 oppositeDirection =
                        Vector3.Negate(GetMoveAt(this.Velocity));

                    //  Move to reverse direction
                    AddPosition(oppositeDirection * Math.Abs(result.distance));

                    //  Crash with player, and attacking
                    if (result.detectedCollide.Owner is GamePlayer)
                    {
                        SetNextAI(AIType.Attack, 0.5f);
                    }
                    else
                    {
                        //  turn to right
                        SetNextAI(AIType.TurnRight, 90.0f / SpecData.TurnAngle);
                    }
                }
                else
                {
                    //  Critical damage
                    if (IsCriticalDamaged)
                        MoveStop();
                    else
                        Move(moveVelocity);
                }
            }
            else
            {
                //  If moving way is blocked
                if (isMoveBlocked)
                {
                    //  turn to right
                    SetNextAI(AIType.TurnRight, 90.0f / SpecData.TurnAngle);
                }
                else
                {
                    MoveStop();

                    SetNextAI(AIType.Search, 0.2f);
                }
            }

            ActionMovement(gameTime, Velocity);
        }
示例#30
0
        /// <summary>
        /// mech's A.I. function.
        /// attacks an attack objective if it is within shooting range.
        /// If not, searches for an attack objective again.
        /// </summary>
        /// <param name="aiBase">current A.I.</param>
        /// <param name="gameTime"></param>
        public override void OnAIAttackEvent(AIBase aiBase, GameTime gameTime)
        {
            MoveStop();

            //  The enmey weapon reloading
            if (CurrentWeapon.CurrentAmmo == 0 && !IsFiring && !IsReloading)
            {
                ActionReload(CurrentWeapon);
            }
            else if (CurrentWeapon.IsPossibleToFire())
            {
                //  Attack action
                if (currentAction == Action.Fire)
                {
                    //  Waiting for ready to first fire
                    if (this.fireDelayElapsedTime >=
                                    CurrentWeapon.SpecData.FireDelayTimeTillFirst)
                    {
                        this.fireDelayElapsedTime = 0.0f;

                        WeaponFire();
                    }
                    else
                    {
                        this.fireDelayElapsedTime +=
                                        (float)gameTime.ElapsedGameTime.TotalSeconds;
                    }
                }
                else
                {
                    ActionFire();
                }
            }

            if (!aiBase.IsActive && currentAction != Action.Fire)
            {
                SetNextAI(AIType.Search, HelperMath.RandomNormal());
            }
        }