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

📄 gameengine.cs

📁 《3d游戏编程入门经典》中范例小游戏。使用C#+DirectX开发。
💻 CS
📖 第 1 页 / 共 3 页
字号:
            }

            if (gameFont != null)
            {
                // Clean up the game font
                gameFont.Dispose();
                gameFont = null;
            }

            // Clean up the textures used for the mesh level
            if ((levelTextures != null) && (levelTextures.Length > 0))
            {
                for(int i = 0; i < levelTextures.Length; i++)
                {
                    levelTextures[i].Dispose();
                }
                // Clean up the mesh level itself
                levelMesh.Dispose();
            }

            // Make sure to cleanup the blocks
            Block.Cleanup();
        }

        /// <summary>
        /// This callback function will be called once at the beginning of every frame. This is the
        /// best location for your application to handle updates to the scene, but is not 
        /// intended to contain actual rendering calls, which should instead be placed in the 
        /// OnFrameRender callback.  
        /// </summary>
        public void OnFrameMove(Device device, double appTime, float elapsedTime)
        {
            if (FrameworkTimer.IsStopped)
                return; // Nothing to do

            if ((isQuitMenuShowing) || (isMainMenuShowing) || (isSelectScreenShowing))
            {
                return; // Nothing to do 
            }

            // Update the player
            player.Update(elapsedTime, (float)appTime);

            // Make sure the level isn't started until the camera moves to position
            UpdateCamera(elapsedTime);

            // See if we need to keep showing the 'you win' screen
            if ((currentLevel.IsGameWon) && (winningLevelTime > ShowWinningTime))
            {
                // Make sure the new level exists
                if (Level.DoesLevelExist(levelNumber + 1))
                {
                    // Reset the variables
                    levelNumber++;
                    LoadCurrentLevel();
                }
            }

            // If the level is won, then increment our timing for showing the screen
            if (currentLevel.IsGameWon)
            {
                winningLevelTime += elapsedTime;
            }

            // Update the current level
            currentLevel.Update(elapsedTime);
        }

        /// <summary>
        /// This callback function will be called at the end of every frame to perform all the 
        /// rendering calls for the scene, and it will also be called if the window needs to be 
        /// repainted. After this function has returned, the sample framework will call 
        /// Device.Present to display the contents of the next buffer in the swap chain
        /// </summary>
        public void OnFrameRender(Device device, double appTime, float elapsedTime)
        {
            bool beginSceneCalled = false;

            // Clear the render target and the zbuffer 
            device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, 0, 1.0f, 0);
            try
            {
                device.BeginScene();
                beginSceneCalled = true;

                // Decide what to render here
                if (isMainMenuShowing)
                {
                    mainScreen.Draw();
                }
                else if (isSelectScreenShowing)
                {
                    selectScreen.Draw((float)appTime);
                }
                else
                {
                    RenderGameScene(device, appTime);
                }

                #if (DEBUG)
                // Show debug stats (in debug mode)
                debugFont.DrawText(null, sampleFramework.FrameStats, new System.Drawing.Rectangle(2,0,0,0),
                    DrawTextFormat.NoClip, unchecked((int)0xffffff00));
                debugFont.DrawText(null, sampleFramework.DeviceStats, new System.Drawing.Rectangle(2,15,0,0),
                    DrawTextFormat.NoClip, unchecked((int)0xffffff00));
                #endif
            }
            finally
            {
                if (beginSceneCalled)
                    device.EndScene();
            }
        }

        #region Creation methods
        /// <summary>
        /// Create the graphical objects 
        /// </summary>
        private void CreateGraphicObjects(SelectLoopyScreen screen)
        {
            // No need to create the level mesh
            if (levelMesh == null)
            {
                // Create the mesh for the level
                ExtendedMaterial[] mtrls;
                levelMesh = Mesh.FromFile(MediaPath + "level.x", MeshFlags.Managed, sampleFramework.Device, out mtrls);

                // Store the materials for later use, and create the textures
                if ((mtrls != null) && (mtrls.Length > 0))
                {
                    levelTextures = new Texture[mtrls.Length];
                    for (int i = 0; i < mtrls.Length; i++)
                    {
                        // Create the texture
                        levelTextures[i] = TextureLoader.FromFile(sampleFramework.Device, MediaPath + 
                            mtrls[i].TextureFilename);
                    }
                }
            }

            // Create our player object
            player = new Player(screen.LoopyMesh, screen.LoopyTexture, 
                screen.LoopyMaterial);

            // Load the current level
            LoadCurrentLevel();
        }

        /// <summary>
        /// Load the current level
        /// </summary>
        private void LoadCurrentLevel()
        {
            // Load our level
            currentLevel = new Level(levelNumber, sampleFramework.Device, player);
                
            // Create a random camera location
            CreateRandomCamera();

            // Now we're loading the level
            isLoadingLevel = true;
            winningLevelTime = 0.0f;
        }
        #endregion

        /// <summary>
        /// This method will render the entire scene for a level
        /// </summary>
        private void RenderGameScene(Device device, double appTime)
        {
            // First render the level mesh, but before that is done, you will need
            // to turn off the zbuffer.  This isn't needed for this drawing
            device.RenderState.ZBufferEnable = false;
            device.RenderState.ZBufferWriteEnable = false;

            device.Transform.World = Matrix.Scaling(15,15,15) * Matrix.Translation(0,22,0);
            device.RenderState.Lighting = false;
            for(int i = 0; i < levelTextures.Length; i++)
            {
                device.SetTexture(0, levelTextures[i]);
                levelMesh.DrawSubset(i);
            }

            // Turn the zbuffer back on
            device.RenderState.ZBufferEnable = true;
            device.RenderState.ZBufferWriteEnable = true;

            // Now, turn back on our light
            device.RenderState.Lighting = true;

            // Render the player
            player.Draw(device, (float)appTime);

            currentLevel.Draw(device);

            int width = sampleFramework.DeviceSettings.presentParams.BackBufferWidth;
            int height = sampleFramework.DeviceSettings.presentParams.BackBufferHeight;

            if (isQuitMenuShowing)
            {
                quitScreen.Draw();
            }
            if (isLoadingLevel)
            {
                string loadingText = string.Format(
                    "Try Level {0}\r\nAre you ready?", levelNumber);
                if (!isQuitMenuShowing)
                {
                    gameFont.DrawText(null, loadingText, new System.Drawing.Rectangle(
                        System.Drawing.Point.Empty, new System.Drawing.Size(width,height)),
                        DrawTextFormat.Center | DrawTextFormat.VerticalCenter |
                        DrawTextFormat.NoClip, System.Drawing.Color.WhiteSmoke);
                }
            }
            else
            {
                // if there is a level happening, update some stats
                if (currentLevel != null)
                {
                    // Draw current state
                    string blockInfo = string.Format("Blocks Remaining {0} - Correct {1}", 
                        currentLevel.NumberBlocks - currentLevel.NumberCorrectBlocks, 
                        currentLevel.NumberCorrectBlocks);

                    System.Drawing.Color statColor = System.Drawing.Color.White;
                    // Change the color once you've gotten more than halfway complete
                    if ((currentLevel.NumberBlocks - currentLevel.NumberCorrectBlocks)
                        > currentLevel.NumberCorrectBlocks)
                    {
                        statColor = System.Drawing.Color.Turquoise;
                    }

                    gameFont.DrawText(null, blockInfo, new System.Drawing.Rectangle(0, 
                        height - 60, width, height), 
                        DrawTextFormat.Center | DrawTextFormat.NoClip, 
                        statColor);

                    if (!currentLevel.IsGameOver)
                    {
                        string gameState = string.Format("Moves: {0} (Max: {1})\r\nTime Remaining: {2}",
                            currentLevel.TotalMoves, currentLevel.MaximumMoves, 
                            currentLevel.TimeRemaining);

                        gameFont.DrawText(null, gameState, new System.Drawing.Rectangle(0, 
                            30, width, height), DrawTextFormat.Center | DrawTextFormat.NoClip, 
                            System.Drawing.Color.Yellow);
                    }
                    else
                    {
                        string gameState;
                        System.Drawing.Color c;
                        if (currentLevel.IsGameWon)
                        {
                            gameState = string.Format("Congratulations! You win this level!");
                            c = System.Drawing.Color.White;
                        }
                        else
                        {
                            gameState = string.Format("Game Over!!");
                            c = System.Drawing.Color.Red;
                        }
                        gameFont.DrawText(null, gameState, new System.Drawing.Rectangle(0, 
                            30, width, height), DrawTextFormat.Center | DrawTextFormat.NoClip, c);
                    }
                }
            }
        }


        #region Lighting
        /// <summary>
        /// Turn on the correct light for the scene
        /// </summary>
        private void EnableLights()
        {
            // Turn on the correct light, turn off the other light
            if (isSelectScreenShowing)
            {
                sampleFramework.Device.Lights[1].Enabled = true;
                sampleFramework.Device.Lights[0].Enabled = false;
            }
            else
            {
                sampleFramework.Device.Lights[0].Enabled = true;
                sampleFramework.Device.Lights[1].Enabled = false;
            }

        }
        #endregion

        #region Camera Functions
        /// <summary>
        /// Create a random camera position to 'fly by' the level
        /// </summary>
        private void CreateRandomCamera()
        {
            Random r = new Random();

            currentCameraPosition = new Vector3(
                (float)r.NextDouble() * 5.0f + 15.0f,

⌨️ 快捷键说明

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