⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gamemain.cs

📁 说明如何使用托管 Direct3D Mobile 创建一个简单的二维游戏。
💻 CS
📖 第 1 页 / 共 2 页
字号:
//---------------------------------------------------------------------
//  This file is part of the Microsoft .NET Framework SDK Code Samples.
// 
//  Copyright (C) Microsoft Corporation.  All rights reserved.
// 
//This source code is intended only as a supplement to Microsoft
//Development Tools and/or on-line documentation.  See these other
//materials for detailed information regarding Microsoft code samples.
// 
//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//PARTICULAR PURPOSE.
//---------------------------------------------------------------------

using System;
using System.Data;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using System.Globalization;
using GraphicsLibrary;
using InputLibrary;
using Timer;

namespace GameApp
{
    /// <summary>
    /// Encapsulates loading and runnig of the game.  This class contains the
    /// game loop and initialization and is the top-level entry point to the
    /// game.
    /// </summary>
    public class GameMain : IDisposable
    {
        /// <summary>
        /// Minimum seconds that one frame can take i.e., the fastest
        /// framerate.
        /// </summary>
        private const float MinSecondsPerFrame = 1.0F / 50.0F;

        /// <summary>
        /// Maximum seconds that one frame can take i.e., the slowest
        /// framerate.
        /// </summary>
        private const float MaxSecondsPerFrame = 1.0F / 10.0F;

        /// <summary>
        /// The initial estimate of the framerate. This value will only be
        /// used until enough frames have been rendered that we can make
        /// reasonable estimates of the true framerate.
        /// </summary>
        private const float InitialSecondsPerFrame = 1.0F / 25.0F;

        /// <summary>
        /// Total length of time to count down after loading level,
        /// before level is playable.
        /// </summary>
        private const float TotalCountDownTime = 3.5F;

        /// <summary>
        /// Minimum length of time to display the splash screen.
        /// </summary>
        private const float TotalSplashTime = 2.0F;

        /// <summary>
        /// Current frame time in seconds.  This is provided as a static
        /// method accessible throughout the game because the rate can be
        /// variable.
        /// </summary>
        public static float SecondsPerFrame
        { get { return currentSecondsPerFrame; } }

        /// <summary>
        /// Current frame time in seconds.
        /// </summary>
        private static float currentSecondsPerFrame =
            InitialSecondsPerFrame;

        /// <summary>
        /// Specifies if the game is done.  When done, the game exits.
        /// </summary>
        private bool done = false;

        /// <summary>
        /// Graphics instance used by the game.
        /// </summary>
        private IGraphics graphics = null;

        /// <summary>
        /// Input instance used by the game.
        /// </summary>
        private Input gi = null;

        /// <summary>
        /// Stopwatch used by the game for timing the frames.
        /// </summary>
        private Timer.Stopwatch sw = null;

        /// <summary>
        /// Level that is currently loaded in the game.
        /// </summary>
        private Level level = null;

        /// <summary>
        /// User interface that is currently loaded in the game.
        /// </summary>
        private UserInterface ui = null;

        /// <summary>
        /// Intro data displayed before the current level.  This is only valid
        /// once loaded and until the level starts.
        /// </summary>
        private Intro intro = null;

        /// <summary>
        /// Defines the current update method.  This is determined by which
        /// state the game is in.
        /// </summary>
        private UpdateDelegate update = null;
        private delegate void UpdateDelegate();

        /// <summary>
        /// This enum is set by update delegates when the game needs to switch
        /// to a different update mode.  This is not done from within the
        /// update methods because problems can occur when delegate is
        /// modified from within a call to that delegate.
        /// </summary>
        private enum ModeSwitch
        {
            UpdateCountdown,
            UpdateLevel,
            UpdateIntro,
            None
        }
        private ModeSwitch mode = ModeSwitch.None;

        /// <summary>
        /// Splash screen image.  This is only valid while the splash
        /// screen is displayed at the start of the game.
        /// </summary>
        private IBitmap splash = null;

        /// <summary>
        /// Shared instance of the game's random number generator.
        /// </summary>
        private static Random rnd = null;

        /// <summary>
        /// Number of frames since the last auto-update check.
        /// </summary>
        public static Int64 CurrentFrame { get { return numFrames; } }
        private static Int64 numFrames = 0;

        /// <summary>
        /// The number of seconds which have passed for 'numFrames' 
        /// number of frames to have been rendered
        /// </summary>
        private float secondsElapsedForCurrentFrames;

        /// <summary>
        /// Specifies if the intro has finished loading.
        /// </summary>
        private bool introLoaded = false;

        /// <summary>
        /// Specifies if the level has finished loading.
        /// </summary>
        private bool levelLoaded = false;

        /// <summary>
        /// Total time left to countdown before starting the game.
        /// </summary>
        private float countDown = TotalCountDownTime;

        /// <summary>
        /// Rectangle cached for drawing routines to reduce memory
        /// allocations.
        /// </summary>
        Rectangle src = new Rectangle();

        /// <summary>
        /// Specifies if the countdown to start the level should begin.
        /// </summary>
        private bool startCountDown = false;

        /// <summary>
        /// Initializes the game libraries.
        /// </summary>
        /// <param name="owner">Control (Form) that owns the game</param>
        public GameMain(Control owner)
        {
            // Create a Graphics instance
#if USE_GDI
            graphics = new GdiGraphics(owner);
#else
            graphics = new DirectXGraphics(owner);
#endif
            Debug.Assert(graphics != null,
                "GameMain.GameMain: Failed to initialize Graphics object");

            // Create a Input instance
            gi = new Input(owner);
            Debug.Assert(gi != null,
                "GameMain.GameMain: Failed to initialize Input object");

            // Register the hardware buttons
            gi.RegisterAllHardwareKeys();

            // Initialize the random number generator
            rnd = new Random();

            // Create a stopwatch instance for timing the frames
            sw = new Timer.Stopwatch();
            Debug.Assert(sw != null,
                "GameMain.Run: Failed to initialize StopWatch");

        }

        /// <summary>
        /// Get a random float from 0-1.
        /// </summary>
        /// <returns>Random float from 0-1</returns>
        public static float Random()
        {
            return (float)rnd.NextDouble();
        }

        /// <summary>
        /// Get a random number in the specified range.
        /// </summary>
        /// <param name="min">Minimum number to return</param>
        /// <param name="max">Maximum number to return</param>
        /// <returns>Random int in range</returns>
        public static int Random(int min, int max)
        {
            return rnd.Next(min, max);
        }

        /// <summary>
        /// Get the full path to the specified file by prepending it
        /// with the directory of the executable.
        /// </summary>
        /// <param name="fileName">Name of file</param>
        /// <returns>Full path of the file</returns>
        public static string GetFullPath(string fileName)
        {
            Debug.Assert(fileName != null && fileName.Length > 0,
                "GameMain.GetFullPath: Invalid string");

            Assembly asm = Assembly.GetExecutingAssembly();
            string str = asm.GetName().CodeBase;
            string fullName = Path.GetDirectoryName(str);

            // the full name can be a URI (eg file://...) but some of the
            // loader functions can't parse that type of path. Hence we get
            // a path that starts with a drive letter.
            Uri uri = new Uri(Path.Combine(fullName, fileName));
            return uri.LocalPath;
        }

        /// <summary>
        /// Reset the current level.
        /// </summary>
        private void Reset()
        {
            // Reset the game
            level.ResetAll();

            // Clear any latent key presses
            gi.ClearKeyPresses();

            // Do one update of the level so it can be drawn
            level.Update(gi);

            startCountDown = false;
            update = new UpdateDelegate(UpdateCountdown);
            countDown = TotalCountDownTime;
            numFrames = 0;
            secondsElapsedForCurrentFrames = 0;

        }

        /// <summary>
        /// Start the game.  This method loads the game resources and
        /// runs the main game loop.
        /// </summary>
        public void Run()
        {

            // Load and validate the splash screen
            splash = graphics.CreateBitmap(GetFullPath(@"Data\Splash\splash.bmp"), false);
            Debug.Assert(splash != null,
                "GameMain.Run: Failed to initialized splash screen");
            Debug.Assert(splash.Width <= graphics.ScreenWidth &&
                splash.Height <= graphics.ScreenHeight,
                "GameMain.Run: Splash screen has invalid dimensions");

            // Load the game ui now because it has font information that is
            // needed for drawing the 'Loading...' tag
            DataSet dsUI = new DataSet();
            
            Debug.Assert(dsUI != null,
                "GameMain.LoadLevel: Failed to initialize UI DataSet");

            dsUI.Locale = CultureInfo.InvariantCulture;

            // Load the ui xml file
            dsUI.ReadXml(GetFullPath(@"Data\UI\ui.xml"));

            // Load the resources specified in the xml file
            ui = new UserInterface(dsUI, graphics, level);
            Debug.Assert(ui != null,
                "GameMain.LoadLevel: Failed to initialize UI");
            
            // Set the current update method as the splash screen updater
            update = new UpdateDelegate(UpdateSplash);

            // Loop until the game is done
            while (!done)
            {
                // Switch the update delegate if a switch was requested.
                switch (mode)
                {
                    case ModeSwitch.UpdateLevel:
                        gi.ClearKeyPresses();
                        update = new UpdateDelegate(UpdateLevel);
                        numFrames = 0;
                        secondsElapsedForCurrentFrames = 0;
                        break;
                    case ModeSwitch.UpdateCountdown:
                        intro.Dispose();
                        intro = null;
                        level.Update(gi);
                        update = new UpdateDelegate(UpdateCountdown);
                        break;
                    case ModeSwitch.UpdateIntro:
                        LoadLevel();
                        update = new UpdateDelegate(UpdateIntro);
                        splash.Dispose();
                        splash = null;
                        break;
                }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -