从零开发游戏需要学习的c#模块,第三十章(掉落物品 —— 血包与能量)

发布时间:2026/6/5 10:18:47
从零开发游戏需要学习的c#模块,第三十章(掉落物品 —— 血包与能量)
本节课学习内容敌人死亡时概率掉落血包或能量球血包恢复血量能量球暂时提升攻击力掉落物有吸引动画可选第一步创建掉落物类右键项目 →添加→类文件名Pickup.cscsharpusing Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace MY_FIRST_GAME { public enum PickupType { Health, // 血包恢复25点血量 Power // 能量球5秒内攻击力翻倍 } public class Pickup { public Vector2 Position; public PickupType Type; public bool IsAlive true; public float Lifetime 10f; // 10秒后消失 public int Value; private Texture2D texture; private float timer; private float floatOffset; private float floatSpeed 0.5f; public Pickup(Vector2 position, PickupType type, GraphicsDevice graphicsDevice) { Position position; Type type; int size 20; texture new Texture2D(graphicsDevice, size, size); Color[] data new Color[size * size]; switch (type) { case PickupType.Health: Value 25; // 红色十字 for (int y 0; y size; y) for (int x 0; x size; x) { bool horizontal (y size * 0.35f y size * 0.65f); bool vertical (x size * 0.35f x size * 0.65f); if (horizontal || vertical) data[y * size x] Color.Red; else data[y * size x] Color.Transparent; } break; case PickupType.Power: Value 5; // 持续5秒 // 黄色闪电 for (int y 0; y size; y) for (int x 0; x size; x) { float dx x - size / 2f; float dy y - size / 2f; if (dx * dx dy * dy (size / 2f) * (size / 2f)) data[y * size x] Color.Gold; else data[y * size x] Color.Transparent; } break; } texture.SetData(data); } public void Update(float deltaTime) { timer deltaTime; floatOffset (float)System.Math.Sin(timer * 3) * 5; // 上下浮动 if (timer Lifetime) IsAlive false; } public void Draw(SpriteBatch spriteBatch) { Vector2 drawPos Position new Vector2(0, floatOffset); spriteBatch.Draw(texture, drawPos, null, Color.White, 0f, new Vector2(texture.Width / 2, texture.Height / 2), 1f, SpriteEffects.None, 0f); } public Rectangle GetBounds() { return new Rectangle( (int)(Position.X - texture.Width / 2), (int)(Position.Y - texture.Height / 2), texture.Width, texture.Height); } } }第二步给 Player 类加 BUFF 系统在Player.cs里添加// BUFF 相关 private bool isPoweredUp; private float powerTimer; private int originalAttack; // 在构造函数里保存原始攻击力 // 在 Player 构造函数末尾加originalAttack Attack; // 添加方法 public void ApplyPowerUp(float duration) { if (!isPoweredUp) { originalAttack Attack; isPoweredUp true; } powerTimer duration; Attack originalAttack * 2; // 攻击力翻倍 } public void UpdateBuffs(float deltaTime) { if (isPoweredUp) { powerTimer - deltaTime; if (powerTimer 0) { isPoweredUp false; Attack originalAttack; // 恢复 } } } public bool HasPowerUp isPoweredUp; public float PowerUpTimeRemaining powerTimer;在Player的构造函数最后加一行csharporiginalAttack Attack;第三步改造Game1.cs只列出需要改的地方。1. 添加字段csharpprivate ListPickup pickups default!;2. 在InitializeGame里初始化csharppickups new ListPickup();3. 在击杀敌人的地方加掉落逻辑在CheckBulletEnemyCollision击杀分支里csharpif (enemies[j].Hp 0) { // ...原有代码... // ★ 掉落判定 float dropChance (float)rng.NextDouble(); if (dropChance 0.4f) // 40%概率掉落 { if (dropChance 0.25f) // 25%血包 pickups.Add(new Pickup(enemies[j].Position, PickupType.Health, GraphicsDevice)); else // 15%能量球 pickups.Add(new Pickup(enemies[j].Position, PickupType.Power, GraphicsDevice)); } }4. 在Update的 Game 状态里更新掉落物csharp// 更新掉落物 foreach (Pickup pickup in pickups) pickup.Update(deltaTime); pickups.RemoveAll(p !p.IsAlive); // 更新玩家 BUFF player.UpdateBuffs(deltaTime); // 检测玩家和掉落物碰撞 CheckPickupCollision();5. 添加碰撞检测方法csharpprivate void CheckPickupCollision() { Rectangle playerRect player.GetBounds(); for (int i pickups.Count - 1; i 0; i--) { if (pickups[i].GetBounds().Intersects(playerRect)) { Pickup pickup pickups[i]; pickups.RemoveAt(i); switch (pickup.Type) { case PickupType.Health: player.Hp Math.Min(player.Hp pickup.Value, player.MaxHp); floatingTexts.Add(new FloatingText(pickup.Position, ${pickup.Value} HP, Color.Red)); break; case PickupType.Power: player.ApplyPowerUp(pickup.Value); floatingTexts.Add(new FloatingText(pickup.Position, 攻击力UP!, Color.Gold)); break; } } } }6. 在DrawGameWorld里画掉落物csharpforeach (Pickup pickup in pickups) pickup.Draw(_spriteBatch);7. 在DrawGameUI里加 BUFF 提示在 UI 最后加csharpif (player.HasPowerUp) { _spriteBatch.DrawString(font, $⚡ 攻击力UP{player.PowerUpTimeRemaining:F1}秒, new Vector2(600, 30), Color.Gold); }好了本节课学习内容到此结束关注我下期更精彩