当前位置: 首页 > news >正文

从零开发游戏需要学习的c#模块,第二十九章(经验值与升级系统)

本节课学习内容

  1. 击杀敌人获得经验值

  2. 经验条显示在血量条下方

  3. 经验满了升级,攻击力提升、血量回满

  4. 升级时屏幕上飘出“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

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方法(加经验条):

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);后面加上:

csharp

foreach (FloatingText ft in floatingTexts) ft.Draw(_spriteBatch, font);

我是魔法阵维护师,关注我,下期更精彩!

http://www.jsqmd.com/news/907331/

相关文章:

  • 从一次“幻觉”到一次“进化”:AI事实核查错误的深度剖析与系统改进启示
  • 从状态检查到数据备份:仓储PLC控制器保养周期与实操清单
  • 效率拉满!VS Code 安装 Qoder CN(原通义灵码)详细教程
  • MySQL—隔离级别和MVCC
  • Docker 网络进阶:容器间通信与 DNS 解析
  • 百度网盘提取码智能查询:3步告别资源获取烦恼的终极指南
  • 别再只关RST了!深入聊聊Intel快速存储技术(RAID)与Ubuntu/Linux的‘爱恨情仇’
  • Arduino旋转电位器应用:从模拟信号读取到Processing数据可视化
  • 不是所有 AI 产品都适合出海,真需求和全球化幻觉差在哪? | 嗨点小圆桌
  • 从压电传感器到示波器:手把手教你搭建电荷放大器与低通滤波器(含Multisim仿真与PCB焊接避坑指南)
  • Jetson Orin Nano + DeepStream 6.2 实战:将YOLOv5模型集成到生产级视觉流水线
  • Python爬虫实战:批量下载校园风光图
  • 10427条密码产品证书全部收集到,我发现几个数据跟认知完全对不上
  • 如何查物种的12S基因片段是否存在于NCBI公共数据库?
  • 别再傻傻用软件SPI了!实测STM32硬件SPI驱动GC9A01屏幕,速度提升10倍(附完整代码)
  • 打破大模型 KV Cache 魔咒:一种让跨模型 Agent 缓存 99% 命中的动态工具注入方案
  • 从音响制造到AI家庭娱乐生态:不见不散AI智能K歌音响亮相第二十届深圳国际金融博览会
  • 百年名校焕新光智底座,华为“领航”光智共融
  • Windows电脑也能玩转AI大模型!6G显存就能本地部署,免费无限用!
  • 北斗导航“指路”申通西安转运中心让特产寄递跑出“加速度”
  • 3D点云处理新思路:ParSeNet如何用“聚类+拟合”两阶段网络搞定复杂曲面重建?
  • Arduino电子钢琴DIY:从电路设计到C++编程的嵌入式音乐项目实践
  • 用鼠标单击我的电脑桌面图标或单击文件夹会自动变成重命名状态
  • Unity 2019.3+ 项目从内置管线迁移到URP的保姆级避坑指南(含材质修复)
  • 别只盯着地图!深度解析ArcGIS Pro内容窗格的5个隐藏选项卡(选择、编辑、捕捉…)
  • 手把手教你用阿里云服务器本地部署AWS DeepRacer训练环境(避坑指南)
  • 量子采样经典算法:突破NISQ时代组合优化瓶颈
  • 0104摩尔定律死亡终审:性能提升唯一路径——放弃几何微缩,转向场域升维+时间重构
  • 亚控组态数据导出踩坑实录:报表保存为Excel时文件名乱码、数据错位的解决办法
  • docker 实战:将一个多组件应用完整容器化