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

本节课学习内容

  1. 敌人死亡时概率掉落血包或能量球

  2. 血包恢复血量

  3. 能量球暂时提升攻击力

  4. 掉落物有吸引动画(可选)

第一步:创建掉落物类

右键项目 → 添加 ,文件名 Pickup.cs

csharp

复制代码
using 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 里添加:

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 的构造函数最后加一行:

csharp

复制代码
originalAttack = Attack;

第三步:改造 Game1.cs

只列出需要改的地方。

1. 添加字段:

csharp

复制代码
private List<Pickup> pickups = default!;

2. 在 InitializeGame 里初始化:

csharp

复制代码
pickups = new List<Pickup>();

3. 在击杀敌人的地方加掉落逻辑:

CheckBulletEnemyCollision 击杀分支里:

csharp

复制代码
if (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. 添加碰撞检测方法:

csharp

复制代码
private 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 里画掉落物:

csharp

复制代码
foreach (Pickup pickup in pickups)
    pickup.Draw(_spriteBatch);

7. 在 DrawGameUI 里加 BUFF 提示:

在 UI 最后加:

csharp

复制代码
if (player.HasPowerUp)
{
    _spriteBatch.DrawString(font,
        $"⚡ 攻击力UP:{player.PowerUpTimeRemaining:F1}秒",
        new Vector2(600, 30), Color.Gold);
}

好了,本节课学习内容到此结束,关注我,下期更精彩!

相关推荐
金銀銅鐵8 小时前
用 Pygame 实现 15 puzzle
python·数学·游戏
Scout-leaf1 天前
C#摸鱼实录——IoC与DI案例详解
c#
咕白m6251 天前
使用 C# 在 Excel 中应用多种字体样式
后端·c#
Artech2 天前
[MAF预定义的AIContextProvider-02]AgentSkillsProvider——将Agent Skills引入MAF
ai·c#·agent·agent skills·maf
通信小呆呆2 天前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
H__Rick2 天前
自动对焦学习-3
人工智能·学习·计算机视觉
Daisy Lee2 天前
量化学习-第1章-什么是量化金融
学习·金融·datawhale
Alsn862 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
YM52e2 天前
买菜计算器小应用 - HarmonyOS ArkUI 开发实战-PC版本
学习·华为·harmonyos·鸿蒙·鸿蒙系统
小雨下雨的雨2 天前
HarmonyOS ArkUI训练营入门-组件掌握系列-Animation 动画效果实现-PC版本
学习·华为·harmonyos·鸿蒙