コード例 #1
0
        /// <summary>
        /// Updates the game each frame.
        /// </summary>
        /// <param name="time">Game time's data</param>
        public override void Update(GameTime time)
        {
            //If winning
            if (m_Victory)
            {
                //Waits 2 seconds
                m_VictoryWait += time.ElapsedGameTime.Milliseconds / 1000.0f;
                if (m_VictoryWait > 2.0f)
                {
                    //Create parameter
                    object[] Parameters = new object[4];
                    Parameters[1] = m_Timer.GetTime();
                    if (m_Player == Player.Klotski)
                    {
                        Parameters[0] = 0;
                    }
                    else
                    {
                        Parameters[0] = 1;
                    }

                    int Movement = 0;
                    foreach (Ship ship in m_Ships)
                    {
                        Movement += ship.GetMoveNumber();
                    }
                    Parameters[2] = Movement;
                    Parameters[3] = 0;

                    //If not player
                    if (m_Player != Player.Klotski)
                    {
                        Parameters[3] = m_VisitedList.Count;
                    }

                    //Go to gameover state
                    Global.StateManager.GoTo(StateID.GameOver, Parameters, true);
                }
            }
            //Otherwise, do the usual update
            else
            {
                //Updates GUI if not editor
                if (m_Player != Player.Storm)
                {
                    int MoveNumber = 0;
                    foreach (Ship ship in m_Ships)
                    {
                        MoveNumber += ship.GetMoveNumber();
                    }
                    m_Counter.SetCounter(MoveNumber, m_VisitedList.Count);
                    m_Timer.Increase(time.ElapsedGameTime);
                }
                else
                {
                    m_Actor.SetLife(3);
                }

                //if player controlled);
                if (m_Player == Player.Klotski || m_Player == Player.Storm)
                {
                    //Check actor collision);
                    foreach (Ship ship in m_Ships)
                    {
                        if (ship.GetBoundingBox().Intersects(m_Actor.GetBoundingBox()))
                        {
                            m_Actor.OnCollision(ship);
                        }
                    }
                }
                else
                {
                    //Check speed change
                    if (InputManager.Keyboard.KeyPushed(Keys.Q))
                    {
                        Ship.DecreaseSpeed();
                    }
                    if (InputManager.Keyboard.KeyPushed(Keys.E))
                    {
                        Ship.IncreaseSpeed();
                    }
                }
                //Updates based on the player
                switch (m_Player)
                {
                    #region Player controlled
                case Player.Storm:
                case Player.Klotski:
                    //Camera switching
                    if (InputManager.Keyboard.KeyPushed(Keys.Tab))
                    {
                        SwitchCamera();
                    }

                    //Controlled character switching
                    if (InputManager.Mouse.ButtonPushed(Mouse.MouseButtons.LeftButton))
                    {
                        //If block is not moving and not in bird's view
                        if (!m_ReadyToUpdate && m_ActiveCamera != m_BirdsView)
                        {
                            //If currently controlling a ship
                            if (m_Controlled != m_Actor)
                            {
                                //Place actor on top of the ship
                                m_Actor.SetPosition(
                                    (m_Controlled.GetBoundingBox().Max.X + m_Controlled.GetBoundingBox().Min.X) / 2.0f,
                                    m_Controlled.GetBoundingBox().Max.Y + 5.0f,
                                    (m_Controlled.GetBoundingBox().Max.Z + m_Controlled.GetBoundingBox().Min.Z) / 2.0f);

                                //Return control to actor
                                m_Actor.SetVisibility(true);
                                m_Controlled = m_Actor;
                            }
                            else
                            {
                                //Get the ship below actor
                                Ship Below = GetShipBelowActor();

                                //If a ship exist
                                if (Below != null)
                                {
                                    //Set as controlled
                                    m_Controlled = Below;

                                    //Turn off actor
                                    m_Actor.SetVisibility(false);
                                }
                            }
                        }
                    }
                    break;

                    #endregion
                    #region AI controlled BFS
                case Player.BFS:
                    //Create iterator if not exist
                    if (m_IteratorStack.Count <= 0)
                    {
                        m_IteratorStack.Push((int)Direction.NegativeY);
                    }

                    //If
                    if (m_Controlled == null || !((Ship)m_Controlled).IsMoving())
                    {
                        //Get stack info
                        int i = (m_IteratorStack.Peek() - (int)Direction.NegativeY) / 5;
                        int j = m_IteratorStack.Peek() - (i * 5);
                        m_IteratorStack.Pop();

                        //While there's no moving block and iterator hasn't finished
                        while (m_Controlled == null && (i * 5) + j < (m_Ships.Count * 5) + (int)Direction.NegativeY)
                        {
                            while (m_Controlled == null && j <= (int)Direction.PositiveY)
                            {
                                //If the ship contains a movement
                                if (m_Ships[i].GetBackDirection() != (Direction)j)
                                {
                                    if (m_Ships[i].GetAvailableMovement().Contains((Direction)j))
                                    {
                                        //Move and Set as active
                                        m_Controlled = m_Ships[i];
                                        m_ShipStack.Push(m_Ships[i]);
                                        m_Ships[i].Move((Direction)j);
                                        m_Depth++;

                                        //Save stack
                                        j++;
                                        if (j > (int)Direction.PositiveY)
                                        {
                                            j = (int)Direction.NegativeY;
                                            i++;
                                        }
                                        m_IteratorStack.Push((i * 5) + j);
                                    }
                                }

                                //Next direction
                                j++;
                            }

                            //Reset j
                            j = (int)Direction.NegativeY;

                            //Next
                            i++;
                        }

                        //If has iterated through all
                        if (m_Controlled == null && i >= m_Ships.Count)
                        {
                            //Increase max depth if at root
                            if (m_Depth == 0)
                            {
                                m_MaxDepth++;
                            }
                            else
                            {
                                //Return via last ship
                                m_Controlled = m_ShipStack.Pop();
                                ((Ship)m_Controlled).Return();
                                m_Depth--;
                            }
                        }
                    }

                    //If moving ship exist
                    if (m_Controlled != null)
                    {
                        //Updates
                        m_Controlled.Update(time);

                        //If not moving
                        if (!((Ship)m_Controlled).IsMoving())
                        {
                            //If maximum depth
                            if (m_Depth >= m_MaxDepth)
                            {
                                //Find current state in list
                                bool     Exist        = false;
                                GameData CurrentState = new GameData();
                                foreach (Ship ship in m_Ships)
                                {
                                    CurrentState.AddShip(ship);
                                }
                                foreach (GameData state in m_VisitedList)
                                {
                                    if (state.Equals(CurrentState))
                                    {
                                        Exist = true;
                                    }
                                }

                                //If not exist
                                if (!Exist)
                                {
                                    m_VisitedList.Add(CurrentState);
                                }

                                ((Ship)m_Controlled).Return();
                                m_ShipStack.Pop();
                                m_Depth--;
                            }
                            else
                            {
                                //If returning, no longer returning, otherwise, add a stack
                                if (((Ship)m_Controlled).Returning)
                                {
                                    ((Ship)m_Controlled).Returning = false;
                                }
                                else
                                {
                                    m_IteratorStack.Push((int)Direction.NegativeY);
                                }

                                //Find a new ship
                                m_Controlled = null;
                            }

                            //Update board
                            CreateBoard();
                            UpdateBoard();
                        }
                    }
                    break;

                    #endregion
                    #region AI controlled DFS
                case Player.DFS:
                    //Create iterator if not exist
                    if (m_IteratorStack.Count <= 0)
                    {
                        m_IteratorStack.Push((int)Direction.NegativeY);
                    }

                    if (m_Controlled == null || !((Ship)m_Controlled).IsMoving())
                    {
                        //Get stack info
                        int x = (m_IteratorStack.Peek() - (int)Direction.NegativeY) / 5;
                        int y = m_IteratorStack.Peek() - (x * 5);
                        m_IteratorStack.Pop();

                        //While there's no moving block and iterator hasn't finished
                        while (m_Controlled == null && (x * 5) + y < (m_Ships.Count * 5) + (int)Direction.NegativeY)
                        {
                            while (m_Controlled == null && y <= (int)Direction.PositiveY)
                            {
                                //If the ship contains a movement
                                if (m_Ships[x].GetBackDirection() != (Direction)y)
                                {
                                    if (m_Ships[x].GetAvailableMovement().Contains((Direction)y))
                                    {
                                        //Move and Set as active
                                        m_Controlled = m_Ships[x];
                                        m_ShipStack.Push(m_Ships[x]);
                                        m_Ships[x].Move((Direction)y);
                                        Console.WriteLine(m_Ships[x].GetBackDirection());

                                        //Save stack
                                        y++;
                                        if (y > (int)Direction.PositiveY)
                                        {
                                            y = (int)Direction.NegativeY;
                                            x++;
                                        }
                                        m_IteratorStack.Push((x * 5) + y);
                                    }
                                }

                                //Next direction
                                y++;
                            }

                            //Reset y
                            y = (int)Direction.NegativeY;

                            //Next
                            x++;
                        }

                        //If has iterated through all
                        if (m_Controlled == null && x >= m_Ships.Count)
                        {
                            //Return via last ship
                            m_Controlled = m_ShipStack.Pop();
                            ((Ship)m_Controlled).Return();
                        }
                    }

                    //If moving ship exist
                    if (m_Controlled != null)
                    {
                        //Updates
                        m_Controlled.Update(time);

                        //If not moving
                        if (!((Ship)m_Controlled).IsMoving())
                        {
                            //Update board
                            CreateBoard();
                            UpdateBoard();

                            //If returning, no longer returning, otherwise, add a stack
                            if (((Ship)m_Controlled).Returning)
                            {
                                ((Ship)m_Controlled).Returning = false;

                                //Find a new ship
                                m_Controlled = null;
                            }
                            else
                            {
                                //Find current state in list
                                bool     Exist        = false;
                                GameData CurrentState = new GameData();
                                foreach (Ship ship in m_Ships)
                                {
                                    CurrentState.AddShip(ship);
                                }
                                foreach (GameData state in m_VisitedList)
                                {
                                    if (state.Equals(CurrentState))
                                    {
                                        Exist = true;
                                    }
                                }

                                //If exist
                                if (Exist)
                                {
                                    ((Ship)m_Controlled).Return();
                                    m_ShipStack.Pop();
                                }
                                else
                                {
                                    m_VisitedList.Add(CurrentState);

                                    m_IteratorStack.Push((int)Direction.NegativeY);

                                    //Find a new ship
                                    m_Controlled = null;
                                }
                            }
                        }
                    }

                    break;
                    #endregion
                }

                //Updating
                #region Entity updating
                //If camera is not bird view
                if (m_ActiveCamera != m_BirdsView && (m_Player == Player.Klotski || m_Player == Player.Storm))
                {
                    //Ensure controlled entity exist
                    if (m_Controlled != null)
                    {
                        //Set active camera
                        m_ActiveCamera = m_Controlled.GetCamera();

                        //Update controlled entity only
                        m_Controlled.UpdateControl(time);
                        m_Controlled.Update(time);
                    }

                    //Update life bar
                    m_LifeBar.SetLife(m_Actor.GetLife());
                    m_LifeBar.Invalidate();

                    //If actor dies
                    if (m_Actor.GetLife() <= 0)
                    {
                        //Create parameter
                        object[] Parameters = new object[4];

                        Parameters[0] = -1;
                        Parameters[1] = new TimeSpan();
                        Parameters[2] = 0;
                        Parameters[3] = 0;

                        //Go to gameover state
                        Global.StateManager.GoTo(StateID.GameOver, Parameters, true);
                    }
                }

                #endregion
                UpdateCamera();
                #region Board updating
                //If currently controlling a ship
                if (m_Controlled is Ship)
                {
                    //If moving, prepare for board update
                    if ((m_Controlled as Ship).IsMoving())
                    {
                        m_ReadyToUpdate = true;
                    }
                    else if (m_ReadyToUpdate)
                    {
                        //Update board
                        CreateBoard();
                        UpdateBoard();

                        //No longer need to update board
                        m_ReadyToUpdate = false;
                    }
                }
                #endregion

                //if escape is pressed
                if (InputManager.Keyboard.KeyPushed(Keys.Escape))
                {
                    //Save actor's data if exist
                    if (m_Actor != null)
                    {
                        m_Actor.SaveState();
                    }

                    //Go to pause state
                    object[] Parameters = new object[1];
                    Parameters[0] = false;
                    if (m_Player == Player.Storm)
                    {
                        Parameters[0] = true;
                    }
                    Global.StateManager.GoTo(StateID.Pause, Parameters);
                }
            }
        }