用于检测“唯一幸存者”获胜者的 Roblox 游戏脚本

Posted

技术标签:

【中文标题】用于检测“唯一幸存者”获胜者的 Roblox 游戏脚本【英文标题】:Roblox game script to detect "sole survivor" winner 【发布时间】:2021-03-25 10:40:21 【问题描述】:

我正在开发一款基于 6 人回合的 Roblox 游戏,如果任一时间用完或除一名幸存者之外的所有玩家都仍然存在,则每回合都会结束。在每一轮之后,玩家(以及在这一轮中被杀的人)被传送回大厅,然后是短暂的中场休息,然后将 bak 传送到地图中以开始新一轮(随机选择了许多不同的地图)。我对这款游戏的策略是在所有地图周围创建一个大区域,并在回合中随着计时器倒计时,不断检测该区域中的 # 名玩家。当该数字变为 1 时,该回合将结束并宣布获胜者。这种方法有两个问题:

    我必须创建一个巨大的区域来包含所有不同的地图,并且随着我添加更多地图,该区域必须变得越来越大。一次最多只能有 6 名玩家出现在一张地图中,是否会在如此大的区域内检测到 # 名玩家?

    我的玩家检测脚本不工作。它检测到一名玩家,但当有 2 名玩家时,它仍然返回“1”作为玩家人数。为了解决这个问题,我创建了一个简单的游戏,它检测玩家何时在一个区域(灰色底板)以及他们何时离开该区域(红色底板)。当我在游戏中公开运行游戏 - https://www.roblox.com/games/6060804433/Rounds - 有 2 名玩家时,它只返回游戏中的 1 名玩家(我在左上角的 GUI 中显示)。我的代码如下 - 我认为问题在于表/字典 playerFound 的工作方式。

代码:

regionPart = game.Workspace.RegionFromThisPart -- I created a transparent cube to define the region
pos1, pos2 = (regionPart.Position - (regionPart.Size/2)),(regionPart.Position + (regionPart.Size/2))
region = Region3.new(pos1,pos2)
Status = game.ReplicatedStorage.Status

wait(5)

while wait(1) do

    partsInRegion = workspace:FindPartsInRegion3(region, game.Workspace.Baseplate,1000) 
    playersFound =  -- table of players found

    for i, part in pairs (partsInRegion) do
        if part.Parent:FindFirstChild("Humanoid") ~= nil then
            playersFound["playerinregion"] = part.Parent -- add players character to table
            print (i, part) -- 0
        end 
    end

    function Length(playersFound)
        local counter = 0 
        for _, v in pairs(playersFound) do
            counter =counter + 1
        end
        return counter
    end

    Status.Value = Length(playersFound) .." players in region"

end 

额外问题:我创建的用于显示该地区玩家数量的 GUI 显示在我的屏幕上,但不显示其他玩家的屏幕(屏幕上显示“标签”)。

我花费了大量时间来转动我的车轮,非常感谢帮助解决这个问题。

谢谢!

【问题讨论】:

【参考方案1】:

您的问题源于您如何将玩家放入您的playersFound 牌桌,这是绝对正确的。因为您每次都在表中使用相同的键,所以您正在用您找到的任何新玩家覆盖旧玩家。 相反,请尝试使用唯一的钥匙来抓住玩家。这可能是i,或者更好的是,玩家的名字。既然你只是再次在桌子上循环,为什么不记录一下有多少玩家呢。

local regionPart = game.Workspace.RegionFromThisPart -- I created a transparent cube to define the region
local pos1 = (regionPart.Position - (regionPart.Size/2))
local pos2 = (regionPart.Position + (regionPart.Size/2))
local region = Region3.new(pos1,pos2)
local Status = game.ReplicatedStorage.Status
local BasePlate = game.Workspace.Baseplate
local time = 30 -- seconds

wait(5)

while wait(1) do
    
    -- count how many players are left
    local playersFound = 
    local totalPlayersFound = 0
    local partsInRegion = workspace:FindPartsInRegion3(region, baseplate, 1000)
    for i, part in pairs(partsInRegion) do
        if part.Parent:FindFirstChild("Humanoid") ~= nil then
            -- keep track of all the players still alive
            -- since a player's character is made of many parts, each player will show up multiple times,
            -- so only hold onto each player once
            local character = part.Parent
            if (playersFound[character.Name] == nil) then
                playersFound[character.Name] = character
                print ("Found Player : ", character.Name)
                totalPlayersFound = totalPlayersFound + 1
            end
        end 
    end

    -- EDIT BASED ON COMMENTS --
    -- update the UI based on the game state
    if time == 0 then
        Status.Value = "Round over!"
        break
    elseif totalPlayersFound == 1 then
        -- since we know that there's only one entry in the playersFound table,
        -- grab it using the next() function
        local playerName, character = next(playersFound)
        StatusValue = "Winner : " .. playerName
        wait(5)
        break
    --elseif totalPlayersFound  == 0 then
        -- make sure to check in case no players are left
    else
        Status.Value = tostring(totalPlayersFound) .. " players in round"
        time = time - 1
        -- DEBUG :
        -- print("There are " .. tostring(totalPlayersFound) .. " players in the round")
        -- for playerName, character in pairs(playersFound) do
        --     print(" - " .. playerName .. " is still in the game")
        -- end
    end
end

至于您的额外问题,您应该提出后续问题并发布代码,以显示您如何创建和更新标签。

【讨论】:

另外,如果您不需要专门索引的字典,您可以简单地使用数组来存储玩家字符:table.insert(playersFound, part.Parent),然后使用长度运算符 Status.Value = tostring(#playersFound) .. " players in region " 获取计数 Kylaaa,非常感谢!这行得通。我有一个后续问题:稍后在我的脚本中(在您编写的循环之外)我想显示获胜玩家的姓名。但是当我尝试通过引用 playerFound[part.Parent.Name] 来做到这一点时,它似乎无法识别它(脚本中的“部分”一词带有下划线。当我打印它时,我得到“nil”返回。任何建议?再次感谢! @Kevind,每个键中保存的值玩家的名字。您可以使用 pairs 关键字遍历所有键,即使您知道字典中只有一个条目:for playerName, playerCharacter in pairs(playersFound) do print("The winning Player is : ", playerName") end 更好的解决方案就是使用数组,因为这样你就可以使用print("The winning Player is : ", playersFound[1].Name)抓住最后一个玩家 努力弄清楚如何实现它。这是我决定结束回合的代码,因为时间用完了,或者如果剩下唯一的玩家成为获胜者:如果 time == 0 then Status.Value = "Round over!" break elseif Length(playersFound)== 1 then StatusValue = "Winner" wait(5) break else Status.Value = Length(playersFound) .." 玩家在回合)" time = time - 1 end

以上是关于用于检测“唯一幸存者”获胜者的 Roblox 游戏脚本的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Roblox 游戏模式中显示弹出消息?

为啥我的井字游戏代码无法检测到有人中奖了?蟒蛇 3

找不到我以私人模式发布的 Roblox 游戏

在 ROBLOX 上,我如何制作小游戏脚本? [关闭]

Roblox & C# |检查游戏是不是为FE,并打印到标签

Roblox Studio 游戏通行证购买失败