Когда вы пишете игру без использования событий ... все, что вы действительно делаете, это реализует события самостоятельно. Это выгодно, потому что вы можете сделать его намного более эффективным, чем с помощью встроенных событий вашего языка. Игры, написанные таким образом, менее подвержены ошибкам, если вы знаете, что делаете.
Например, когда я пытался научить моего брата, как пишутся игры, я написал для него простую игру со змеями. У меня была основная петля в потоке, переместите змею и нарисуйте ее в новой позиции в цикле. Я хотел бы иметь поток, работающий в то же время, что постоянно проверяет 4 вещи:
Если змея врезалась в себя (игра окончена); если игра окончена, остановите основной поток, который обновляет основное положение змеи, выведите игру на экран, дождитесь ввода с клавиатуры и перезапустите игру.
Если бы змея съела яблоко; увеличьте переменную счетчика, которая сообщает, сколько яблок было съедено, и выведите это новое значение на экран, перезаписав то, что было ранее.
Если змея съела количество яблок, кратных 10 (змея растет на 1 клетку, вычтите из переменной ожидания, которая говорит, сколько времени должно пройти между каждым движением змеи)
Если нажата клавиша со стрелкой. Если влево, установите перемещение в 0, если вправо установите в 1, если вниз установите в 2, если в верх установите в 3. Указатель, в котором он хранится, является указателем на массив из 4 делегатов, которые заставляют змею двигаться. в правильном направлении.
Основной цикл, который обновляет положение змеи, сообщает нити, проверяющей эти 4 вещи, что делает змея. То, как я это делаю, заключается в том, что у меня есть каждая ячейка на экране, которую голова змеи перемещает, чтобы ссылаться на двумерный массив делегатов. Об этом массиве делегатов:
Игра написана в режиме консоли и использует цвета консоли. Консоль установлена на 80x50 символов. Делегат выглядит следующим образом: "делегат void ptr ()"; затем я создаю массив с:
"ptr [,] pos = new ptr [80,50]". Скажем, голова змеи находится в положении (4,5) на экране, после того как она переместится туда, главный цикл выполнит «pos [4,5] .Invoke ();».
Один из них:
Когда змея перемещается в новую позицию, поток основного цикла получит каждую ячейку, которую змея покрывает на экране, и установит делегата в этой позиции, чтобы указывать на функцию с именем "void gameover ()", которая установит переменную gameover_ к истине. Поэтому, когда поток цикла, который проверяет состояние игры, проверяет наличие игрового процесса, он останавливает игру и выводит ее на экран.
Другой:
Когда на экране нарисовано яблоко, положение делегата, в котором оно нарисовано (которое рандомизировано), устанавливается равным «void increment_apple ()», который увеличивает счетчик яблок, удаляет текущее яблоко из поля зрения и рисует новое яблоко. на экране, установка старой позиции яблока, чтобы она указывала на «void nop ()», которая ничего не делает, и новая позиция яблока, чтобы указывать на «void increment_apple ()».
Так работает игра. Как вы можете видеть, змея перемещается в эти позиции на экране, и без выполнения каких-либо явных проверок, таких как «if (snake_position == some_position)», игра автоматически делает все, что от нее требуется, для всего, что происходит в игре, очень похоже на то, как когда вы нажимаете кнопку в форме, действие, назначенное этому событию, выполняется автоматически, без необходимости проверять событие самостоятельно.
Видите ли, я мог бы использовать форму и события по умолчанию, которые предоставляет C #, но я этого не сделал. Я использовал интерфейс консоли и внедрил собственную систему событий.
Вот как это работает за кулисами:основной цикл для вашего приложения формы будет выполняться в потоке, который проверяет ввод всех кнопок и т. д. на экране. Каждый из этих элементов установит для используемой ими логической переменной значение true. Когда вы нажимаете эту кнопку, другой поток, выполняющий цикл, проверяет, что вы нажали, и, скажем, вы нажали кнопку с именем «button1», этой кнопке был бы назначен делегат; этот делегат затем выполняется с тем, на что он указывает.
Трудно объяснить, но имеет ли это для вас смысл?