上一章我们学习了循环和集合,今天我们来学习方法

代码的复用车床——方法 (Method)

到目前为止,我们的所有代码都挤在 Main 里面。如果我想在游戏里让角色“攻击”三次,就得把攻击逻辑复制粘贴三遍。这太蠢了。

方法,就是给一段代码起个名字。你需要它的时候,喊它的名字就行。这是消除重复代码的最基本手段。

看一个最简单的例子:一个只会打印“普通攻击!”的方法

// 这是一个方法的定义
static void Attack() 
{
    Console.WriteLine("你发动了普通攻击!");
}

static:静态的。现阶段你所有的 Main 方法里直接调用的方法,都先加上 static。我们后面讲类时会深究。

void:这表示“这个方法执行完了,什么都不给我返回”。就像开灯,它只做事,不给你结果。

Attack:我们自己起的方法名字。跟变量名一样,用动词或动词短语。

():括号是方法的标志。里面可以放参数

{ ... }方法体。这个方法被调用时会执行的代码块。

如何“叫”它调用方法

定义了方法,它不会自己执行。你需要喊它的名字,也就是调用

static void Main(string[] args)
{
    Console.WriteLine("遇到敌人!");
    
    Attack(); // 喊一声"Attack",程序就跳去执行上面的方法
    Attack(); // 再喊一次,它就再执行一次
    Attack(); // 打第三次
    
    Console.WriteLine("敌人被消灭了!");
}

// 方法定义在 Main 方法的外面,但还在 class Program 的大括号里面
static void Attack()
{
    Console.WriteLine("你发动了普通攻击!");
}

(这个代码没有外壳,只有核心内容,如果要运行用下面这个代码)

using System;

namespace MyFirstGameCode
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("遇到敌人!");

            Attack(); // 喊一声"Attack",程序就跳去执行上面的方法
            Attack(); // 再喊一次,它就再执行一次
            Attack(); // 打第三次

            Console.WriteLine("敌人被消灭了!");
            Console.ReadKey(); // 暂停一下,让你能看到结果
        }

        // 方法定义在 Main 方法的外面,但还在 class Program 的大括号里面
        static void Attack()
        {
            Console.WriteLine("你发动了普通攻击!");
        }
    }
}
百变金刚——有参数的方法

普通的攻击每次都一样,太单调了。我想让角色能释放不同名字的技能。“火球术”、“冰箭术”等等 这就需要用参数来告诉方法。

// string skillName 就是我们定义的一个参数,用来接收技能名字
static void CastSpell(string skillName) 
{
    Console.WriteLine("你对敌人释放了" + skillName + "!");
}

调用时,必须给它一个参数:)

CastSpell(“火球术”);
CastSpell(“冰箭术”);
CastSpell(“治疗术”);
// 输出:你对敌人释放了火球术! ...

一个方法可以有多个参数,用逗号隔开。我们做一个有目标、有伤害的完整攻击:

static void DealDamage(string targetName, int damage)
{
    Console.WriteLine("对" + targetName + "造成了" + damage + "点伤害!");
}

现在,我们可以在 Main 里这样用:

DealDamage(“哥布林”, 25);
DealDamage(“巨龙”, 8);
 有“还”有“报”——有返回值的方法

有些方法不只做事,还要给你一个计算结果。比如一个“计算暴击后伤害值”的方法,你得把计算后的数值拿回来。这时,void 就不够用了,我们需要返回值

void 表示“不返回任何东西”。要返回一个整数,我们就写 int;要返回一个字符串,就写 string

看这个方法,它计算伤害,并用 return 把结果传回来。

// 计算范围伤害,对一个区域内的敌人造成的伤害只计算65%
static float CalculateAOEDamage(int baseDamage)
{
    float aoeMultiplier = 0.65f; // 范围伤害系数
    float finalDamage = baseDamage * aoeMultiplier; // 计算结果
    return finalDamage; // return 就像工厂的出货口,把结果交出去
}

调用它,并用变量接住:

int mySpellPower = 100;
float aoeDamage = CalculateAOEDamage(mySpellPower); // 把100传进去,用aoeDamage接住65的结果
Console.WriteLine("你的范围攻击造成了 " + aoeDamage + " 点伤害。");
实战演练:整合一个简单战斗系

现在,把我们学到的所有东西整合起来。我们不在 Main 里写任何具体逻辑,只用来调度我们造好的方法。

class Program
{
    // 玩家属性(现在声明在Main外面,这样所有方法都能用,暂时先这样写)
    static int playerHp = 100;
    static string playerName = “勇者”;

    static void Main(string[] args)
    {
        Console.WriteLine(“=== 战斗开始! ===”);

        // 用带参数的方法攻击一系列敌人
        DealDamage(“哥布林”, 30);
        DealDamage(“暗影魔”, 45);

        // 受伤
        TakeDamage(25);
        TakeDamage(18);

        // 检查状态
        CheckStatus();

        Console.WriteLine(“\n=== 战斗结束 ===”);
        Console.ReadKey();
    }

    // 1. 攻击方法
    static void DealDamage(string enemyName, int damage)
    {
        Console.WriteLine(“\n你对” + enemyName + “造成了” + damage + “点伤害!”);

        // 有10%几率追加一次暴击
        Random rng = new Random();
        if (rng.Next(1, 101) <= 10)
        {
            Console.WriteLine(“  ⚔️ 暴击!额外造成” + damage + “点伤害!”);
        }
    }

    // 2. 受伤方法
    static void TakeDamage(int damage)
    {
        playerHp = playerHp - damage;
        Console.WriteLine(“你受到了” + damage + “点伤害!当前血量:” + playerHp);

        // 检查是否死亡
        if (playerHp <= 0)
        {
            Console.WriteLine(“你倒下了... Game Over.”);
        }
    }

    // 3. 检查状态方法
    static void CheckStatus()
    {
        Console.WriteLine(“\n--- 状态 ---”);
        Console.WriteLine(“角色:” + playerName);
        Console.WriteLine(“剩余血量:” + playerHp);
    }
}

留给大家一个小小的作业,在最后的代码中加入护甲的概念,如果护甲高于伤害,则造成零点伤害,需要答案的小伙伴可以私信我。

今天的学习到此结束,今天我们学习了方法,关注我,下一期更精彩(如果报错可以检查一下双引号是不是中文)

还有一张打击运行图

更多推荐