Я делаю текстовую RPG, и мне бы очень хотелось подражать времени.
Я мог бы просто провести некоторое время между каждым разом, когда игрок что-то печатает, но мне бы хотелось, чтобы это было лучше, чем это, если это возможно. Мне было интересно, будет ли многопоточность хорошим способом сделать это.
Я подумал, может быть, просто вторая, действительно простая нить на заднем плане, которая просто имеет цикл, повторяющийся каждые 1000 мс. За каждый проход, хотя его цикл, мировое время будет увеличиваться на 1 секунду, и игрок будет восстанавливать немного здоровья и маны.
Это то, что может сделать многопоточность, или есть какие-то вещи, о которых я не знаю, которые могли бы заставить это не работать? (Я бы предпочел не тратить кучу времени изо всех сил на изучение этого, если это не поможет мне с этим проектом.)
Да, многопоточность, безусловно, могла бы сделать это, но надо знать, что многопоточность обычно более сложна, чем альтернатива (которая будет основным потоком, опрашивающим различные события обновления как часть своего основного цикла, который должен выполняться по крайней мере один раз каждые 100 мс или около того) ).
В вашем случае, если поток часов следует довольно строгим правилам, вы, вероятно, будете в порядке.
Если вы реализуете его таким образом, вам даже не нужно будет знакомиться с мьютексами, чтобы запустить поток и безопасно работать, и ваше время будет точным.
Но! Вот некоторая пища для размышления: что, если вы хотите связать внутриигровые триггеры в определенное время дня? Например, сообщение, которое будет отправлено пользователю «Солнце зашло» или похожие. Код, необходимый для этого, в любом случае должен будет выполняться в главном потоке (если только вы не хотите реализовать межпотоковые очереди обмена сообщениями!) И, вероятно, будет выглядеть очень похоже на базовый код периодической проверки и обновления часов , Таким образом, в этот момент вам будет лучше просто сохранить простую унифицированную модель потока.
Я обычно использую класс с именем Simulation, чтобы шагнуть вперед по времени. У меня его нет в C ++, но я сделал многопоточность в Java, которая продвигает время вперед и активирует события в соответствии с расписанием (или случайное событие в запланированное время). Вы можете взять это и перевести на C ++ или использовать, чтобы увидеть, как объектно-ориентированная реализация.
package adventure;
public class Simulation extends Thread {
private PriorityQueue prioQueue;
Simulation() {
prioQueue = new PriorityQueue();
start();
}
public void wakeMeAfter(Wakeable SleepingObject, double time) {
prioQueue.enqueue(SleepingObject, System.currentTimeMillis() + time);
}
public void run() {
while (true) {
try {
sleep(5);
if (prioQueue.getFirstTime() <= System.currentTimeMillis()) {
((Wakeable) prioQueue.getFirst()).wakeup();
prioQueue.dequeue();
}
} catch (InterruptedException e) {
}
}
}
}
Чтобы использовать его, вы просто создаете его экземпляр и добавляете свои объекты:
` Simulation sim = new Simulation();
// Load images to be used as appearance-parameter for persons
Image studAppearance = loadPicture("Person.gif");
// --- Add new persons here ---
new WalkingPerson(sim, this, "Peter", studAppearance);
Я собираюсь предположить, что ваша программа в настоящее время тратит большую часть своего времени на ожидание пользовательского ввода — что блокирует ваш основной поток нерегулярно и на относительно длительный период времени, не давая вам иметь короткие зависящие от времени обновления. И что вы хотите избежать сложных решений (многопоточность).
Если вы хотите получить доступ к времени в главном потоке, доступ к нему без отдельного потока относительно прост (посмотрите на пример).
Если вам не нужно ничего делать в фоновом режиме во время ожидания ввода пользователя, не могли бы вы написать функцию для вычисления нового значения на основе количества времени, которое прошло во время ожидания? Вы можете иметь некоторую переменную LastSystemTimeObserved
он обновляется каждый раз, когда вам нужно использовать одну из зависящих от времени переменных — вызывая некоторую функцию, которая вычисляет измененное значение переменной на основе того, сколько времени прошло с момента ее последнего вызова, вместо того, чтобы пересчитывать значения каждую секунду.
Если вы делаете отдельную тему, убедитесь, что вы правильно защищать любые переменные, к которым обращаются оба потока.