Лучший способ управлять ресурсами в игре

Недавно я начал разработку игр и сейчас работаю над MMORTS-игрой (массовая многопользовательская онлайн-стратегия в реальном времени), но я застрял на одном этапе и нуждаюсь в совете, как это сделать. Управляй этим. Ниже приведен случай: -

Общая информация об игре

Все данные сохраняются в SQL Server 2008
Эта игра разрабатывается для использования в мобильных устройствах.

введите здесь описание изображения

выше находится значок ресурсов игры с его значением.

Каждый ресурс имеет свой прирост в час, предположим:-

Дерево :- 100/час
Камень :- 100/час
Еда: - 100/час

Проблема

Игра, которую я разрабатываю, будет иметь 10 тысяч пользователей, использующих эту игру одновременно, что означает я не могу постоянно обновлять значение ресурса. Итак, мой вопрос: как мне управлять ресурсами игры (дерево, камень, еда)?

Зачем обновлять значение ресурса в базе данных?

Это потому, что если человек нападает на город, то сколько ресурсов (дерево, камень, еда) доступно для захвата.

Мой текущий подход

Изменение значения во время атаки на город, но есть ли лучший способ сделать это?

Пожалуйста, не стесняйтесь задавать любые вопросы и менять теги вопроса, так как я не знаю, какой тег сюда подходит.


person Developer Nation    schedule 04.09.2015    source источник
comment
что именно вы имеете в виду под управлением. управлять обновлением в базе данных или в графическом интерфейсе?   -  person SomeJavaGuy    schedule 04.09.2015
comment
@KevinEsche я имею в виду в базе данных, потому что, если кто-то атакует город, сколько ресурсов можно захватить.   -  person Developer Nation    schedule 04.09.2015
comment
Если вы знаете текущий статус ресурса и время его сохранения, вы знаете соотношение. Просто выполните Value+timedifference*ratio, чтобы получить текущее значение. Таким образом, вам нужно обновлять только тогда, когда что-то действительно изменилось из-за атак или потрачено на локальные постройки/войска. Какая бы ни была ваша игра.   -  person mxix    schedule 04.09.2015
comment
@mxix это именно тот подход, который я пытаюсь использовать, но есть ли лучший способ для этого?   -  person Developer Nation    schedule 04.09.2015
comment
Я не вижу лучшего подхода, чем то, что вы делаете. Просто написал ответ, описывающий именно этот подход, а затем увидел ваше редактирование... Дох!   -  person GarethD    schedule 04.09.2015
comment
@GarethD Я считаю, что это лучший ответ =) все равно добавь   -  person mxix    schedule 04.09.2015


Ответы (1)


Зачем вам вообще его обновлять, если у вас есть начальное значение и скорость увеличения, это достаточно простой расчет. StartValue + (HoursSinceStart * Rate), это закроет ваши дисплеи. Затем каждый раз, когда вы добавляете/удаляете ресурс с помощью определенного действия, вставляйте новую запись с суммой действия публикации и новой отметкой времени.

Например, используя Wood, User1 начинает со 100:

Ресурс

ResourceID  Name    HourlyIncrease
------------------------------------
1           Wood    100
2           Stone   100
3           Food    100

Пользовательский ресурс

UserID  ResourceID  Value   CreatedDateTime
---------------------------------------------
1       1           100     2015-09-04 10:00:00

Чтобы получить значение в @DateTime, вы можете использовать:

DECLARE @DateTime DATETIME2 = SYSDATETIME(),
        @UserID INT = 1,
        @ResourceID INT = 1;

SELECT  TOP 1
        Quantity = Value + (r.HourlyIncrease * DATEDIFF(HOUR, ur.CreatedDateTime, @DateTime))
FROM    UserResource AS ur
        INNER JOIN Resource AS r
            ON r.ResourceID = ur.ResourceID
WHERE   ur.ResourceID = @ResourceID
AND     ur.UserID = @UserID
AND     ur.CreatedDateTime < @DateTime
ORDER BY ur.CreatedDateTime DESC;

Затем, если пользователь делает что-то, что израсходует количество 50, просто создайте новую запись:

DECLARE @DateTime DATETIME2 = SYSDATETIME(),
        @UserID INT = 1,
        @ResourceID INT = 1,
        QuantityChange INT = -50;

INSERT UserResource (UserID, ResourceID, Value, CreatedDateTime)
SELECT  TOP 1
        ur.UserID,
        ur.ResourceID,
        Value = Value + (r.HourlyIncrease * DATEDIFF(HOUR, ur.CreatedDateTime, @DateTime)) + QuantityChange,
        CreatedDateTime = @DateTime
FROM    UserResource AS ur
        INNER JOIN Resource AS r
            ON r.ResourceID = ur.ResourceID
WHERE   ur.ResourceID = @ResourceID
AND     ur.UserID = @UserID
AND     ur.CreatedDateTime < @DateTime
ORDER BY ur.CreatedDateTime DESC;

Таким образом, вы избегаете ненужных транзакций для вещей, которые предназначены только для демонстрации.

Н.Б. Я предположил, что ресурс будет увеличиваться только после завершения целого часа, если это не так, вам может понадобиться что-то вроде:

Quantity = Value + FLOOR((r.HourlyIncrease * DATEDIFF(SECOND, ur.CreatedDateTime, @DateTime) / 3600))

Тем не менее, для целей игры, если это будет постоянно увеличиваться, вероятно, лучше всего просто извлечь 3 компонента (скорость, время и начальное значение) и сохранить их в вашем сеансе, а затем выполнить расчет на сторона клиента.

person GarethD    schedule 04.09.2015
comment
Уменьшение значения приведет к отсутствию ресурсов. @GarethD, что бы вы предложили для решения этой проблемы. Сохранить двойные/поплавки в БД и указать значение в самом интерфейсе/приложении? - person Davy de Vries; 13.02.2020
comment
@DavydeVries используется только общее количество ресурсов, поэтому потеря ресурсов будет минимальной. Например, если с момента создания ресурса древесины прошло 52 минуты и 23 секунды, а древесина пополняется со скоростью 100 единиц в час, это будет означать, что было пополнено 86,67 древесины, все, что делает пол, это округляет это значение в меньшую сторону, исходя из предположения. эта древесина идет целыми порциями. Если это не так, то да, именно то, что вы сказали, сохраните его как десятичное число и не округляйте в меньшую сторону, а округляйте на переднем конце. - person GarethD; 13.02.2020