CPU3D.com2D графикаО 2D графике → Создание кланов или рас юнитов в стратегиях

Создание кланов или рас юнитов в стратегиях

палитра цветов

Стандартный Windows интерфейс – GDI

Наверное, любой геймер играл в такие хиты, как WarCraft и StarCraft. Известно, что население той или иной миссии не ограничивается количеством рас в игре. Так, например, в WarCraft’e существуют всего две расы: Люди и Орки, в StarCraft’e таких рас три: Люди, Зерги, Протосы. Однако, помимо рас существуют еще и кланы, которые принадлежат одной и той же расе, но различаются между собой цветом. Вот о том, как клонировать спрайты, но сделать их различными по цвету и пойдет разговор.

Можно сделать все очень просто – наделать столько спрайтов, сколько кланов полагается в игре и вся проблема решена, но представьте себе, что в игре, которую Вы пишите, полагается сделать три расы в каждой спрайтов по 400. Если к каждой расе сделать 6 кланов, то итоговое количество спрайтов в игре станет равным: 3*400*6 = 7200. Не правда ли многовато? И хотя этот способ самый простой и, скорее всего, самый быстро действенный по результатам работы получившейся потом игры, но слишком большой расход оперативной памяти не даст Вам покоя, он будет мучить Вас и днем и ночью.

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

После создания спрайтов, те части спрайта, которые должны менять цвет, делаются серым, так чтобы составляющие цвета (R, G, B) в каждом сером пикселе были равны между собой. Вывод спрайта на экран осуществить попиксельно, проверяя в цикле каждый пиксель на принадлежность серому цвету. Если цвет не является серым вывести его на экран без изменений, если является – изменить и вывести. Например, мы хотим вывести на экран спрайт, принадлежащий красному клану:1
2
3
4
5
6
7
8 For i := 0 to Sprite.Width-1 do
For j := 0 to Sprite.Height-1 do
Begin
If Sprite.Pixels[i, j]=GrayColor then
Canvas.Pixels[i, j]:=RedColor
Else
Canvas.Pixels[i, j]:=Sprite.Pixels[i, j];
End;

При этом интенсивность красного цвета должна быть пропорциональна интенсивности серого в каждом конкретном пикселе. Вы можете написать несколько строчек кода для расчета интенсивности красного на основе серого цвета, но можете и не писать, т. к. этот способ далеко не лучший. Он накладывает ряд ограничений. Во-первых ни один находящийся в здравом рассудке человек не будет совершать попиксельный вывод на экран, т. к. быстродействие такого приложения сможет вывести из себя даже слона, во-вторых мы не сможем использовать оттенки серого цвета для изображения частей спрайта не участвующих в смене цветов( А, простите, каким цветом мы будем рисовать рыцарские доспехи и амуницию?) и в-третьих процедура расчета интенсивности нового цвета на основе интенсивности серого тоже займет порядочно времени и вызовет торможение программы.
Способ цветовой ротации

Второй способ основан на цветовой ротации.
О цветовой ротации рассказано много. В основном, когда используют этот термин, имеют в виду изменение палитры в восьмибитном режиме. Иногда этот способ называют Pallete Animation. Но как бы красиво это не называлось, нам это не походит. Во-первых, я надеюсь, мы не собираемся делать игру в восьмибитном режиме, во-вторых, мы работать будем не с палитрой, а с отдельными битами цвета.

На рисунке изображено представление цвета в 24 – битном режиме. Палитра, как таковая, отсутствует, так как она не нужна. Каждый оттенок представлен одним байтом ( восемь бит). Общее количество цветов зашкаливает аж за 16 миллионов. Чем нам это может быть полезно? Вот если мы сделаем наши спрайты таким образом, чтобы те части спрайта, которые должны менять цвет в зависимости от клана, были нарисованы только оттенками одного цвета ( например только красным – первые восемь бит), то получим возможность получить другие цвета. Как это работает? Есть такая ассемблерная операция, называется циклический сдвиг. Это когда берется какое-нибудь число и биты в нем циклически переставляются, первый становится последним, второй становится первым и так далее. Иногда в обратную сторону. Так вот если у нас изменяющиеся цвета выполнены в одном только красном оттенке, то у этих пикселей биты с 1 по 8 (вернее с 0 по 7) могут быть как единицей, так и нулем. Все остальные биты заведомо будут нулями. Теперь, если мы выполним циклический сдвиг вправо на 8, то все биты красного цвета переместятся туда где расположен синий цвет, в результате чего цвет станет оттенком синего. Если сдвинем вправо на 16 или влево на 8, то биты красного цвета займут места битов зеленого цвета – цвет станет зеленым. Так, получается, чтобы получить новый цвет, требуется узнать какой цвет имеем на данный момент, вычислить, на сколько сдвигать, сдвинуть прямо на изображении в памяти и вывести картинку на экран. Все. Это очень хороший способ, основное преимущество которого состоит в том, что не требуется никаких дополнительных спрайтов или временных буферов и достаточно высока скорость выполнения, но основной его недостаток сводит на нет его преимущества – мы может получить только три клана ( синий, зеленый, красный ). Бывают ситуации, когда этого вполне достаточно ( игра Z ), но в заголовке статьи упоминается игра WarCraft, а там кланов намного больше. Есть способ лучше – РОНДО!, то есть я хотел сказать – МАСКИ!



Источник: http://delphi-graphics.ru