聽起來像一個很酷的遊戲,你正在努力。 Microsoft Azure Table Storage(NoSQL數據庫)速度非常快,對你的遊戲來說非常完美。您可以使用包含查詢語言(自定義LINQ提供程序)並且還將數據存儲在Azure表存儲中的Slazure(我編碼的Slazure BTW)。如果我爲你的遊戲使用Slazure和Microsoft Azure Table Storage NoSQL數據庫,我會這樣做。我建議你將在PlayersTable表中存儲一行,其中PartitionKey是玩家名稱,而RowKey是遊戲回合的多少毫秒 - 因爲每個表都在PartitionKey列上索引並且按排序RowKey列使用這些列的所有查詢確實非常快。還有爲使用的武器創建的列,屏幕上的位置,健康狀況,圓號以及哪個玩家被誰殺死。你可以創建一個表使用下同提出的方法來保存數據的破壞:
using SysSurge.Slazure;
using SysSurge.Slazure.Linq;
using SysSurge.Slazure.Linq.QueryParser;
namespace TableOperations
{
public class PlayerInfo
{
// List of weapons
public enum WeaponList {
Axe, Arrow, Knife, Sling
};
// Update a player with some new data
public void UpdatePlayerData(dynamic playersTable, DateTime gameStartedTime, int round, string playerName, WeaponList weapon, int healthPoints, int xPos, int yPos)
{
// Create an entity in the Players table using the player name as the PartitionKey, the entity is created if it doesn't already exist
var player = playersTable.Entity(playerName);
// Store the time the event was recorded for later as milliseconds since the game started.
// This means there is one row for each stored player event
player.Rowkey = ((DateTime.UtcNow.Ticks - gameStartedTime.Ticks)/10000).ToString("d19");
player.Round = round; // Round number
player.Weapon = (int)weapon; // Weapon carried by player. Example Axe
// Store player X and Y position coordinates on the screen
player.X = xPos;
player.Y = yPos;
// Number of health points, zero means player is dead
player.HealthPoints = healthPoints;
// Save the entity to the Azure Table Service storage
player.Save()
}
// Update a player with some new data
public void PlayerKilled(dynamic playersTable, DateTime gameStartedTime, int round, string playerName, string killedByPlayerName)
{
// Create an entity in the Players table using the player name as the PartitionKey, the entity is created if it doesn't already exist
var player = playersTable.Entity(playerName);
// Store the time the event was recorded for later as milliseconds since the game started.
// This means there is one row for each stored player event
player.Rowkey = ((DateTime.UtcNow.Ticks - gameStartedTime.Ticks)/10000).ToString("d19");
player.Round = round; // Round number
// Number of health points, zero means player is dead
player.HealthPoints = 0;
player.KilledByPlayerName = killedByPlayerName; // Killed by this player, example "Kyle"
// Save the entity to the Azure Table Service storage
player.Save()
}
// Get all the player positions between two time intervals
public System.Linq.IQueriable GetPlayerPositions(dynamic playersTable, string playerName, int fromMilliseconds, int toMilliseconds, int round)
{
return playersTable.Where("PrimaryKey == @0 && RowKey >= @1 && RowKey <= @2 && Round == @3",
playerName, fromMilliseconds.ToString("d19"), toMilliseconds.ToString("d19"), round).Select("new(X, Y)");
}
}
}
首先,你需要記錄當比賽開始和回合數:
var gameStartedTime = DateTime.UtcNow;
var round = 1; // Round #1
,並創建一個表在NoQL數據庫:現在
// Get a reference to the Table Service storage
dynamic storage = new DynStorage("UseDevelopmentStorage=true");
// Get reference to the Players table, it's created if it doesn't already exist
dynamic playersTable = storage.Players;
,在遊戲過程中,你可以不斷地像這樣更新播放器的信息:
UpdatePlayerData(playersTable, gameStartedTime, round, "Micheal", WeaponList.Axe, 45, 12313, 2332);
UpdatePlayerData(playersTable, gameStartedTime, round, "Kyle", WeaponList.Knife, 100, 13343, 2323);
如果你需要等待50毫秒,你可以這樣做的每個存儲事件之間:
System.Threading.Thread.Sleep(50);
,然後存儲一些玩家事件數據:
UpdatePlayerData(playersTable, gameStartedTime, round, "Micheal", WeaponList.Axe, 12, 14555, 1990);
UpdatePlayerData(playersTable, gameStartedTime, round, "Kyle", WeaponList.Sling, 89, 13998, 2001);
當的一個玩家已經死了,你可以用同樣的方法調用零點生命值和殺死他/她的玩家的名字:
PlayerKilled(playersTable, gameStartedTime, round, "Micheal", "Kyle");
現在,在你隨後的比賽分析,你可以查詢所有從遊戲開始(0毫秒)的位置到10000毫秒進入遊戲如下:
// Get a reference to the table storage and the table
dynamic queryableStorage = new QueryableStorage<DynEntity>("UseDevelopmentStorage=true");
QueryableTable<DynEntity> queryablePlayersTable = queryableStorage.PlayersTable;
var playerPositionsQuery = GetPlayerPositions(queryablePlayersTable, "Micheal", 0, 10000, round);
// Cast the query result to a dynamic so that we can get access its dynamic properties
foreach (dynamic player in playerPositionsQuery)
{
// Show player positions in the console
Console.WriteLine("Player position: Name=" + player.PrimaryKey + ", Game time MS " + player.RowKey + ", X-position=" + player.X + ", Y-position=" + player.Y;
}
比方說,有大約30000位玩家如移動。 (X,Y,Z,LookLocation,Velocity)。抓住這些職位的表現如何?我們還要說,有100人試圖做同樣的事情。 Azure的表格存儲沒有限制嗎?除此之外,我將試驗這個看看它對我有多好。 –
@MohamadBataineh Azure存儲可以處理20,000次IOPS(每秒讀/寫操作),這對大多數應用程序來說應該足夠了,請參閱https://azure.microsoft.com/en-us/documentation/articles/storage-scalability-targets/更多細節。您可以一次性獲取所有30,000個職位,也可以在Slazure查詢中使用分頁,一次只檢索部分查詢結果。 – 2015-09-04 20:30:33
@MohamadBataineh您可以一次獲得所有30,000個職位,或者在Slazure查詢中使用分頁來一次只檢索部分查詢結果,例如'.Take(1000).Skip(10000)'將檢索1,000行,跳過前10,000行,從而僅檢索10,000到11,000行。有關詳細信息,請參閱示例https://www.syssurge.com/Help/Slazure/html/M_SysSurge_Slazure_Linq_QueryParser_DynamicQueryable_Skip.htm和https://www.syssurge.com/Help/Slazure/html/M_SysSurge_Slazure_Linq_QueryParser_DynamicQueryable_Take.htm。 – 2015-09-04 20:36:24