从零开发游戏需要学习的c#模块,第三十四章(设置界面)

发布时间:2026/6/1 0:23:57

从零开发游戏需要学习的c#模块,第三十四章(设置界面) 本节课学习目标标题画面增加“设置”选项设置界面音量滑块、全屏开关设置保存到 JSON 文件暂停菜单中也能打开设置第一步扩展存档数据打开SaveManager.cs在SaveData类里加两个字段public class SaveData{public int HighScore { get; set; }public int TotalCoinsCollected { get; set; }public int TotalEnemiesDefeated { get; set; }public float MusicVolume { get; set; } 0.5f; // ★ 音量 0~1public bool IsFullscreen { get; set; } false; // ★ 是否全屏}第二步创建设置界面类右键项目 →添加→类文件名SettingsMenu.csusing Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using FontStashSharp; using System.Collections.Generic; namespace MY_FIRST_GAME { public class SettingsMenu { private Liststring options; private int selectedIndex; private KeyboardState previousKeyboard; private KeyboardState currentKeyboard; private bool adjustingVolume; // 正在调节音量 public float Volume { get; set; } public bool IsFullscreen { get; set; } public SettingsMenu(float volume, bool isFullscreen) { Volume volume; IsFullscreen isFullscreen; options new Liststring { 音量, 全屏, 返回 }; selectedIndex 0; adjustingVolume false; } // 返回值-1还在设置, 0返回, 1音量变化, 2全屏切换 public int Update() { previousKeyboard currentKeyboard; currentKeyboard Keyboard.GetState(); if (adjustingVolume) { if (IsKeyJustPressed(Keys.Left) || IsKeyJustPressed(Keys.A)) { Volume MathHelper.Max(0, Volume - 0.1f); return 1; } if (IsKeyJustPressed(Keys.Right) || IsKeyJustPressed(Keys.D)) { Volume MathHelper.Min(1, Volume 0.1f); return 1; } if (IsKeyJustPressed(Keys.Enter) || IsKeyJustPressed(Keys.Escape)) { adjustingVolume false; } return -1; } if (IsKeyJustPressed(Keys.W) || IsKeyJustPressed(Keys.Up)) { selectedIndex--; if (selectedIndex 0) selectedIndex options.Count - 1; } if (IsKeyJustPressed(Keys.S) || IsKeyJustPressed(Keys.Down)) { selectedIndex; if (selectedIndex options.Count) selectedIndex 0; } if (IsKeyJustPressed(Keys.Enter) || IsKeyJustPressed(Keys.Space)) { switch (selectedIndex) { case 0: // 音量 adjustingVolume true; break; case 1: // 全屏 IsFullscreen !IsFullscreen; return 2; case 2: // 返回 return 0; } } if (IsKeyJustPressed(Keys.Escape)) return 0; return -1; } private bool IsKeyJustPressed(Keys key) { return currentKeyboard.IsKeyDown(key) previousKeyboard.IsKeyUp(key); } public void Draw(SpriteBatch spriteBatch, SpriteFontBase font, GraphicsDevice device) { Texture2D overlay new Texture2D(device, 1, 1); overlay.SetData(new[] { new Color(0, 0, 0, 200) }); spriteBatch.Draw(overlay, new Rectangle(0, 0, 800, 600), Color.White); string title - 设置 -; Vector2 titleSize font.MeasureString(title); spriteBatch.DrawString(font, title, new Vector2(400 - titleSize.X / 2, 100), Color.White); // 音量选项 Color volColor (selectedIndex 0) ? Color.Gold : Color.LightGray; string volText (selectedIndex 0) ? 音量 : 音量 ; spriteBatch.DrawString(font, volText, new Vector2(400 - font.MeasureString(volText).X / 2, 200), volColor); // 音量条 DrawSlider(spriteBatch, device, 250, 230, 300, 20, Volume); // 音量数值 string volValue ${(int)(Volume * 100)}%; spriteBatch.DrawString(font, volValue, new Vector2(560, 230), Color.White); // 全屏选项 Color fsColor (selectedIndex 1) ? Color.Gold : Color.LightGray; string fsText (selectedIndex 1) ? 全屏 : 全屏 ; spriteBatch.DrawString(font, fsText, new Vector2(400 - font.MeasureString(fsText).X / 2, 300), fsColor); string fsValue IsFullscreen ? 开 : 关; spriteBatch.DrawString(font, fsValue, new Vector2(560, 300), IsFullscreen ? Color.LimeGreen : Color.Gray); // 返回选项 Color backColor (selectedIndex 2) ? Color.Gold : Color.LightGray; string backText (selectedIndex 2) ? 返回 : 返回 ; spriteBatch.DrawString(font, backText, new Vector2(400 - font.MeasureString(backText).X / 2, 400), backColor); string hint ↑↓ 选择 | 回车 确认 | ←→ 调节 | ESC 返回; spriteBatch.DrawString(font, hint, new Vector2(400 - font.MeasureString(hint).X / 2, 500), Color.Gray); } private void DrawSlider(SpriteBatch spriteBatch, GraphicsDevice device, int x, int y, int width, int height, float value) { Texture2D pixel new Texture2D(device, 1, 1); pixel.SetData(new[] { Color.White }); // 背景 spriteBatch.Draw(pixel, new Rectangle(x, y, width, height), Color.DarkSlateGray); // 边框 spriteBatch.Draw(pixel, new Rectangle(x, y, width, 2), Color.White); spriteBatch.Draw(pixel, new Rectangle(x, y height - 2, width, 2), Color.White); spriteBatch.Draw(pixel, new Rectangle(x, y, 2, height), Color.White); spriteBatch.Draw(pixel, new Rectangle(x width - 2, y, 2, height), Color.White); // 填充 int fillWidth (int)((width - 4) * value); spriteBatch.Draw(pixel, new Rectangle(x 2, y 2, fillWidth, height - 4), Color.Gold); // 滑块 int sliderX x 2 fillWidth - 5; spriteBatch.Draw(pixel, new Rectangle(sliderX, y - 4, 10, height 8), Color.White); } public void Reset() { selectedIndex 0; adjustingVolume false; } } }第三步改造Game1.cs1. 添加字段csharpprivate SettingsMenu settingsMenu default!; private bool inSettings false;2. 在Initialize里创建设置菜单csharpsettingsMenu new SettingsMenu(saveData.MusicVolume, saveData.IsFullscreen); // 应用保存的设置 ApplySettings();3. 添加应用设置的方法csharpprivate void ApplySettings() { SoundEffect.MasterVolume saveData.MusicVolume; _graphics.IsFullScreen saveData.IsFullscreen; _graphics.ApplyChanges(); }4. 在标题画面加“设置”选项把标题画面的空格触发改成菜单选择。简单做法在Update的Title状态里加csharpcase SceneType.Title: if (keyboard.IsKeyDown(Keys.Enter)) { inSettings true; settingsMenu new SettingsMenu(saveData.MusicVolume, saveData.IsFullscreen); settingsMenu.Reset(); } if (keyboard.IsKeyDown(Keys.Space) !inSettings) { // 开始游戏... } break;5. 处理设置更新在Update开头暂停检查之后加csharpif (inSettings) { int result settingsMenu.Update(); if (result 1) // 音量变化 { saveData.MusicVolume settingsMenu.Volume; SoundEffect.MasterVolume settingsMenu.Volume; } else if (result 2) // 全屏切换 { saveData.IsFullscreen settingsMenu.IsFullscreen; _graphics.IsFullScreen settingsMenu.IsFullscreen; _graphics.ApplyChanges(); } else if (result 0) // 返回 { SaveManager.Save(saveData); inSettings false; } }6. 在Draw里画设置界面在所有绘制之后加csharpif (inSettings) { _spriteBatch.Begin(); settingsMenu.Draw(_spriteBatch, font, GraphicsDevice); _spriteBatch.End(); }本节课学习到此结束我叫魔法阵维护师关注我下期更精彩

相关新闻