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

📄 dodger.cs

📁 学习Managed directx3d的很好的资料,VC#源码实例,共包括6章,其中第四章为:创建三维地形
💻 CS
📖 第 1 页 / 共 2 页
字号:
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;

namespace Dodger
{

    /// <summary>
    /// Structure used to maintain high scores
    /// </summary>
    public struct HighScore
    {
        private int realScore;
        private string playerName;
        public int Score { get { return realScore; } set { realScore = value; } }
        public string Name { get { return playerName; } set { playerName = value; } }
    }

    /// <summary>
	/// Summary description for DodgerGame.
	/// </summary>
	public class DodgerGame : System.Windows.Forms.Form
	{
        // Constant values for the locations
        public const float RoadLocationLeft = 2.5f;
        public const float RoadLocationRight = -2.5f;
        private const float RoadSize = 100.0f;
        private const float MaximumRoadSpeed = 250.0f;
        private const float RoadSpeedIncrement = 0.5f;

        // Depth locations of the two 'road' meshes we will draw
        private float RoadDepth0 = 0.0f;
        private float RoadDepth1 = -100.0f;
        private float RoadSpeed = 30.0f;

        private float elapsedTime = 0.0f;

        // Rendering device
        private Device device = null;

        // Game board mesh information
        private Mesh roadMesh = null;
        private Material[] roadMaterials = null;
        private Texture[] roadTextures = null;

        // Game information
        private bool isGameOver = true;
        private int gameOverTick = 0;
        private bool hasGameStarted = false;
        private int score = 0;

        // Obstacle information
        private Obstacles obstacles;

        // Car
        private Car car = null;

        // Fonts
        private Direct3D.Font scoreFont = null;
        private Direct3D.Font gameFont = null;

        // High score information
        private HighScore[] highScores = new HighScore[3];
        private string defaultHighScoreName = string.Empty;

        // Obstacle height constant
        private const float ObstacleHeight = Car.Height * 0.85f;

        public DodgerGame()
        {
            this.Size = new Size(800,600);
            this.Text = "Dodger Game";

            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);

            LoadHighScores();
        }


        /// <summary>
        /// Here we will load all the default game options
        /// </summary>
        private void LoadDefaultGameOptions()
        {
            // Road information
            RoadDepth0 = 0.0f;
            RoadDepth1 = -100.0f;
            RoadSpeed = 30.0f;
            // Car data information
            car.Location = RoadLocationLeft;
            car.Speed = 10.0f;
            car.IsMovingLeft = false;
            car.IsMovingRight = false;
            score = 0;

            // Remove any obstacles currently in the game
            foreach(Obstacle o in obstacles)
            {
                // Dispose it first
                o.Dispose();
            }
            obstacles.Clear();

            // Add some obstacles
            AddObstacles(RoadDepth1);

            // Start our timer
            Utility.Timer(DirectXTimer.Start);
        }

        /// <summary>
        /// We will initialize our graphics device here
        /// </summary>
        public void InitializeGraphics()
        {
            // Set our presentation parameters
            PresentParameters presentParams = new PresentParameters();

            presentParams.Windowed = true;
            presentParams.SwapEffect = SwapEffect.Discard;
            presentParams.AutoDepthStencilFormat = DepthFormat.D16;
            presentParams.EnableAutoDepthStencil = true;

            // Store the default adapter
            int adapterOrdinal = Manager.Adapters.Default.Adapter;
            CreateFlags flags = CreateFlags.SoftwareVertexProcessing;

            // Check to see if we can use a pure hardware device
            Caps caps = Manager.GetDeviceCaps(adapterOrdinal, DeviceType.Hardware);

            // Do we support hardware vertex processing?
            if (caps.DeviceCaps.SupportsHardwareTransformAndLight)
                // Replace the software vertex processing
                flags = CreateFlags.HardwareVertexProcessing;
            
            // Do we support a pure device?
            if (caps.DeviceCaps.SupportsPureDevice)
                flags |= CreateFlags.PureDevice;

            // Create our device
            device = new Device(adapterOrdinal, DeviceType.Hardware, this, flags, presentParams);
            // Hook the device reset event
            device.DeviceReset += new EventHandler(this.OnDeviceReset);
            this.OnDeviceReset(device, null);

            // Create our fonts
            scoreFont = new Direct3D.Font(device, new System.Drawing.Font("Arial", 12.0f, FontStyle.Bold));
            gameFont = new Direct3D.Font(device, new System.Drawing.Font("Arial", 36.0f, FontStyle.Bold | FontStyle.Italic));
        }

        private void OnDeviceReset(object sender, EventArgs e)
        {
            device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1.0f, 1000.0f);
            device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 9.5f, 17.0f), new Vector3(), new Vector3(0,1,0));

            // Try to set up a texture minify filter, pick anisotropic first
            if (device.DeviceCaps.TextureFilterCaps.SupportsMinifyAnisotropic)
            {
                device.SamplerState[0].MinFilter = TextureFilter.Anisotropic;
            }
            else if (device.DeviceCaps.TextureFilterCaps.SupportsMinifyLinear)
            {
                device.SamplerState[0].MinFilter = TextureFilter.Linear;
            }

            // Do the same thing for magnify filter
            if (device.DeviceCaps.TextureFilterCaps.SupportsMagnifyAnisotropic)
            {
                device.SamplerState[0].MagFilter = TextureFilter.Anisotropic;
            }
            else if (device.DeviceCaps.TextureFilterCaps.SupportsMagnifyLinear)
            {
                device.SamplerState[0].MagFilter = TextureFilter.Linear;
            }

            // Do we have enough support for lights?
            if ((device.DeviceCaps.VertexProcessingCaps.SupportsDirectionalLights) &&
                (device.DeviceCaps.MaxActiveLights > 1))
            {
                // First light
                device.Lights[0].Type = LightType.Directional;
                device.Lights[0].Diffuse = Color.White;
                device.Lights[0].Direction = new Vector3(1, -1, -1);
                device.Lights[0].Update();
                device.Lights[0].Enabled = true;
                // Second light
                device.Lights[1].Type = LightType.Directional;
                device.Lights[1].Diffuse = Color.White;
                device.Lights[1].Direction = new Vector3(-1, 1, -1);
                device.Lights[1].Update();
                device.Lights[1].Enabled = true;

            }
            else
            {
                // Hmm.. no light support, let's just use
                // ambient light
                device.RenderState.Ambient = Color.White;
            }

            // Create our road mesh
            roadMesh = LoadMesh(device, @"..\..\road.x", ref roadMaterials, ref roadTextures);

            // Create our car
            car = new Car(device);

            // Create our obstacles class
            obstacles = new Obstacles();
        }

        /// <summary>
        /// Add a series of obstacles onto a road section
        /// </summary>
        /// <param name="minDepth">Minimum depth of the obstacles</param>
        private void AddObstacles(float minDepth)
        {
            // Add the right number of obstacles
            int numberToAdd = (int)((RoadSize / car.Diameter - 1) / 2.0f);
            // Get the minimum space between obstacles in this section
            float minSize = ((RoadSize / numberToAdd) - car.Diameter) / 2.0f;

            for (int i = 0; i < numberToAdd; i++)
            {
                // Get a random # in the min size range
                float depth = minDepth - ((float)Utility.Rnd.NextDouble() * minSize);
                // Make sure it's in the right range
                depth -= (i * (car.Diameter * 2));

                // Pick the left or right side of the road
                float location = (Utility.Rnd.Next(50) > 25) ? RoadLocationLeft : RoadLocationRight;

                // Add this obstacle
                obstacles.Add(new Obstacle(device, location, ObstacleHeight, depth));
            }
        }

        public static Mesh LoadMesh(Device device, string file, ref Material[] meshMaterials, ref Texture[] meshTextures)
        {
            ExtendedMaterial[] mtrl;

            // Load our mesh
            Mesh tempMesh = Mesh.FromFile(file, MeshFlags.Managed, device, out mtrl);

            // If we have any materials, store them
            if ((mtrl != null) && (mtrl.Length > 0))
            {
                meshMaterials = new Material[mtrl.Length];
                meshTextures = new Texture[mtrl.Length];

                // Store each material and texture
                for (int i = 0; i < mtrl.Length; i++)
                {
                    meshMaterials[i] = mtrl[i].Material3D;
                    if ((mtrl[i].TextureFilename != null) && (mtrl[i].TextureFilename != string.Empty))
                    {
                        // We have a texture, try to load it
                        meshTextures[i] = TextureLoader.FromFile(device, @"..\..\" + mtrl[i].TextureFilename);
                    }
                }
            }

            return tempMesh;
        }

        private void OnFrameUpdate()
        {
            // Nothing to update if the game is over
            if ((isGameOver) || (!hasGameStarted))
                return;

            // First, get the elapsed time
            elapsedTime = Utility.Timer(DirectXTimer.GetElapsedTime);

            RoadDepth0 += (RoadSpeed * elapsedTime);
            RoadDepth1 += (RoadSpeed * elapsedTime);

            // Check to see if we need to cycle the road
            if (RoadDepth0 > 75.0f)
            {
                RoadDepth0 = RoadDepth1 - 100.0f;
                AddObstacles(RoadDepth0);
            }

            if (RoadDepth1 > 75.0f)
            {
                RoadDepth1 = RoadDepth0 - 100.0f;
                AddObstacles(RoadDepth1);
            }

⌨️ 快捷键说明

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