Здравствуйте! Одна из основополагающих в разработке игр - это оптимизация, и если вы разрабатываете более-менее крупный проект, вы должны о ней задуматься. Сегодня мы рассмотрим один из способов оптимизации - динамическое выделение памяти.
Нужно понимать, что каждая переменная занимает какой-то объем памяти, в зависимости от ее типа. Ниже представлены основные типы переменных, диапазон их значений и занимаемая память.
И так, выше мы ознакомились с диапазоном значений переменных и занимаемую ими память. Но как же нам с этой памятью работать? В этом нам помогут указатели, а так же операторы new и delete. Для начала, что же такое указатели? Указатель - это переменная, значением которого является адрес ячейки памяти. Как известно, у каждой переменной есть свой индивидуальный адрес памяти, которую она занимает. взять этот адрес мы можем при помощи оператора взятия адреса '&'. Для наглядности, рассмотрим код ниже.
Мы создали целочисленную переменную и инициализировали ее. Далее, в первой строке консоли мы вывели ее значение(10), а затем и адрес(0018FCB8).
Теперь, когда мы мы знакомы с адресами памяти и указателями, научимся их использовать во благо игростроя. Для чего же они в нем используются? Для примера, возьмем такую игру, как GTA. Все мы наверняка в нее играли, да и пример получится очень наглядным. Если стоять на одном месте, то NPC будут проходить мимо главного героя, и, отойдя на определенную дистанцию, исчезнут(выгрузятся). Если бы они просто выгружались, тогда оптимизацией это служило бы слабой, так как у нас остались переменные от них, которые занимают какую-то память. Поэтому, эту память нужно динамически создавать и очищать. Рассмотрим код ниже.
В нем есть создание переменной с выделенной под нее память(int *a = new int();), инициализировали ее(*a = 10;), использовали(cout << "*a = " << *a << endl;) и удалили(delete a;). Таким образом, использовав переменную и потеряв в ней надобность, мы удалили ее и очистили память для новых переменных. Аналогичным образом работает и вышеприведенный случай с GTA: создается некая переменная(-ые) или массив с информацией о NPC(появление NPC в радиусе действия), она(-и) используется(взаимодействие с игроком) и удаляются(после того, как NPC умер и исчез/вышел за радиус действия/...).
На этом все, надеюсь, эта статья была кому-то полезна и интересна(если так, то мы можем продолжить разбирать эту и схожие темы).
На самом деле я понятия не имею, каким образом NPC и их память реализована в GTA, но вышеуказанный способ вполне мог сгодится для этого.
Также если вы считаете, что данный материал мог быть интересен и полезен кому-то из ваших друзей, то вы бы могли посоветовать его, отправив сообщение на e-mail друга:
Игровые объявления и предложения:
Если вас заинтересовал материал «С++. Работа с памятью», и вы бы хотели прочесть что-то на эту же тему, то вы можете воспользоваться списком схожих материалов ниже. Данный список сформирован автоматически по тематическим меткам раздела.
Предлагаются такие схожие материалы:
Если вы ведёте свой блог, микроблог, либо участвуете в какой-то популярной социальной сети, то вы можете быстро поделиться данной заметкой со своими друзьями и посетителями.
Общий уровень низкий. Отмечу ошибки и опечатки при небольшом объёме материала. Автор не владеет терминологией («память нужно... создавать»). Код и результаты работы отображены на снимке экрана, что затрудняет чтение. (Второй снимок дублирует первый, это ошибка.)
«Один из способов оптимизации — динамическое выделение памяти». Сперва надо договориться о том, что оптимизируем. Динамическое выделение памяти имеет свои недостатки и достоинства. Критерий не озвучен! Дальше смысла нет что-то обсуждать.
«Представлены основные типы переменных, диапазон их значений и занимаемая память». Неверно. В C++ эти значения зависят от конкретной платформы.
Но как же нам с этой памятью работать? В этом нам помогут указатели... Совсем не обязательно!
Непонятно откуда взялся пример про ГТА, в чём автор позже признаётся: «На самом деле я понятия не имею, каким образом NPC и их память реализованы в GTA, но вышеуказанный способ вполне мог сгодиться для этого».
Резюме: много фактических ошибок, ошибки в терминах, несвязное изложение, отсутствие доказательной базы.
Сегодня мы рассмотрим один из способов оптимизации - динамическое выделение памяти.
Динамическое выделение памяти к оптимизации не имеет никакого отношения. Наоборот, ради оптимизации избегают частого использования new/delete: * Есть шаблон/паттерн программирования/проектирования Объектный пул (Object pool), где память выделяется заранее, потому что постоянные выделения памяти в кучи (new/delete) ухудшают производительность. * Иногда очередь реализуют не через список узлов в куче (связанный список), а через массив, пример: http://gameprogrammingpatterns.com/event-queue.html#a-ring-buffer. Также замечу, что надо избегать явного использования new/delete и использовать только в низкоуровневом коде, в обычном коде используют умные указатели. Ссылка по теме https://habrahabr.ru/company/aligntechnology/blog/283352/.