Планирование работы в игре! Рамки

В настоящее время я занимаюсь разработкой игрового приложения (v. 1.2.4), в котором пользователи могут выполнять определенные задачи и получать за это вознаграждение. Эти задачи требуют некоторой энергии, которая со временем будет пополняться. Базовая настройка следующая:

public class User extends Model {
    public Long energy;
    public Long maxenergy;
    public Long cooldown = Long.valueOf(300);
}

public class Task extends Controller {
    public static void perform(Long id) {
        User user = User.findById(id).first();

        // do some complex task here...

        user.energy--;
        user.save();
        Task.list();
    }
}

Теперь я хочу пополнить энергию пользователя после кулдауна (5 мин). Предполагая, что у пользователя есть 10/10 очков энергии, и я хочу пополнить очко через 5 минут после его использования, я мог бы легко использовать для этого задание:

public class EnergyHealer extends Job {
    public Long id;

    public EnergyHealer(Long id) {
        this.id = id;
    }

    public void doJob() throws Exception {
        User user = User.findById(id);
        user.energy++;
        if (user.energy > user.maxenergy) {
            user.energy = user.maxenergy;
        }
        user.save()
    }
}

... и вызвать его в моем контроллере сразу после выполнения задачи:

new EnergyHealer(user.id).in(user.cooldown);

Моя проблема здесь в том, что в этом случае задания планируются одновременно, поэтому, если пользователь выполняет задачу через 2 секунды после того, как он выполнил предыдущую задачу, первая точка энергии пополняется через 5 минут, а последующая точка пополняется только через 2 секунды.

Итак, мне нужно, чтобы задания были сериализованы, например, если у меня есть 8 из 10 очков энергии, должно пройти ровно 10 минут, пока все очки энергии не будут восполнены.

В связи с этим: пользователи имеют разные уровни и получают опыт за выполнение задач после достижения определенного порога. Их уровень повышается, и все очки энергии восполняются, независимо от того, сколько из них было использовано на предыдущем уровне, поэтому некоторые задания могут устареть к моменту их выполнения.

Учитывая несколько тысяч пользователей, работа может быть не идеальным выбором, поэтому, если у кого-то есть идея, как реализовать описанный сценарий, я буду рад любой помощи!


person aix    schedule 30.04.2012    source источник


Ответы (1)


Я думаю, что у вас просто неправильный график работы. Вместо того, чтобы запускать вашу работу каждый раз, когда они выполняют действие, вы должны просто иметь фасад или что-то, что запускает работу только в том случае, если она еще не существует для пользователя.

  1. Если задание еще не существует, создайте его, в противном случае ничего не делайте

  2. то это должно добавить 1 энергию,

  3. проверить, заполнена ли энергия, если да, конец

  4. если нет, пауза на 5 минут

  5. вернуться к 2

person Codemwnci    schedule 01.05.2012
comment
Уэйн, спасибо за ответ! Однако я боюсь, что не очень понимаю ваше решение, возможно, вы можете предоставить короткий фрагмент кода: 1) как будет выглядеть фасад и как запускается описанный вами алгоритм, и 2) где я могу отслеживать текущее задание пользователя, например, при получении последовательного запроса, как мне узнать, выполняется ли задание (сохранение очереди с отслеживанием состояния или что-то в этом роде)? - person aix; 01.05.2012
comment
поэтому вместо вызова задания вызовите одноэлементный объект, который может проверить значение объекта. Этот объект будет использоваться, чтобы определить, есть ли активное задание для вашего пользователя. В зависимости от того, сообщает ли БД, что выполняется задание, ваш одноэлементный объект может запустить задание или нет. - person Codemwnci; 01.05.2012