constructor TFirstComp.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
SecondComp:=TSecondComp.Create(SELF);
end;
Т.е. дочернему компоненту в качастве владельца передавайте его непосредственного хозяина.
Посмотрите компонент RichEdit98 (полностью бесплатный). ftp://ftp.bcsmi.minsk.by/alex/
Глюки
При увеличении размера компонента TImage в RunTime пытаюсь рисовать заново на всем поле, но отображается только часть компонента (прежнего размера). В чем дело?
Ответ: Нужно при инициализации выполнить SetBounds(), с максимальными размерами.
Обнаружил, что компонент QReport никак не реагирует на установки принтера PrinterSetup диалога, вызываемого нажатием кнопочки собственного Preview!
В QuickReport есть собственный объект TQRPrinter, установки которого он использует при печати, а стандартные установки принтеров на него не влияют. В диалоге PrinterSetup, вызываемом из Preview можно лишь выбрать принтер на который нужно печатать (если, конечно, установлено несколько принтеров).
Советую поставить обновление QReport на 2.0J с www.qusoft.com.
Перед печатью (не только из QReport) программно установите требуемый драйвер принтера текущим для Windows
function SetDefPrn(const stDriver : string) : boolean;
begin
SetPrinter(nil).Free;
Result := WriteProfileString('windows', device', PChar( stDriver));
end;
После печати восстановите установки.
Создание редактора карт в стратегиях типа WarCraft
Довелось мне как-то озадачиться идеей написать редактор карт для моей новой игры. Скажу сразу, что задача эта не из простых. Приступим сразу к делу. Как правило, в двумерных стратегических играх типа Warcraft, Heroes of Might and Magic, Z и т. д. карты строятся из ячеек. Иными словами, карта — это матрица с некоторыми числовыми значениями внутри ячеек. Эти значения есть номера текстур (растровых картинок с изображениями земли, воды, камней и т. д., из которых и будет склеиваться Ваш уникальный ландшафт)
Рисунок 1
На рисунке изображена ну очень маленькая карта с размером матрицы 3×3. Для создания подобной карты задается двумерный массив ( Map : Array[3,3] of Byte ), записываются, каким-либо образом, в каждую ячейку порядковые номера текстур и при выводе карты на экран эти номера читаются из массива. Ну например:
…
For i := 0 to 2 do
For j := 0 to 2 do Begin
Number := Map[i,j];
X := J * TextureWidth;
Y := i * TextureHeight;
DrawTexture(X,Y,Number);
End;
…
Где Number – номер текстуры,
Х – координата текстуры на экране,
Y – то же самое,
DrawTexture – некая процедура вывода текстуры на экран.
Совет!!!
Если Вам заранее не известно из какого количества ячеек будет состоять Ваша карта, не используйте Tlist в Tlist'e для ее создания. Советую воспользоваться PbyteArray.
( GetMem(PbyteArray,MapWidth*MapHeight*SizeOf(Тип ячейки)) ).
Тип ячейки в нашем случае – Byte. Обращение в этом случае будет таким: Number := PbyteArray[Y*MapWidth + X]; Где X,Y – координаты нужной ячейки в матрице.
Все что мы рассмотрели выше подходит для карт на основе только лишь одного типа земли. Взгляните на рисунок расположенный выше. Вы увидите, что поскольку все текстуры разные — карта как-бы состоит из квадратиков. Кому она такая нужна? Хочется чтобы эти текстуры плавно перетекали друг в друга. Отсюда есть три выхода:
• Создавать карту из текстур мало отличающихся друг от друга и при рисовании карты выбирать их случайным образом.
• Налепить целю кучу "пересекающихся" между собой текстур и класть их на карту вручную.
• Так же налепить ту же кучу текстур и написать программу позволяющую автоматически распределять их на карте.
Первый способ не очень интересен. Он скорее подходит для создания ролевых игр. Где, как правило, присутствует базовый тип земли, а все остальное, такое как вода, камни, травка представляется объектами. Второй способ легок по реализации, но очень утомительно будет потом создавать карты в таком редакторе.
Посмотрите на рисунок. Если у Вас вся карта состоит из текстур с травой, а Вам надо добавить участок воды, то мы видим, что для того чтобы добиться плавного перетекания Вам придется добавить еще 8 промежуточных текстур окружающих текстуру с водой. Если делать это вручную (по второму способу), то это займет слишком много времени и сил. Поэтому нам второй способ тоже не подходит. Мы остановимся на третьем способе и будем создавать карту подобно тому, как это происходит в WarCraft'e. При добавлении текстуры на карту (фактически — записи номера текстуры в определенную ячейку матрицы), окружающие ее текстуры будут рассчитываться автоматически. Как этого добиться?
Рисунок 2
Я достаточно долго ломал голову над этой проблемой. Я пытался найти какой-нибудь способ позволяющий не утруждать компьютер громоздкими вычислениями и работать максимально быстро и эффективно. Один раз я даже вывел формулу, по которой рассчитывались новые значения ячеек, но она увы имела ограниченное действие (только 2 типа земли) и плохо подходила для создания карт, где требуется максимальное разнообразие. Но достаточно лирики, давайте вернемся к нашим баранам.
Прежде всего необходимо выяснить — какое количество переходных текстур нам понадобится для обеспечения плавного перетекания между двумя типами земель. Здесь есть свои тонкости.
Представим, что у нас имеется два типа земли: ВОДА и ЗЕМЛЯ, тогда: Во-первых нам понадобятся две базовых текстуры, это текстуры полностью заполненные водой или землей.
Рисунок 3
Во вторых нам понадобятся промежуточные текстуры. Сколько их нужно мы сейчас посчитаем.
Рисунок 4
Оказалось, что для плавного перетекания двух земель друг в друга надо 14 промежуточных текстур, плюс две базовых. Итого 16. Всякий программист знает, что это хорошая цифра.
Возможно кто-то спросит: А зачем так много? Не достаточно ли 8 текстур, как на рисунке 2 — где трава пересекается с водой? Нет не достаточно. Ведь ситуации бывают разные. Окружающие ячейки могут быть не полностью забиты травой ( в данном случае землей ), и тогда понадобятся дополнительные текстуры.
Тогда может последовать другой вопрос: Почему так мало текстур? Где например текстуры когда вода с трех сторон окружена землей, и с четырех, и другие? Не следует ли предусмотреть все случаи?
И это правильный вопрос, но здесь все зависит от конкретной реализации алгоритма автоматического вычисления необходимой текстуры. В моем примере он реализован так, что остальные текстуры не нужны. Объясню наглядно:
1. Текстуры воды окруженные землей с двух противоположных сторон превращаются в базовую текстуру земли (в текстуру заполненную только землей). Соответственно то же самое происходит когда вода окружена с трех или четырех сторон.