从零开发游戏需要学习的c#模块,第二十二章(音效与背景音乐)
本节课学习目标加载并播放背景音乐循环收集金币时播放音效碰到敌人时播放音效用 MonoGame 内置音频系统实现第一步准备音频文件去这些网站下载免费音效freesound.orgopengameart.orgmixkit.co需要三个文件文件用途coin.wav吃金币音效hit.wav碰敌人音效bgm.wav或bgm.mp3背景音乐MonoGame 支持的格式.wav、.mp3、.ogg下载后放到Content文件夹属性设为“如果较新则复制”。第二步完整代码把Game1.cs完整替换为using Microsoft.Xna.Framework;using Microsoft.Xna.Framework.Graphics;using Microsoft.Xna.Framework.Input;using Microsoft.Xna.Framework.Audio;using Microsoft.Xna.Framework.Media;using System;using System.Collections.Generic;using System.IO;using FontStashSharp;namespace MY_FIRST_GAME{public enum GameState { Exploring, Battling }public class Game1 : Game{private GraphicsDeviceManager _graphics;private SpriteBatch _spriteBatch;private Player player default!;private Texture2D playerSpriteSheet;private Texture2D coinTexture;private ListVector2 coins;private Random rng;private int score;private Texture2D enemyTexture;private ListVector2 enemies;private SpriteFontBase font;private GameState state GameState.Exploring;// ★ 音频private SoundEffect coinSound default!;private SoundEffect hitSound default!;private Song bgm default!;public Game1(){_graphics new GraphicsDeviceManager(this);Content.RootDirectory Content;IsMouseVisible true;// ★ 背景音乐必须通过 MGCB Editor 加载// 如果 MGCB 不能用这里会跳过音乐加载}protected override void Initialize(){_graphics.PreferredBackBufferWidth 800;_graphics.PreferredBackBufferHeight 600;_graphics.ApplyChanges();rng new Random();coins new ListVector2();enemies new ListVector2();score 0;SpawnCoins(5);SpawnEnemies(3);base.Initialize();}protected override void LoadContent(){_spriteBatch new SpriteBatch(GraphicsDevice);// 玩家图集using var stream File.OpenRead(Content/player_spritesheet.png);playerSpriteSheet Texture2D.FromStream(GraphicsDevice, stream);player new Player(playerSpriteSheet, new Vector2(400, 300));// 金币coinTexture new Texture2D(GraphicsDevice, 24, 24);Color[] coinData new Color[24 * 24];for (int i 0; i coinData.Length; i) coinData[i] Color.Gold;coinTexture.SetData(coinData);// 敌人enemyTexture new Texture2D(GraphicsDevice, 40, 40);Color[] enemyData new Color[40 * 40];for (int i 0; i enemyData.Length; i) enemyData[i] Color.Red;enemyTexture.SetData(enemyData);// 字体var fontSystem new FontSystem();fontSystem.AddFont(File.ReadAllBytes(Content/consola.ttf));font fontSystem.GetFont(18);// ★ 加载音效SoundEffect 可以用 FileStream 直接读try{using var coinStream File.OpenRead(Content/coin.wav);coinSound SoundEffect.FromStream(coinStream);using var hitStream File.OpenRead(Content/hit.wav);hitSound SoundEffect.FromStream(hitStream);// 背景音乐MediaPlayer 需要 MGCB 编译直接读文件不支持// 暂时用音效替代把 bgm 循环播放}catch (Exception ex){System.Diagnostics.Debug.WriteLine(音效加载失败 ex.Message);}}// ★ 开始播放背景音乐在 Initialize 之后调用protected override void BeginRun(){base.BeginRun();// 尝试播放背景音乐音效作为临时方案try{// 如果你的 bgm 是 mp3/wav可以用 SoundEffect 播放using var bgmStream File.OpenRead(Content/bgm.wav);var bgmSound SoundEffect.FromStream(bgmStream);SoundEffectInstance bgmInstance bgmSound.CreateInstance();bgmInstance.IsLooped true;bgmInstance.Volume 0.3f; // 音量 30%bgmInstance.Play();}catch{// 没有音乐文件就跳过}}private void SpawnCoins(int count){for (int i 0; i count; i)coins.Add(new Vector2(rng.Next(50, 750), rng.Next(50, 550)));}private void SpawnEnemies(int count){for (int i 0; i count; i)enemies.Add(new Vector2(rng.Next(80, 720), rng.Next(80, 520)));}protected override void Update(GameTime gameTime){float deltaTime (float)gameTime.ElapsedGameTime.TotalSeconds;KeyboardState keyboard Keyboard.GetState();if (state GameState.Exploring){player.Update(deltaTime);CheckCoinCollision();CheckEnemyCollision();if (coins.Count 0) SpawnCoins(5);if (enemies.Count 0) SpawnEnemies(3);}if (keyboard.IsKeyDown(Keys.M)){// ★ 按 M 静音/取消静音MediaPlayer.IsMuted !MediaPlayer.IsMuted;SoundEffect.MasterVolume SoundEffect.MasterVolume 0 ? 0f : 1f;}if (keyboard.IsKeyDown(Keys.Escape)) Exit();base.Update(gameTime);}private void CheckCoinCollision(){Rectangle playerRect player.GetBounds();for (int i coins.Count - 1; i 0; i--){Rectangle coinRect new Rectangle((int)coins[i].X, (int)coins[i].Y, 24, 24);if (playerRect.Intersects(coinRect)){coins.RemoveAt(i);score 10;// ★ 播放吃金币音效try { coinSound?.Play(); }catch { }}}}private void CheckEnemyCollision(){Rectangle playerRect player.GetBounds();for (int i enemies.Count - 1; i 0; i--){Rectangle enemyRect new Rectangle((int)enemies[i].X - 20, (int)enemies[i].Y - 20, 40, 40);if (playerRect.Intersects(enemyRect)){enemies.RemoveAt(i);score 50;// ★ 播放碰敌人音效try { hitSound?.Play(); }catch { }}}}protected override void Draw(GameTime gameTime){GraphicsDevice.Clear(Color.CornflowerBlue);_spriteBatch.Begin();foreach (Vector2 coinPos in coins)_spriteBatch.Draw(coinTexture, coinPos, Color.White);foreach (Vector2 enemyPos in enemies)_spriteBatch.Draw(enemyTexture, enemyPos, null, Color.White,0f, new Vector2(20, 20), 1f, SpriteEffects.None, 0f);player.Draw(_spriteBatch);_spriteBatch.DrawString(font, $分数{score}, new Vector2(10, 10), Color.White);_spriteBatch.DrawString(font, $金币{coins.Count}, new Vector2(10, 35), Color.Gold);_spriteBatch.DrawString(font, $敌人{enemies.Count}, new Vector2(10, 60), Color.Red);_spriteBatch.DrawString(font, $HP{player.Hp}/{player.MaxHp}, new Vector2(10, 85), Color.LimeGreen);_spriteBatch.DrawString(font, WASD移动 | M静音 | ESC退出, new Vector2(10, 570), Color.LightGray);_spriteBatch.End();base.Draw(gameTime);}}}本节课新内容using var stream File.OpenRead(Content/coin.wav); coinSound SoundEffect.FromStream(stream); coinSound.Play(); // 播放一次SoundEffectInstance bgmInstance bgmSound.CreateInstance(); bgmInstance.IsLooped true; // 循环播放 bgmInstance.Volume 0.3f; // 音量 bgmInstance.Play();SoundEffect.MasterVolume 0f; // 所有音效静音 SoundEffect.MasterVolume 1f; // 恢复本节课到此结束我叫魔法阵维护师关注我下期更精彩
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2640401.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!