コード例 #1
0
ファイル: World.cs プロジェクト: Onin1/shootmup
        private void AIMove(object state)
        {
            // block usage if a menu is being displayed
            if (Map.IsPaused)
            {
                return;
            }

            // move the AI
            int       index = (int)state;
            Stopwatch timer = new Stopwatch();

            timer.Start();
            if (Players[index] is AI)
            {
                AI    ai     = Players[index] as AI;
                float xdelta = 0;
                float ydelta = 0;
                float angle  = 0;

                // the timer is reentrant, so only allow one instance to run
                if (System.Threading.Interlocked.CompareExchange(ref ai.RunningState, 1, 0) != 0)
                {
                    return;
                }

                if (ai.IsDead)
                {
                    // drop the current players goodies
                    Map.Drop(ai);
                    ai.SwitchWeapon();
                    Map.Drop(ai);

                    // stop the timer
                    AITimers[index].Dispose();
                    return;
                }

                // NOTE: Do not apply the ZoomFactor (as it distorts the AI when debugging) - TODO may want to allow this while parachuting
                // TODO will likely want to translate into a copy of the list with reduced details
                List <Element> elements      = Map.WithinWindow(ai.X, ai.Y, Constants.ProximityViewWidth, Constants.ProximityViewHeight).ToList();
                var            angleToCenter = Collision.CalculateAngleFromPoint(ai.X, ai.Y, Background.X, Background.Y);
                var            inZone        = Background.Damage(ai.X, ai.Y) > 0;

                if (Constants.CaptureAITrainingData)
                {
                    // capture what the ai sees
                    AITraining.CaptureBefore(ai, elements, angleToCenter, inZone);
                }

                // get action from AI

                var action = ai.Action(elements, angleToCenter, inZone, ref xdelta, ref ydelta, ref angle);

                // turn
                ai.Angle = angle;

                // perform action
                bool result = false;
                Type item   = null;
                switch (action)
                {
                case ActionEnum.Drop:
                    item    = Map.Drop(ai);
                    result |= (item != null);
                    ai.Feedback(action, item, result);
                    break;

                case ActionEnum.Pickup:
                    item    = Map.Pickup(ai);
                    result |= (item != null);
                    ai.Feedback(action, item, result);
                    break;

                case ActionEnum.Reload:
                    var reloaded = ai.Reload();
                    result |= (reloaded == AttackStateEnum.Reloaded);
                    ai.Feedback(action, reloaded, result);
                    break;

                case ActionEnum.Attack:
                    var attack = Map.Attack(ai);
                    result |= attack == AttackStateEnum.FiredAndKilled || attack == AttackStateEnum.FiredWithContact ||
                              attack == AttackStateEnum.MeleeAndKilled || attack == AttackStateEnum.MeleeWithContact;
                    ai.Feedback(action, attack, result);
                    break;

                case ActionEnum.SwitchWeapon:
                    var swap = ai.SwitchWeapon();
                    result |= swap;
                    ai.Feedback(action, null, result);
                    break;

                case ActionEnum.Move:
                case ActionEnum.None:
                    break;

                default: throw new Exception("Unknown ai action : " + action);
                }

                // have the AI move
                float oxdelta = xdelta;
                float oydelta = ydelta;
                var   moved   = Map.Move(ai, ref xdelta, ref ydelta);
                ai.Feedback(ActionEnum.Move, null, moved);

                // ensure the player stays within the map
                if (ai.X < 0 || ai.X > Map.Width || ai.Y < 0 || ai.Y > Map.Height)
                {
                    System.Diagnostics.Debug.WriteLine("Out of bounds");
                }

                if (ai.RecordTraining)
                {
                    // capture what the ai sees
                    AITraining.CaptureAfter(ai, action, oxdelta, oydelta, angle,
                                            action == ActionEnum.None || action == ActionEnum.Move
                        ? moved
                        : result);
                }

                // set state back to not running
                System.Threading.Volatile.Write(ref ai.RunningState, 0);
            }
            timer.Stop();

            if (timer.ElapsedMilliseconds > 100)
            {
                System.Diagnostics.Debug.WriteLine("**AIMove Duration {0} ms", timer.ElapsedMilliseconds);
            }
        }
コード例 #2
0
ファイル: World.cs プロジェクト: Onin1/shootmup
        public void KeyPress(char key)
        {
            // inputs that are accepted while a menu is displaying
            if (Map.IsPaused)
            {
                switch (key)
                {
                // menu
                case Constants.Esc:
                    HideMenu();
                    break;
                }

                return;
            }

            // menu
            if (key == Constants.Esc)
            {
                ShowMenu();
                return;
            }

            // for training we track the human movements (as the supervised set)
            if (Human.RecordTraining)
            {
                // capture what the user sees
                List <Element> elements      = Map.WithinWindow(Human.X, Human.Y, Constants.ProximityViewWidth, Constants.ProximityViewHeight).ToList();
                var            angleToCenter = Collision.CalculateAngleFromPoint(Human.X, Human.Y, Background.X, Background.Y);
                var            inZone        = Background.Damage(Human.X, Human.Y) > 0;
                AITraining.CaptureBefore(Human, elements, angleToCenter, inZone);
            }

            // handle the user input
            ActionEnum action = ActionEnum.None;
            bool       result = false;
            float      xdelta = 0;
            float      ydelta = 0;

            switch (key)
            {
            // move
            case Constants.Down:
            case Constants.Down2:
            case Constants.DownArrow:
                ydelta = 1;
                break;

            case Constants.Left:
            case Constants.Left2:
            case Constants.LeftArrow:
                xdelta = -1;
                break;

            case Constants.Right:
            case Constants.Right2:
            case Constants.RightArrow:
                xdelta = 1;
                break;

            case Constants.Up:
            case Constants.Up2:
            case Constants.UpArrow:
                ydelta = -1;
                break;

            case Constants.Switch:
                action = ActionEnum.SwitchWeapon;
                result = SwitchWeapon(Human);
                break;

            case Constants.Pickup:
            case Constants.Pickup2:
                action = ActionEnum.Pickup;
                result = Pickup(Human);
                break;

            case Constants.Drop3:
            case Constants.Drop2:
            case Constants.Drop4:
            case Constants.Drop:
                action = ActionEnum.Drop;
                result = Drop(Human);
                break;

            case Constants.Reload:
            case Constants.MiddleMouse:
                action = ActionEnum.Reload;
                result = Reload(Human);
                break;

            case Constants.Space:
            case Constants.LeftMouse:
                action = ActionEnum.Attack;
                result = Attack(Human);
                break;

            case Constants.RightMouse:
                // use the mouse to move in the direction of the angle
                float r = (Human.Angle % 90) / 90f;
                xdelta = 1 * r;
                ydelta = 1 * (1 - r);
                if (Human.Angle > 0 && Human.Angle < 90)
                {
                    ydelta *= -1;
                }
                else if (Human.Angle > 180 && Human.Angle <= 270)
                {
                    xdelta *= -1;
                }
                else if (Human.Angle > 270)
                {
                    ydelta *= -1; xdelta *= -1;
                }
                break;
            }

            // if a move command, then move
            if (xdelta != 0 || ydelta != 0)
            {
                action = ActionEnum.Move;
                result = Move(Human, xdelta, ydelta);
            }

            // for training we track the human movements (as the supervised set)
            if (Human.RecordTraining)
            {
                // capture the result
                AITraining.CaptureAfter(Human, action, xdelta, ydelta, Human.Angle, result);
            }
        }