找回密码
 注册
X系列官方授权正版
搜索
查看: 2259|回复: 2

[原创] [教程]玩转游戏---制定你自己的游戏规则(高级篇)

[复制链接]
发表于 2008-2-15 21:56:55 | 显示全部楼层 |阅读模式
玩转游戏---制定你自己的游戏规则(高级篇)

在中级篇教程中,我们已经可以独立的完成一个完整的规则逻辑了.
在高级篇中,我们将开始探讨一些复杂的规则逻辑.并对其中的部分逻辑进行代码实现.
我们借用FX MOD,<<家园>>模式中的随机奖励,来讲解复杂的规则逻辑.

我们直接跳过选项的设置和取值关联,直接进入规则逻辑部分.

首先,我们对所需要实现的规则逻辑进行细致的分析.

一.素材准备

    最先的准备,如果你连你想要奖励什么都不清楚的话...就很难进行下面的工作了...
    1.我们需要一张详细的奖励清单,用来确定那些单位或者其他项目将会被奖励.
    2.我们需要确定奖励承载物(<<家园>>模式中的资源箱).

二.逻辑顺序分析及简单设计

    将复杂的逻辑分解成若干个简单的逻辑,并使用调用来联系他们.
    1.规则:放置奖励承载物.(function rule_CrateAdd())
      运行方式:间隔一定时间执行一次(低频率)

        1-1.规则:在地图中产生随机位置(用于放置奖励承载物)并将值返回给调用者.(function getCratePoint() return P)
            运行方式:普通函数,调用运行.

            1-1-1.规则:接收参数(位置),判断这个位置附近是否有玩家拥有的单位.如周围"安全".告知调用者当前位置可以放置奖励承载者.(function isPointOkToAddCrate(P) return IsOk)
                  运行方式:普通函数,调用运行.

    2.规则:检测奖励承载物是否过时,并将过时的奖励承载物剔除.判断玩家的单位是否接近现有的奖励承载物.(function checkPlayerGetCrate())
      运行方式:间隔一定时间执行一次(高频率)

        2-1.规则:给予玩家奖励.(function givePlayerCrateReward(playerId))
            运行方式:普通函数,调用执行.

            2-1-1.规则:检索奖励列表,并将选中的奖励返回给调用者.(function checkCrateReward(playerId) return rewardType)
                  运行方式:普通函数,调用执行.


三.执行流程伪代码描述(超级伪...还杂交了中文...-_-...)

function 初始化函数()
    规则加载("rule_CrateAdd","间隔时间")
    规则加载("checkPlayerGetCrate","间隔时间")
end


function rule_CrateAdd()            --向地图中添加奖励承载物,把选择位置的工作扔给了getCratePoint()函数
    local P = getCratePoint()
    添加模型("箱子", P)
end


function getCratePoint()            --产生随机点,把检测位置是否合理的工作交给了isPointOkToAddCrate(P)函数
    代码块(一系列算法产生一个随机点P)
    while (isPointOkToAddCrate(P) ~= 可以放置) do
        P = P + 随机数
    end
    return P
end


function isPointOkToAddCrate(P)     --检测位置是否合乎要求,并将结果返回调用者
    local isOk = "可以放置"
    local playerId = 0
    local playercount = 累计玩家数量()
    while (playerId < playercount) do
        if (玩家是否存在(playerId) == 1) then
            local sobGroup
            将指定范围内指定玩家的单位累计入指定组(sobGroup, playerId, 范围半径)
            if (sobGroup ~= 空) then
                isOk = "不可放置"
                break
            end
        end
        playerId = playerId + 1
    end
    return isOk
end


function checkPlayerGetCrate()      --剔除过期的奖励承载物,以及判断玩家是否可以拾取奖励.把具体的奖励工作交给了givePlayerCrateReward(playerId)函数
    代码块(检测奖励承载物是否过时并把过时的奖励承载物剔除.)
    local playerId = 0
    local playercount = 累计玩家数量函数()
    while (playerId < playercount) do
        if (玩家是否存在(playerId) == 1) then
            local sobGroup
            将指定范围内指定玩家的单位累计入指定组(sobGroup, playerId, 范围半径)
            if (sobGroup ~= 空) then
                代码块(剔除拣起的奖励承载物)
                givePlayerCrateReward(playerId)
                break
            end
        end
        playerId = playerId + 1
    end
end


function givePlayerCrateReward(playerId)      --为玩家颁发奖品,把挑选奖品的工作交给了checkCrateReward(playId)函数
    local rewardType = checkCrateReward(playerId)
    将指定奖励给予指定玩家(playerId, rewardType)
end


function checkCrateReward(playId)             --挑选奖品并返回给调用者
    local rewardType
    代码块(按照一定规则选出奖励并赋值给rewardType)
    return rewardType
end


(PS:以上巨伪的代码流程中...中文描述的函数,一些是使用HW2的内置函数实现功能,另一些是使用一些结合HW2内置函数的代码块来实现功能,大家是否看了暴汗呢...-_-)
(再PS:同时我们也看到,将多个互相关联的逻辑细分开来,让一个函数尽量只做1~2件简单的工作,能够使得我们的代码实现更为简便和有条理,也保证了低错误率)

到这里,对规则逻辑的分析已经完成了.我们已经得到了最基本的流程.
现在,我们来完成挑选奖品的函数~~相信每个人都喜欢挑东西吧~~~
首先,随便整个奖励列表吧(模仿<<家园>>模式的结构).

PrsentsList =
{
    {
        prob = 0.1 ,
        ships =
        {
            {ship = "A" , prob = 0.5 ,},
            {ship = "B" , prob = 1.0 ,},
        },
    },
    {
        prob = 0.3 ,
        ships =
        {
            {ship = "C" , prob = 0.6 ,},
            {ship = "D" , prob = 1.0 ,},
        },
    },
    {
        prob = 0.8 ,
        ships =
        {
            {ship = "E" , prob = 0.3 ,},
            {ship = "F" , prob = 0.8 ,},
            {ship = "G" , prob = 1.0 ,},
        },
    },
    {
        prob = 1.0 ,
        ships =
        {
            {ship = "H" , prob = 1.0 ,},
        },
    },
}


嘿嘿~~奖励列表就被我们胡乱搞出来了...
然后,我们来实现一个不需要参数的挑选奖励的简单函数

function checkCrateReward()
    local iClass = 1
    local probsNum = RandomRange(0.0 ,1.0)
                 --浮点数随机函数RandomRange(<iMin> ,<iMax>)
    while (PrsentsList[iClass].prob < probsNum) do
        iClass = iClass + 1
    end
    probsNum = RandomRange(0.0 ,1.0)
                       --再取一次随机数,不然出来的结果就傻了...-_-
    local iShip = 1
    while (PrsentsList[iClass].ships[iShip].prob < probsNum) do
        iShip = iShip + 1
    end
    return PrsentsList[iClass].ships[iShip].ship
end


具体的语法结构要看先前所设计的奖励列表的结构而定,在这里再举一个更简单的实现方式(各有各的好处,就看具体问题了).

PrsentsList =
{
    {ship = "A" , prob = 0.1},
    {ship = "B" , prob = 0.2},
    {ship = "C" , prob = 0.3},
    {ship = "D" , prob = 0.4},
    {ship = "E" , prob = 0.5},
    {ship = "F" , prob = 0.6},
    {ship = "G" , prob = 0.8},
    {ship = "H" , prob = 1.0},
}

function checkCrateReward()
    local iShip = 1
    local probsNum = RandomRange(0.0 ,1.0)
    while (PrsentsList[iShip].prob < probsNum) do
        iShip = iShip + 1
    end
    return PrsentsList[iShip].ship
end

评分

参与人数 1UCC +20 收起 理由
白衣 + 20 我认为此帖很有意义

查看全部评分

发表于 2008-2-21 16:15:37 | 显示全部楼层
好~~
回复

使用道具 举报

 楼主| 发表于 2008-2-21 16:46:50 | 显示全部楼层
一般一般全国第三了~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

Archiver|手机版|小黑屋|DeepTimes.NET 太空游戏站