XNA-製作一個遊戲時間

XNA-製作一個遊戲時間

    之所以需要再遊戲中製作一個屬於遊戲的時間是為了製作暫停這項功能,有些遊戲有需要非常明確地指出遊戲時間,這類的遊戲就必須做一個屬於遊戲自己的時間,為了能夠製作暫停之後玩家不知道會停多久,然後再按繼續遊戲,這時就會需要這項功能。

    這裡會使用到遊戲預設給我們的繼承GameTime下來的gameTime物件,分別使用到TotalGameTime和ElapsedGameTime這兩個功能,之後再去取看你是要分還是秒等等的成員變數可以任君取用,型態都是double,因此存放的變數也必須是double的資料型態。

  • TotalGameTime ==> 遊戲程式開始到現在的時間
  • ElapsedGameTime ==> 回傳Update函數和上一個Update函數呼叫之間的時間

    因此我們在程式方面就必須注意到若要存放TotalGameTime的變數,不管是分還是秒等其他的,只需要用指派給一個變數就可以記錄從開啟遊戲到目前所有的時間了。

double minute = gameTime.TotalGameTime.TotalMinutes;

    而ElapsedGameTime裡面的分和秒都只會回傳和上一個Update函數呼叫之間的時間,因此需要有一個紀錄遊戲時間的變數,如果遊戲不是暫停狀態就一直加ElapsedGameTime裡的成員變數,暫停的話則不加,如此就可以做到一個屬於遊戲的時間了。

double gamesecond += gameTime.ElapsedGameTime.TotalSeconds;

    此範例還需要用到數值轉成字串的函數,因為我最後印在螢幕上的是字串而不是數值,所以需要將數值轉換成字串的動作才可,Convert底下ToString的函數,參數就是一個變數數值的型態不管是int float double皆可,然後就指派給一個字串型態的變數即可。

String 字串變數 = Convert.ToString(數值變數);

    再來是處裡字串的動作,會需要用到字串變數下的Substring函數,最主要是要存放從哪個字到哪個字結束,參數是從哪個字串開始到哪個字串。

字串變數 = 字串變數.Substring(0, 5); => 這樣即代表存放0到5之間的字串

    接下來就是實作一個小小範例程式,很簡單的去看時間暫停和繼續後遊戲時間的功能,按P就代表暫停,能夠看見下排的遊戲時間會停注,而上排的開啟遊戲到目前為止的時間則會繼續的改變,按S鍵的話,下排的遊戲時間就會繼續從剛剛暫停的時間開始計算。

程式範例:


using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace MakeGameTime
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteFont Font;
        double allminute;       //開啟遊戲到目前為止的所有時間-分
        double allsecond;       //開啟遊戲到目前為止的所有時間-秒
        double gameminute;      //遊戲中真正的時間-分
        double gamesecond;      //遊戲中真正的時間-秒
        Vector2 allminutepos;   //存放開啟遊戲到目前為止分的位置
        Vector2 allsecondpos;   //存放開啟遊戲到目前為止秒的位置
        Vector2 gameminutepos;  //存放遊戲真正的時間分的位置
        Vector2 gamesecondpos;  //存放遊戲真正的時間秒的位置
        KeyboardState oldState = Keyboard.GetState();    //用來偵測按鍵的變數
        bool pass;              //遊戲暫停狀態

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            allminutepos = new Vector2(0,0);
            allsecondpos = new Vector2(200, 0);
            gameminutepos = new Vector2(0, 25);
            gamesecondpos = new Vector2(200, 25);
            pass = false;
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Font = Content.Load<SpriteFont>("SpriteFont1");
        }

        protected override void UnloadContent()
        {
        
        }

        protected override void Update(GameTime gameTime)
        {
            //讀取開啟遊戲到目前為止的所有時間
            allminute = gameTime.TotalGameTime.TotalMinutes;
            allsecond = gameTime.TotalGameTime.TotalSeconds;
            KeyboardState newState = Keyboard.GetState();
            //按下按鍵P就是遊戲暫停
            if (newState.IsKeyDown(Keys.P))            
            {
                if (!oldState.IsKeyDown(Keys.P))
                {
                    pass = true;
                }
            }
            //按下按鍵S就是繼續遊戲
            if (newState.IsKeyDown(Keys.S))
            {
                if (!oldState.IsKeyDown(Keys.S))
                {
                    pass = false;
                }
            }
            newState = oldState;
            if (pass == false)
            {
                //讀取遊戲中真正的時間
                gameminute += gameTime.ElapsedGameTime.TotalMinutes;
                gamesecond += gameTime.ElapsedGameTime.TotalSeconds;
            }
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            String allminutetxt = Convert.ToString(allminute);
            String allsecondtxt = Convert.ToString(allsecond);
            String gameminutetxt = Convert.ToString(gameminute);
            String gamesecondtxt = Convert.ToString(gamesecond);
            if (allminutetxt.Length>1)
                allminutetxt = allminutetxt.Substring(0, 1);
            if (allsecondtxt.Length>1)
                allsecondtxt = allsecondtxt.Substring(0, 5);
            GraphicsDevice.Clear(Color.Black);
            spriteBatch.Begin();
            spriteBatch.DrawString(Font, allminutetxt, allminutepos, Color.Yellow);
            spriteBatch.DrawString(Font, allsecondtxt, allsecondpos, Color.Yellow);
            spriteBatch.DrawString(Font, gameminutetxt, gameminutepos, Color.Yellow);
            spriteBatch.DrawString(Font, gamesecondtxt, gamesecondpos, Color.Yellow);
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}

1

    當然這個只是範例而已,還有需要改良的地方就是當遊戲時間的秒數超過60的時候,需要適時的做歸0的動作,才府何時間的運算。

最後附上專案檔MakeGameTime.rar