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

📄 block.cs

📁 《3d游戏编程入门经典》中范例小游戏。使用C#+DirectX开发。
💻 CS
字号:
using System;
using System.Drawing;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace Blockers
{
    /// <summary>
    /// Color possibilities of the blocks
    /// </summary>
    public enum BlockColor : byte
    {
        Red = 0,
        Blue = 1,
        Green = 2,
        Yellow = 3,
        SandyBrown = 4,
        WhiteSmoke = 5,
        DarkGoldenRod = 6,
        CornflowerBlue = 7,
        Pink = 8
    }

    /// <summary>
    /// The class for controlling a single block
    /// </summary>
    public class Block
    {
        #region Static/Constant Data
        public const float MaximumVelocity = 75.0f;
        private const float MaxBoxScaleSpeed = 15.0f;
        private const float MaxBoxScale = 0.01f;
        private const float BoxSize = 3.0f; // World size of box

        // List of colors available for boxes
        private static readonly Color[] BoxColors = {Color.Red , Color.Blue, Color.Green, 
                                Color.Yellow, Color.SandyBrown, Color.WhiteSmoke,
                                Color.DarkGoldenrod, Color.CornflowerBlue, Color.Pink};

        // List of each possible material object for the box
        private static Material[] boxMaterials;
        // The static mesh of the box
        private static Mesh boxMesh = null;
        #endregion

        #region Instance Data
        private Vector3 pos; // Current position of the box in the level
        private Material material; // Current material color of the box

        // Possible colors of the blocks
        private BlockColor[] colors;
        private int colorIndex;
        private bool canWrap;
        private float time = 0.0f;
        private bool shouldPulse = false;
        private Vector3 velocity;
        #endregion

        #region Creation
        /// <summary>
        /// Create a new instance of the block class
        /// </summary>
        /// <param name="dev">D3D Device to use as the render object</param>
        public Block(Device dev, BlockColor[] list, int index, bool wrap)
        {
            if ((list == null) || (list.Length == 0))
                throw new ArgumentNullException("list", "You must pass in a valid list");

            // Initialize the static data if needed
            if (boxMesh == null)
            {
                InitializeStaticData(dev);
            }

            // Set the default position
            pos = new Vector3(0,-1.0f, 0);

            // Store the information
            colors = list;
            colorIndex = index;
            canWrap = wrap;

            // Set the default material
            SetBlockColor(colors[colorIndex]);
        }

        /// <summary>
        /// Initialize the static data
        /// </summary>
        /// <param name="dev">D3D Device to use as the render object</param>
        private static void InitializeStaticData(Device dev)
        {
            // Create the mesh for each box that will be drawn
            boxMesh = Mesh.Box(dev, BoxSize, BoxSize, BoxSize);
            // Create the material list based on the colors of the boxes
            boxMaterials = new Material[BoxColors.Length];
            for (int i = 0; i < boxMaterials.Length; i++)
            {
                boxMaterials[i].Diffuse = boxMaterials[i].Ambient = BoxColors[i];
            }
        }

        #endregion

        #region Block Color Methods/Properties
        /// <summary>
        /// Sets the color of this block
        /// </summary>
        /// <param name="color">Color of the block</param>
        private void SetBlockColor(BlockColor color)
        {
            material = boxMaterials[(byte)color];
        }

        /// <summary>
        /// Retrieve the block color
        /// </summary>
        public BlockColor BlockColor
        {
            get { return colors[colorIndex]; }
        }

        /// <summary>
        /// Sets whether or not the block should pulse
        /// </summary>
        public void SetBlockPulse(bool pulse)
        {
            shouldPulse = pulse;
        }
        /// <summary>
        /// Sets the current total time on a block
        /// </summary>
        public void SetBlockTime(float totalTime)
        {
            time = totalTime;
        }
        /// <summary>
        /// Sets the blocks velocity after game over
        /// </summary>
        public void SetBlockVelocity(Vector3 vel)
        {
            velocity = vel;
        }
        public void UpdateBlock(float elapsed)
        {
            // Update the blocks position based on velocity
            Vector3 velocityFrame = velocity;
            velocityFrame.Normalize();
            velocityFrame.Scale(velocity.Length() * elapsed);

            // Move the block
            pos += velocityFrame;
        }

        /// <summary>
        /// Select the next available color in the block list.  Wrap if necessary
        /// </summary>
        public void SelectNextColor()
        {
            // Are we at the end, and can wrap?  If so, reset the color index
            if ((colorIndex == (colors.Length - 1)) && (canWrap))
            {
                // Reset color index
                colorIndex = 0;
            }
            // Otherwise, if we're not at the end, increment the color index
            else if (colorIndex != (colors.Length - 1))
            {
                // Increment color index since we haven't gotten to the last one yet
                colorIndex++;
            }

            // Update material
            SetBlockColor(colors[colorIndex]);
        }
        #endregion

        #region Position properties
        /// <summary>
        /// Current Box Position
        /// </summary>
        public Vector3 Position
        {
            get { return pos; }
            set { pos = value; }
        }
        #endregion

        #region Cleanup
        /// <summary>
        /// Cleanup any resources used for rendering the blocks
        /// </summary>
        public static void Cleanup()
        {
            if (boxMesh != null)
            {
                boxMesh.Dispose();
            }
            boxMesh = null;
            boxMaterials = null;
        }
        #endregion

        #region Rendering Method
        /// <summary>
        /// Render the current box using instance settings
        /// </summary>
        /// <param name="dev"></param>
        public void Draw(Device dev)
        {
            // Set the device's material to the color of this box
            dev.Material = material;
            // Move the box into position
            if (shouldPulse)
            {
                float scaling = (float)Math.Abs(Math.Sin(time * MaxBoxScaleSpeed));
                scaling *= MaxBoxScale;
                float scaleFactor = 1.0f + scaling;
                dev.Transform.World = Matrix.Translation(pos) * Matrix.Scaling(
                    scaleFactor, 1.0f, scaleFactor);
            }
            else
            {
                // Move the box into position
                dev.Transform.World = Matrix.Translation(pos);
            }
            // Turn off any texture
            dev.SetTexture(0, null);
            // Draw the box
            boxMesh.DrawSubset(0);
        }
        #endregion
    }
}

⌨️ 快捷键说明

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