当前位置: 首页 > 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.zskr.cn/news/1418633.html

相关文章:

  • MySQL—隔离级别和MVCC
  • 百度网盘提取码智能查询:3步告别资源获取烦恼的终极指南
  • 不是所有 AI 产品都适合出海,真需求和全球化幻觉差在哪? | 嗨点小圆桌
  • Docker 网络进阶:容器间通信与 DNS 解析
  • Arduino旋转电位器应用:从模拟信号读取到Processing数据可视化
  • 北斗导航“指路”申通西安转运中心让特产寄递跑出“加速度”
  • Arduino电子钢琴DIY:从电路设计到C++编程的嵌入式音乐项目实践
  • 别只盯着地图!深度解析ArcGIS Pro内容窗格的5个隐藏选项卡(选择、编辑、捕捉…)
  • 0104摩尔定律死亡终审:性能提升唯一路径——放弃几何微缩,转向场域升维+时间重构
  • 新手也能搞定的TPS5430电源设计:从24V到15V,手把手教你选对每个元器件(附完整BOM清单)
  • ArcMap新手必看:三种要素选择方法(按属性、位置、图形)的保姆级图文教程
  • Arm CoreLink NIC-400与NI/NoC动态调频技术详解
  • 从实验室到产线:Imatest枯叶图在摄像头批量质检中的实战应用与自动化脚本思路
  • 告别死板教程!用ShaderGraph复刻《和平精英》动态海面,这5个参数调好了效果直接翻倍
  • C语言在嵌入式Linux系统开发中的实战应用
  • PriLLM: 为LLM服务实时定价的 Stackelberg Game 建模 【School of CS and Eng,Southeast University】
  • 别再只会拖Button了!用Python脚本+Unity UGUI EventSystem,5分钟自动化测试你的UI交互
  • OpenCV 4.x时代,如何用ORB替代SIFT搞定Python图像拼接(附完整代码)
  • 避坑指南:Unity ShaderGraph制作透明火焰效果时,Alpha混合和Surface设置的那些坑
  • 别再死记硬背了!用Python实战模拟四种循环(简单/嵌套/连锁/非结构)的测试用例设计
  • 亚控组态报表数据导出Excel后,如何用VBA实现自动汇总与图表生成?
  • 技术美术进阶:三方向映射纹理的“坑”与优化技巧(从UE4到Unity的避坑指南)
  • 保姆级教程:理光喷头UV打印机白墨与光油通道设置实战(以1H2C_4C+2WV为例)
  • Oracle数据清洗实战:用正则表达式搞定脏数据,附赠常用SQL模板
  • Yolov8全系列模型C#推理性能优化:TensorRT vs. OpenVINO C# API对比实测
  • 工业网关实战:基于神州龙芯GSC3290双网口与YT8521S的稳定网络方案设计与调试心得
  • RuoYi-Vue + PostgreSQL实战:除了改驱动和URL,这些配置细节你调对了吗?
  • 手把手教你用Vivado 2019.1配置Tri Mode Ethernet MAC,搞定FPGA与RTL8211E的千兆UDP通信
  • 别再手动折腾了!用Composer和PECL一键搞定PHPStudy的imagick扩展(附PHP7.3/7.4版本适配指南)
  • 告别偏色!手把手教你用i1Profiler 3.5为打印机制作精准ICC曲线(附D50/D65光源选择指南)