arrays - 使用 roblox 上的数据存储保存游戏数据而不是玩家数据

标签 arrays lua datastore roblox

这是使用 lua 和 roblox studio 的一般问题。我在游戏中需要保存一些信息以便与加入的玩家分享。特别是,我正在编写一款平台游戏,玩家在平台上跳跃,当他们跳跃时,平台会变成他们团队的颜色。我需要为所有玩家更新平台颜色,但如果玩家加入游戏中期,已经被“征服”的平台也必须是该颜色。为此,我使用 getAsync 和 setAsync。据我所知,人们大多使用数据存储来保存游戏之间的数据,但就我而言,我希望在游戏期间检索游戏期间保存的数据。一旦游戏结束,数据将被设置为零。我假设数据存储是可行的方法(...?)。我遇到的问题是,据我所知,roblox 中的数据存储只允许为每个键保存一个值,并且它使用玩家的键来保存它。但我需要键的三个值。它们是:所征服平台的行、列和颜色。我也不一定需要知道玩家的 id。我希望每个玩家在加入或更新时都可以访问此数据存储。理想情况下我想要这样的东西:

设置:

local dataStoreService = game:GetService("DataStoreService")
local PlatformsScored = dataStoreService:GetDataStore('PlatformsScored')

玩家得分时的函数内部:

PlatformsScored:SetAsync({col, row}, platformColor)

然后,检索并向所有客户端和/或新玩家加入时触发:

local pScoredNow = PlatformsScored:GettAsync({col, row}, platformColor)

for k, platform in (myPlatforms) do
   if platform.col == col and platform.row = row do
   platform.BrickColor = BrickColor.new(platformColor)
end

这个想法是这个 for 循环遍历所有平台并设置颜色。我一直在互联网上查找,我不确定这是否可能。您可以将表保存到 Roblox studio 中的数据存储吗?数据存储是否可以是“非个人的”,不一定与作为 key 的玩家 ID 相关联?谢谢。

最佳答案

您问了很多问题,所以我会尽力解决所有问题

Can you save tables to datastore in Roblox studio? ... I need three values by key. These are: the row, the column and the colour of the platform conquered.

表格无法保存,但如果您的数据可以序列化,您可以使用 HttpService:JSONEncode() 将表格转换为字符串,然后使用 HttpService:JSONDecode() 返回表.

local HttpService = game:GetService("HttpService")
local dataString = HttpService:JSONEncode({
    row = 5,
    column = 10,
    color = "Red",
})
print(dataString)

local reconstructedData = HttpService:JSONDecode(dataString)
print(reconstructedData.row, reconstructedData.column, reconstructedData.color)

Can datastore be ''impersonal'' that is not associated necessarily with a player ID as the key

当然,您可以将信息存储在您想要的任何键下。但您应该非常小心地选择 key ,因为每个游戏服务器都会写入这些 key 。这就是为什么总是推荐playerID,因为它是一个有保证的唯一 key ,并且玩家不能同时在两个服务器中,因此不存在两个服务器意外同时写入同一个 key 的风险。

如果您有多个游戏服务器写入同一个 key ,则两个服务器很有可能会覆盖彼此的数据,并且某人的资料会丢失。

I want the data saved during the game to be retrieved during the game... I want then every player to access this datastore when they join or when it updates.

这对于数据存储来说不是一个好的用例。数据存储应该用于持久存储有关必须跨多个服务器传输的玩家或世界的数据。例如,考虑一个全局排行榜,或者玩家的游戏进度,或者多人挖的洞有多深(假设您希望该洞在下次游戏启动时仍然存在)。

如果您尝试访问游戏状态信息并且仍处于事件游戏中,则可以让新玩家根据当前状态构建他们的游戏板。无需通过数据存储来传达这一点。

处理事件游戏状态信息的一个好方法是在服务器脚本中创建一个“GameManager”对象,并使其拥有对游戏中发生的更改的权限。球员得分?告诉 GameManager,它将更新记分板。有玩家加入?询问 GameManager 平台/游戏板的当前状态是什么。

您可以使用简单的 lua 表、RemoteEvents 和 RemoteFunctions 来完成所有这些。我喜欢使用 ModuleScript 来创建我的 GameManager 类。我的架构大致轮廓是这样的......

local PlayerService = game:GetService("Players")

-- keep a list of RemoteFunctions and RemoteEvents that are fired by players when they do something
local GetState = game.ReplicatedStorage.Functions.GetState
local PlayerAction = game.ReplicatedStorage.Events.PlayerAction

-- keep a list of RemoteEvents that are fired by the GameManager when something should be communicated to the players
local StartGame = game.ReplicatedStorage.Events.StartGame
local UpdateBoard = game.ReplicatedStorage.Events.UpdateBoard
local EndGame = game.ReplicatedStorage.Events.EndGame


-- make an authority over the game state
local GameManager = {}
GameManager.__index = GameManager

function GameManager.new()
    local gm = {
        -- keep a list of players
        teams = { "red" = {}, "blue" = {} },

        -- keep a list of scores per team
        scores = { "red" = 0, "blue" = 0 },

        -- keep track of the board colors
        platforms = {},

        -- keep track of the state of the game 
        currentGameState = "WaitingForPlayers", --InGame, PostGame

        -- as good housecleaning, hold onto connection tokens
        __tokens = {},
    }
    setmetatable(gm, GameManager)


    -- if anyone ever asks what the current state of the game is, let them know!
    GetState.OnServerInvoke = function()
        return gm.scores, gm.platforms, gm.currentGameState, gm.teams
    end

    return gm
end

function GameManager:waitForPlayers()
   -- wait for players to join to start the game
   while #PlayerService:GetPlayers() < 1 do
       wait(5)
   end

   wait(5)
   -- tell everyone the round is starting!
   self:startNewGame()
end

function GameManager:startNewGame()
    -- start listening to game events
    local playerActionToken = PlayerAction:OnServerEvent(function(player, ...)
        -- the player has done something, update the game state!
        local args = { ... }
        print("PlayerAction : ", player.Name, unpack(args))

        -- if a platform was taken, alert all players so they can update their stuff
        UpdateBoard:FireAllClients(self.platforms)
    end)
    table.insert(self.__tokens, playerActionToken)

    -- assign players to teams...

    -- tell all the players that the game has begun
    StartGame:FireAllClients()

    -- rather than code a game loop, just kill the game for now
    spawn(function()
        wait(30)
        -- tell everyone the game is over
        self:endGame()
    end)
end

function GameManager:endGame()
    self.currentGameState = "PostGame"

    -- communicate to all players that the game is over, and let them know the score
    EndGame:FireAllClients(self.scores)

    -- stop accepting actions from the game and clean up connections
    for _, token in ipairs(self.__tokens) do
        token:Disconnect()
    end

    -- start the game over again!
    spawn(function()
        wait(30)
        self:waitForPlayers()
    end)
end

return GameManager

然后在服务器脚本中,只需创建 GameManager...

local GameManager = require(script.Parent.GameManager) -- or wherever you've put it
local gm = GameManager.new()
gm:waitForPlayers()

然后在 LocalScript 中,让玩家在加入游戏时请求游戏状态...

-- connect to all the game signals that the server might send
game.ReplicatedStorage.Events.StartGame:Connect(function(args)
    -- construct the local game board
    print("Game has started!")
end)
game.ReplicatedStorage.Events.UpdateBoard:Connect(function(newBoardState)
    print("Board state has changed!")
end)
game.ReplicatedStorage.Events.EndGame:Connect(function(scores)
    print("Game has ended!")
end)


-- request the current game state with a RemoteFunction
local GetState = game.ReplicatedStorage.Functions.GetState
local scores, platforms, currentGameState, teams= GetState:InvokeServer()

-- parse the current game state and make the board...
for k, v in pairs(scores) do
    print(k, v)
end
for k, v in pairs(platforms) do
    print(k, v)
end
print(currentGameState)
for k, v in pairs(teams) do
    print(k, v)
end

关于arrays - 使用 roblox 上的数据存储保存游戏数据而不是玩家数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59742747/

相关文章:

c++ txt文件逐行字符串和纸牌游戏int成数组

c# - Lua:在没有全局方法的情况下获取堆栈跟踪

android - DbxRecord 服务器修改日期时间戳或修订

python - 从 AppEngine 数据存储区删除之前获取部分祖先

python - 如何在 Google App Engine 扩展类中创建动态字段?

c - 在我的代码中的函数之间返回数组指针有问题吗?

arrays - React Redux,如何正确处理数组中对象的变化?

javascript - 使用每个对象名称的数组创建对象数组

nginx - Apache APISIX的高性能和低延迟是如何实现的

string - Lua - 删除不在列表中的单词