代码之家  ›  专栏  ›  技术社区  ›  Paul

更有效地使用数据存储

  •  0
  • Paul  · 技术社区  · 4 年前

    我正在用Roblox Stuido ide为我的拳头编写一个与lua的游戏。游戏可以运行——有点——尽管我知道代码不太好。这是一个适合小孩子的游戏,在这个游戏中,一个数字显示在一个标志上,玩家必须去与这个数字匹配的平台。我遇到的一个问题是,我希望有一个图形用户界面,以大数字显示分数,因为上角的领先者统计数据不容易看到。我想要的不仅仅是让玩家看到自己的分数,这会更容易一些,只需在初学者玩家gui上添加一个textLabel,并使用这样的脚本:

    while true do 
        wait(.1)
        script.Parent.Text = game.Players.LocalPlayer.leaderstats.Platforms.Value
    end
    

    还有以下代码:

    game.Players.PlayerAdded:connect(function(player)
        local playerKey = "Player_" .. player.UserId
        local leaderstats = Instance.new("Folder",player)
        leaderstats.Name = "leaderstats"
        local Platforms = Instance.new("IntValue", leaderstats) 
        Platforms.Name = "Platforms"
        Platforms.Value = 0
        platformCount:SetAsync(player.UserId, 0)
        StartGui:FireAllClients(player)
    
    end)
    

    请注意那个街区的最后几行,这是我想出来的。我不确定如何做得更好,但我感觉他们是个混蛋。

    我的目标是,每个玩家不仅可以实时看到他们的分数更新,还可以看到其他玩家的分数。这是不完全有效的。我的方法如下。当玩家踏上所需的平台时,我在本地脚本上有这段代码

                    allPlats[k].Eliminated = true
                    player:WaitForChild("leaderstats"):FindFirstChild("Platforms").Value = player:WaitForChild("leaderstats"):FindFirstChild("Platforms").Value + 1 --increase leaderstats
                    points = points + 1
                    numIfScored:InvokeServer(column, row, teamColorReady, points, team)
                    PlatformDeleted.OnClientEvent:Connect(platformTransparency)
    

    忽略不适用于该问题的行。这个问题的重要部分是,我访问在leadersstats中创建的intValue,并将其值增加一个。我还通过远程功能向服务器发送了一个调用,该功能会传递平台的位置、团队的颜色等。。。

    然后,服务器端脚本使用这些值来执行与设置下一个目标和更新平台外观相关的许多任务,并且至关重要的是,将数据发送到数据存储:

    函数numIfScored。OnServerInvoke(plr、col、row、originalTeamColor、points、team)

    game.Workspace.TargetNumber.Value = getAnddisplayTarget(col, row)
    
    PlatformDeleted:FireAllClients(col, row)
    
    for k, v in pairs(allPlats) do 
        if v.Column == col and v.Row == row then
            v.Part.Transparency = 0
            v.Part.Material = "Neon"
            v.Part.BrickColor = BrickColor.new(orignalTeamColor)
        end
    end
    platformCount:SetAsync(plr.UserId, points)
    

    结束

    然后,我在同一脚本中运行一个单独的代码块,通过从数据存储中获取点来不断更新gui:

    while wait(.1) do   
        for _, player in pairs(Players:GetPlayers()) do
    
            local points = platformCount:GetAsync(player.UserId)
            UpdateGUI:FireAllClients(player.UserId,points, player.Team)
        end
    end
    

    我有一个localscript,它是文本标签的子级,用以下代码显示分数:

    local function UpdateLabel(plrId, points, team)
    
        if team.Name == "Really red Team" then
        game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeam.Text = points
        elseif team.Name == "Really blue Team" then
        game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeam.Text = points
        end
    end
    StartGui.OnClientEvent:Connect(StartLabel)
    

    这很有效,但有缺陷。我在家和儿子一起玩,这有点奏效,但有点滞后,但一旦我尝试和其他玩家一起玩,比如我的朋友和他的儿子,系统就停止了正常工作。我知道的一件事是不好的,如果你在另一个玩家加入之前就开始玩游戏,那么那个玩家在他们加入之前就看不到你的进度。另一个问题是,第一个加入的玩家会被后来加入的玩家看到,但当玩家加入时,他们看不到之前加入的玩家的标签。

    是否有更简单的方法来创建一个更新所有玩家gui中所有玩家分数的gui?谢谢。

    如果需要,我可以发布完整的代码。

    0 回复  |  直到 4 年前
        1
  •  0
  •   user12280259 user12280259    4 年前

    不需要完整的代码。我只需要一句“它在LocalScript中”。即使你在服务器脚本中更改标签的文本,你也是在本地脚本上添加点,这意味着它只会为你更改点,而不会为任何其他玩家更改点。相反,如果你使用RemoteFunction并调用服务器来更改点,我非常确定它应该工作。