本节课学习内容
-
击杀敌人获得经验值
-
经验条显示在血量条下方
-
经验满了升级,攻击力提升、血量回满
-
升级时屏幕上飘出"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.cs:
cs
using 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 List<FloatingText> floatingTexts = default!;
2. 在 InitializeGame 里初始化列表:
csharp
floatingTexts = new List<FloatingText>();
3. 在 CheckBulletEnemyCollision 里,击杀敌人后给经验并生成飘字:
找到击杀敌人的那几行,加上:
csharp
if (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 附近)加上:
csharp
foreach (FloatingText ft in floatingTexts)
ft.Update(deltaTime);
floatingTexts.RemoveAll(ft => !ft.IsAlive);
5. 替换 DrawGameUI 方法(加经验条):
cs
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. 添加画经验条的方法:
cs
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); 后面加上:
csharp
foreach (FloatingText ft in floatingTexts)
ft.Draw(_spriteBatch, font);
我是魔法阵维护师,关注我,下期更精彩!