Найти в Дзене
REVERSE

Reverse engineering. Основы работы игр part VI

Классы и данные
Любые данные, которые могут быть обновлены в игре, хранятся в переменных. Это включает в себя такие вещи, как счет игрока, позиция или деньги. Эти переменные объявляются в коде. Пример определения переменной в C может выглядеть следующим образом:
Этот код объявляет денежное значение как целое число. Как мы узнали из предыдущего урока, целочисленные значения в Cи - это целые числа
Оглавление

Классы и данные

Любые данные, которые могут быть обновлены в игре, хранятся в переменных. Это включает в себя такие вещи, как счет игрока, позиция или деньги. Эти переменные объявляются в коде. Пример определения переменной в C может выглядеть следующим образом:

Этот код объявляет денежное значение как целое число. Как мы узнали из предыдущего урока, целочисленные значения в Cи - это целые числа (например, 1, 2 или 3). Представьте себе, если бы нам пришлось отслеживать деньги для нескольких игроков. Один из способов сделать это - иметь несколько объявлений, например:

-2

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

-3

Если бы мы добавили еще одного игрока, нам пришлось бы пойти и обновить каждый раздел кода, который изменил деньги игроков. Лучшим подходом было бы объявить эти значения в списке. Затем мы можем использовать инструкцию, известную как цикл, чтобы пройти через каждый элемент в списке. Это называется итерацией. В языке Си списки обычно реализуются с использованием так называемого массива. Для наших целей можно предположить, что эти два слова являются синонимами. Один тип цикла в языке Си известен как цикл" for". Циклы for делится на три сегмента: начальное значение, условие и способ обновления значения на каждой итерации. Зная это, пример предыдущего кода может быть написан следующим образом:

-4

Теперь нам нужно будет только обновить переменную current_players, чтобы добавить поддержку другого игрока.

Чтобы упростить разработку сложных приложений, разработчики часто используют модель программирования, известную как объектно-ориентированное программирование или ООП. В ООП переменные и функции группируются в коллекции, называемые "классами". Классы, как правило, самодостаточны. Например, многие игры будут иметь класс "Player". Этот класс будет содержать такие поля(переменные класса), как позиция игрока, имя или деньги. Он также будет содержать функции для изменения этих полей. Один из примеров класса Player может выглядеть следующим образом:

-5

Игры часто содержат списки классов. Например, в игре Quake 3 есть массив всех игроков, подключенных в данный момент к серверу. Каждый из этих игроков имеет свой собственный класс "Player". Чтобы вычислить счета игрока, он будет просматривать каждого игрока в массиве и смотреть на количество убийств, которые у них есть.

Память

Игры имеют много больших ресурсов, таких как изображения и звуки. Они должны быть загружены с жесткого диска, как правило, на этапе "инициализации" игры. После загрузки они помещаются в оперативную память вместе с кодом и данными игры. Поскольку игры настолько велики, они должны постоянно загружать различные данные из оперативной памяти в регистры для работы. Эта загрузка обычно выполняется командой "mov". Эта команда переместит часть данных из памяти в регистр. Наш пример увеличения денег, выполняемый процессором, может выглядеть следующим образом:

-6

По адресу 0x12345678 берется значение и командой "mov" перемещается в регистр eax, далее следующая команда "add" прибавляет к значению из ячейки памяти единицу и последняя команда перемещает увеличенное на единицу значение обратно в ячейку по тому же адресу.

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

-7

В этом случае процессор должен был найти местоположение денег игрока на основе местоположения класса "Player"(адрес) + "offset"(смещение) .

Продолжение следует...