从零开发游戏需要学习的c#模块,第二十九章(经验值与升级系统)
本节课学习内容击杀敌人获得经验值经验条显示在血量条下方经验满了升级攻击力提升、血量回满升级时屏幕上飘出“LEVEL UP”文字第一步升级 Player 类打开Player.cs在类里加上经验值和升级相关的内容1. 添加字段csharp// 升级系统 public int Level { get; private set; } 1; public int Experience { get; private set; } 0; public int ExpToNextLevel { get; private set; } 30;2. 在构造函数里初始化这些字段已经有默认值不用动构造函数。3. 在Player.cs末尾添加方法csharp// 获得经验值返回 true 表示升级了 public bool GainExperience(int amount) { Experience amount; if (Experience ExpToNextLevel) { LevelUp(); return true; } return false; } private void LevelUp() { Level; Experience - ExpToNextLevel; ExpToNextLevel (int)(ExpToNextLevel * 1.5f); // 升级所需经验递增 Attack 5; MaxHp 20; Hp MaxHp; // 升级回满血 } // 获取经验值百分比用于经验条 public float GetExpPercent() { return (float)Experience / ExpToNextLevel; }第二步添加飘字效果类右键项目 →添加→类文件名FloatingText.csusing Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using FontStashSharp; namespace MY_FIRST_GAME { public class FloatingText { public Vector2 Position; public string Text; public Color Color; public float Lifetime; public float MaxLifetime; public bool IsAlive Lifetime 0; private float floatSpeed -60f; // 向上飘 public FloatingText(Vector2 position, string text, Color color, float lifetime 1.5f) { Position position; Text text; Color color; Lifetime lifetime; MaxLifetime lifetime; } public void Update(float deltaTime) { Lifetime - deltaTime; Position.Y floatSpeed * deltaTime; } public void Draw(SpriteBatch spriteBatch, SpriteFontBase font) { float alpha Lifetime / MaxLifetime; Vector2 textSize font.MeasureString(Text); spriteBatch.DrawString(font, Text, Position - textSize / 2, Color * alpha); } } }第三步改造Game1.cs以下是需要改动的部分对照着替换即可。1. 添加字段private ListFloatingText floatingTexts default!;2. 在InitializeGame里初始化列表csharpfloatingTexts new ListFloatingText();3. 在CheckBulletEnemyCollision里击杀敌人后给经验并生成飘字找到击杀敌人的那几行加上csharpif (enemies[j].Hp 0) { enemies[j].IsAlive false; score enemies[j].ScoreValue; enemiesDefeatedThisGame; particleSystem.EmitHitParticles(enemies[j].Position); // ★ 加经验 int expGain enemies[j].ScoreValue / 2 5; bool leveledUp player.GainExperience(expGain); floatingTexts.Add(new FloatingText(enemies[j].Position, ${expGain} EXP, Color.Cyan)); if (leveledUp) { floatingTexts.Add(new FloatingText( enemies[j].Position new Vector2(0, -30), LEVEL UP!, Color.Gold, 2f)); } }4. 在Update中更新飘字在Game状态的Update里particleSystem.Update附近加上csharpforeach (FloatingText ft in floatingTexts) ft.Update(deltaTime); floatingTexts.RemoveAll(ft !ft.IsAlive);5. 替换DrawGameUI方法加经验条private void DrawGameUI() { _spriteBatch.DrawString(font, $分数{score}, new Vector2(10, 10), Color.White); _spriteBatch.DrawString(font, $最高分{saveData.HighScore}, new Vector2(10, 35), Color.Gold); // 血量条 DrawPlayerHealthBar(_spriteBatch, 10, 65, 200, 20); _spriteBatch.DrawString(font, ${player.Hp}/{player.MaxHp}, new Vector2(220, 63), Color.White); // ★ 经验条 DrawExpBar(_spriteBatch, 10, 90, 200, 14); _spriteBatch.DrawString(font, $Lv.{player.Level}, new Vector2(220, 86), Color.Cyan); _spriteBatch.DrawString(font, ${player.Experience}/{player.ExpToNextLevel}, new Vector2(270, 86), Color.LightGray); _spriteBatch.DrawString(font, $敌人{enemies.Count} | 子弹{bullets.Count}, new Vector2(10, 115), Color.Yellow); _spriteBatch.DrawString(font, WASD移动 | 鼠标瞄准左键射击 | M静音, new Vector2(10, 570), Color.LightGray); }6. 添加画经验条的方法private void DrawExpBar(SpriteBatch spriteBatch, int x, int y, int width, int height) { float expPercent player.GetExpPercent(); Texture2D pixel new Texture2D(GraphicsDevice, 1, 1); pixel.SetData(new[] { Color.White }); // 背景 spriteBatch.Draw(pixel, new Rectangle(x, y, width, height), Color.DarkSlateGray); // 经验值 int currentWidth (int)(width * expPercent); spriteBatch.Draw(pixel, new Rectangle(x, y, currentWidth, height), Color.Cyan); // 边框 spriteBatch.Draw(pixel, new Rectangle(x, y, width, 1), Color.White); spriteBatch.Draw(pixel, new Rectangle(x, y height - 1, width, 1), Color.White); spriteBatch.Draw(pixel, new Rectangle(x, y, 1, height), Color.White); spriteBatch.Draw(pixel, new Rectangle(x width - 1, y, 1, height), Color.White); }7. 在DrawGameWorld末尾加飘字绘制在player.Draw(_spriteBatch);后面加上csharpforeach (FloatingText ft in floatingTexts) ft.Draw(_spriteBatch, font);我是魔法阵维护师关注我下期更精彩