Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Demo,Intro _ Елка, снег, игрушки ...

Автор: volvo 1.12.2006 19:15

Близится Новый Год...

Скоро опять будем наряжать елку. Вот я и подумал, а чего бы мне елку не сделать на мониторе? smile.gif

Естественно, подобные темы уже были на форуме. Вот тут, например: http://forum.pascal.net.ru/index.php?showtopic=8542
или тут: http://forum.pascal.net.ru/index.php?showtopic=8547

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

При написании данной программы я использовал уже готовые свои модули (они, кстати, выложены и на форуме:
http://forum.pascal.net.ru/index.php?s=&showtopic=2085&view=findpost&p=38351
, за объяснениями по поводу работы со списками идем сюда: http://forum.pascal.net.ru/index.php?s=&showtopic=2706&view=findpost&p=23570
...

Примечание: в реализацию модулей item_dx + list_dx внесены некоторые изменения, сейчас эти модули в стадии отладки (эта программа изначально задумывалась, кстати, как одна из тестовых, и только потом пришла идея сделать именно елку), поэтому сырые исходники выкладываться не будут, я присоединяю архив с *.TPU / *.PPU+*.O файлами, чтобы можно было откомпилировать и посмотреть работу основной программы как с использованием TP, так и на FPC. Как только станет понятно, что новая версия TList не содержит глюков и багов, я просто обновлю исходники по первой ссылке...

excl.gif [attachmentid=4380]

Комментироваться ниже будет только основная часть программы (в архиве комментарии отсутствуют).

uses
crt, graph
item_dx, list_dx;

const
{
Эта константа - для будущего использования...
Мне, если честно, не совсем нравится, как ложится снег на "землю", я попробовал сделать
что-то вроде сглаживания, но это не совсем то, что я хотел (а хотелось сделать сугробы или
нечто на них похожее), так что программа тоже еще будет дорабатываться, до НГ есть время
}
linear_size = 25;

{ Цвет отображения снега }
snow_color = white;

type
{
Указатель на массив, хранящий "уровень снега" для каждой вертикальной колонки
пикселей на картинке + еще несколько значений влево/вправо, чтобы не вылетать
за пределы массива при произведении сглаживания...
}
pzero_array = ^zero_array;
zero_array =
array[1 - linear_size .. (maxint div 2) div sizeof(integer)] of integer;

{
Собственно, сама функция сглаживания, пока не совсем правильно работающая
}
function linearize(const current: integer;
const arr: array of integer): integer;

function index(x: integer): integer;
begin
index := x - 1;
end;

var
i, left, right: integer;
s: longint;
begin
s := 0;
for i := current-linear_size to current+linear_size do
s := s + arr[index(i)];
s := trunc(s / (2 * linear_size + 1));

if arr[index(current)] - 1 < s then linearize := 0 else linearize := 1;
end;



var
gZero: pzero_array;
snow_level: integer;
const
snow_count: longint = 0;


type
{
Объект - снежинка, наследник типа tbase, что позволяет создать список снежинок
}
ptsnow = ^tsnow;
tsnow = object(tbase)
{ текущие координаты снежинки }
x, y: integer;

{ скорость (гориз. и верт. соответственно) }
Vx, Vy: double;

{ является ли снежинка активной (при получении значения false объект изымается из списка) }
active: boolean;

constructor init;
destructor done; virtual;

procedure show;
procedure hide;

{ пересчет координат снежинки }
procedure recalc;

private
{ масса снежинки в граммах }
mass: integer;

{ буфер, хранящий изображение под снежинкой }
under: integer;
end;

{
Функция сравнения снежинок (на самом деле, в этой функции проверяется, является ли значение
поля active одной снежинки аналогичным значению поля active другой)
}
function snow_item_compare(const a, b: ttype): boolean;
{$ifndef FPC} far; {$endif}
begin
{
поскольку фактические параметры имеют тип указателя на объект - предок,
для получения доступа к полю требуется привести указатель к нужному типу...
}
snow_item_compare := (ptsnow(a)^.active = ptsnow(b)^.active)
end;


const
{
коэффициент вертикальной составляющей скорости:
чем он больше, тем быстрее будут падать снежинки
}
VScale = 1.25;

{
"вероятность внезапного порыва ветра", что заставит снежинку полететь в другом
направлении (на данный момент меняется знак горизонтальной составляющей скорости)
}
wind_probability = 0.01;

constructor tsnow.init;
const
{
при выпадении каждой 2000-ной (почему не 2007 =) ) снежинки
высота снежного покрова _может_ увеличиться еще на 1 пиксел
}
every = 2000;
begin
inherited init;

{ счетчик снежинок }
inc(snow_count);

{ регулируем высоту снежного покрова }
snow_level := 10 + (snow_count div every);

{ вновь созданная снежинка еще не лежит на земле }
active := true;
mass := random(5) + 1;

{ координаты X и Y }
x := random(getmaxx);
y := random(getmaxy div 4);

{ Вычисляем скорости }
Vx := random(5) - 2;
Vy := mass * VScale;

show;
end;

destructor tsnow.done;
begin end;

procedure tsnow.show;
begin

{ изображение под снежинкой: если уже цвет снега - не сохранять }
under := getpixel(x, y);
if under = snow_color then under := -1
else putpixel(x, y, white);

end;
procedure tsnow.hide;
begin

{ если что-то было сохранено, то надо его восстановить }
if under <> -1 then
putpixel(x, y, under);

end;

procedure tsnow.recalc;
var lin: integer;
begin
{ если случился "порыв ветра" - поменять направление движения снежинки }
if random < wind_probability then Vx := - Vx;

{ пересчитываем координаты в зависимости от скоростей }
x := trunc(x + vx);
y := trunc(y + vy);

{
если снежинка достигла "уровня снега", то делаем следующее: если этот самый
"уровень" не выше разрешенного (см. описание snow_level), то проверяем, что
скажет функция сглаживания, и в зависимости от этого либо поднимаем, либо нет
уровень снега в этой колонке, и, в любом случае, "выводим снежинку из игры"
}
if y >= gZero^[x] then begin

if gzero^[x] > getmaxx - snow_level then
dec(gZero^[x], linearize(x, gZero^));

y := gZero^[x];
active := false;

end;
end;


{
Переходим к реализации "гирлянды"
}
type
{
этот массив может хранить 2 цвета лампочки, соответственно -
во включенном, и в выключенном состоянии
}
tcolorstate = array[boolean] of integer;

{
сам объект - "лампочка" - тоже наследник tbase, что позволяет хранить
всю гирлянду в таком же списке типа tlist
}
ptlight = ^tlight;
tlight = object(tbase)
{ координаты центра лампочки }
x, y: integer;

{ ее цвет (выкл./вкл.) }
color: tcolorstate;

{ включена ли она в данный момент }
is_active: boolean;

constructor init(px, py: integer; pcolor: tcolorstate);
destructor done; virtual;

procedure show;
end;

constructor tlight.init(px, py: integer;
pcolor: tcolorstate);
begin
inherited init;

x := px; y := py; color := pcolor;
{ в момент инициализации выключаем лампу }
is_active := false;
end;
destructor tlight.done;
begin end;

procedure tlight.show;
begin
setfillstyle(solidfill, color[is_active]);
setcolor(color[is_active]);
fillellipse(x, y, 5, 5);
setcolor(white);
circle(x, y, 5);
end;


Const
min = 1;

ColorizeLevel = 8;
LightsOnLevel = 14;

{
Количество и цвета существующих лампочек...
Вся гирлянда будет состоять из ламп этих цветов
}
maxLightColors = 4;
light_colors:
array[0 .. pred(maxLightColors)] of tcolorstate = (
(blue, lightblue),
(red, lightred),
(brown, yellow),
(magenta, lightmagenta)
);

{
Следующие 2 процедуры рисуют фрактальное дерево
(точнее - "папоротник")
}
Procedure lineto1(level: integer; var lst: tlist;
x, y : Integer; l, u : real);
var the_color: integer;
Begin

Line(x, y, Round(x + l * cos(u)), Round(y - l * sin(u)));
if level = ColorizeLevel then begin

{
с вероятностью 15% будет выбран светло-зеленый цвет
"листа", иначе - темно зеленый.
}
if random(100) < 15 then the_color := lightgreen
else the_color := green;

setfillstyle(solidfill, the_color);
fillellipse(Round(x + l * cos(u)), Round(y - l * sin(u)), 3, 3);
end
else if level = (LightsOnLevel) then begin
{
"Лампочки" будут располагаться на определенном уровне "елки". В моем случае -
на 14-ом... Да и то не на каждой такой ветке, а только на 75% из них:
}
if random(100) > 25 then
lst.append(
new(ptlight,
init(Round(x + l * cos(u)), Round(y - l * sin(u)),
light_colors[random(maxLightColors)])
)
);
end;

End;

{
Собственно, рекурсивная отрисовка "папоротника"
}
Procedure Draw_fern(level: integer; var lst: tlist;
x, y : Integer; l, u : real);
Begin

If l > min then Begin

{
этого в исходном алгоритме нет, я добавил этот вызов для того, чтобы
"елка" была заполнена внутри, а не просто очерчивался ее контур
}
if (level > 1) and (level < 5) then
draw_fern(5, lst, x, y, 21, u);

lineto1(level, lst, x, y, l, u);
x := Round(x + l * cos(u));
y := Round(y - l * sin(u));

Draw_fern(succ(level), lst, x, y, l*0.45, u - 14*pi/30);
Draw_fern(succ(level), lst, x, y, l*0.45, u + 14*pi/30);
Draw_fern(succ(level), lst, x, y, l*0.73, u + pi/30);
End;

End;



{
А теперь - переходим собственно к реализации "сцены":
}

{
Первое что нам понадобится - задержка перед очередной перерисовкой
изображения. Поскольку программа тестировалась как на Turbo, так и на
Free Паскале, я воспользовался директивами компилятора
}
const
to_delay =
{$ifdef FPC}
55
{$else}
1255
{$endif}
;
var
grDriver, grMode:
{$ifdef FPC}
smallint
{$else}
integer
{$endif}
;
ErrCode: integer;

{
Еще одна часть программы, которая будет важна при компиляции на TP, а для FPC
ее быть не должно - включение BGI драйвера непосредственно в EXE файл
}

{$ifndef FPC}
{$L EGAVGA.OBJ}
Procedure EGAVGADriverProc; External;
{$endif}

procedure OpenGraphix;
begin
{ инициализируем нужный графический режим }

{$ifdef FPC}
grDriver := d8bit; grMode := m800x600;
{$else}
If RegisterBGIDriver(@EGAVGADriverProc) < 0 Then Begin
WriteLn('Error registering driver: ',
GraphErrorMsg(GraphResult));
Halt( 100 )
End;
grDriver := Detect;
{$endif}

InitGraph(grDriver, grMode, '');
ErrCode := GraphResult;
if ErrCode <> grOk then begin
Writeln('Graphics error:', GraphErrorMsg(ErrCode));
writeln('Press Enter to halt()'); readln; halt(100);
end;
end;
procedure CloseGraphix;
begin
{ закрываем графику }
closegraph;
end;

{
Константа показывает количество снежинок, которое будет присутствовать на экране
(можно ее изменять, но учтите что программа выполняет отнюдь не маленький объем
вычислений для каждой такой снежинки, и при больших значениях snow_amount может
начать подтормаживать)
}
const
snow_amount = 400;

{ Вот это и есть наша "сцена"... }
type
tscene = object
{ список снежинок }
snowlist: tlist;
{ гирлянда - список лампочек }
lightlist: tlist;

constructor init;
destructor done;

{ и основное действие =) }
procedure run;
end;

{
Ниже описаны функции, позволяющие одним вызовом произвести над всеми
элементами списка какую-то операцию в зависимости от определенного условия
}

{ 1) показать лампочку (смысл: отрисовка гирлянды) }
procedure show_lights(p: ptitem);
{$ifndef FPC} far; {$endif}
begin
with ptlight(p^.info)^ do show;
end;

{ 2) зажечь/погасить лампу }
procedure light_the_lamp(p: ptitem);
{$ifndef FPC} far; {$endif}
begin
with ptlight(p^.info)^ do begin
is_active := not is_active; show;
end;
end;

{
А это - функции-условия (уточняющие, КОГДА производить те или иные действия)
}

{ 1) редко (с вероятностью около 5%) }
function seldom(p: ptitem): boolean;
{$ifndef FPC} far; {$endif}
begin
seldom := (random(100) < 5);
end;

{ 2) всегда (функция всегда возвращает "истину") }
function always(p: ptitem): boolean;
{$ifndef FPC} far; {$endif}
begin
always := true;
end;


{ инициализация сцены: }
constructor tscene.init;
var
i: integer;

begin
{ Запускаем графический режим }
OpenGraphix;

{ инициализируем список для хранения "гирлянды" }
lightlist.init;
{
и отрисовываем "елку"; напомню, в процессе ее рисования
лампочки только добавляются в список, но не показываются
}
Draw_fern(1, lightlist, getmaxx div 2, getmaxy, 130, pi/2);

{
а вот теперь используем возможность запустить зажигание для
всех лампочек, которые есть в списке
}
lightlist.ForEachTrue(always, show_lights);

{
до этого момента случайность нам была не нужна, елка будет отрисовываться
одинаково при нескольких последовательных запусках, а вот снежинки должны
как раз появляться случайно...
}
randomize;

{ инициализируем список снежинок }
snowlist.init;

{
запрашиваем место в дин. памяти для хранения "уровня снега", и заносим туда
случайные значения, мало отличающиеся (разница в 5 пикселей максимум) от
нижней границы экрана.

Я не стал делать этот массив статическим только потому, что на этапе компиляции
(ДО вызова initgraph) размер графического экрана неизвестен, а делать что-то
"про запас" - "это не наш метод" ( С )
}
getmem(gZero, (getmaxx + 2 * linear_size) * sizeof(integer));
for i := (1 - linear_size) to (getmaxx + linear_size) do
gZero^[i] := getmaxy - random(5);

{ Добавляем в список нужное количество снежинок }
for i := 1 to snow_amount do {begin}
snowlist.append(new(ptsnow, init));
end;

{
При "разрушении" сцены я удаляю все объекты в порядке, _строго обратном_
порядку их создания (иногда помогает при поиске багов)
}
destructor tscene.done;
begin
freemem(gZero, (getmaxx + 2 * linear_size) * sizeof(integer));

snowlist.done;
lightlist.done;
CloseGraphix;
end;

{
очередная процедура, показывающая, ЧТО делать с элементами списка.
Здесь - приводим указатель на базовый класс к типу "указатель на снежинку", и
скрываем/пересчитываем координаты/показываем ее
}
procedure refresh(p: ptitem);
{$ifndef FPC} far; {$endif}
begin
with ptsnow(p^.info)^ do
if active then begin
hide; recalc; show;
end;
end;



procedure tscene.run;
var
i, count: integer;
just_non_active: ptsnow;
begin

{
Для того, чтобы сравнить две "снежинки" есть 2 пути:
1) перегрузка оператора "=" (в FPC совершенно нет с этим никакой проблемы,
но проблема есть в TP)

2) инициализация "пустого" объекта с нужным нам значением поля, и вызов функции,
сравнивающей именно значения этих полей в переданных ей объектах (это способ
будет работать как в FPC, так и в TP, и именно его я и реализовал)
}

{ Инициализируем доп. объект, и его поле active устанавливаем в False }
just_non_active := new(ptsnow, init);
just_non_active^.active := false;

{ основной цикл программы }
while true do begin

{
Обновляем положение всех снежинок на экране
(еще раз: для каждого итема списка снежинок
"всегда (always)" вызываем функцию refresh)
}
snowlist.ForEachTrue(always, refresh);

{
если на данной итерации появились "упавшие на землю" снежинки (очевидно,
это те, у которых Active = False), то удалить их из списка (и количество удаленных
элементов) запомнить в переменной count
}
count := snowlist.remove(just_non_active, snow_item_compare);

{
поскольку count снежинок были "выведены из игры", и также удалены из списка,
добавляем в список еще столько же снежинок... Таким образом, у нас всегда будет
snow_amount _падающих_ снежинок...
}
for i := 1 to count do
snowlist.append(new(ptsnow, init));

{
Здесь даем инструкцию "гирлянде" зажечь лампы, только не "всегда", а
"редко (seldom)"... Как я показывал выше, функция seldom вернет true только
при 5% вызовов
}
lightlist.ForEachTrue(seldom, light_the_lamp);

{ приостанавливаем действие }
delay(to_delay);

{
Проверяем, не была ли нажата клавиша. Если была - выходим из цикла
}
if keypressed then break;

end;

{
Все, цикл окончен, больше не потребуется сравнивать "снежинки" с образцом,
можно его удалить, чтобы не было утечки памяти ( хоть и кратковременной =) )
}
dispose(just_non_active, done);

{ enter выходит из метода Run }
readln;
end;

{
Как и рекомендуется в ООП - основная программа состоит только из
инициализации объекта, запуска его основной функции, и удаления
}
var
scene: tscene;
begin
scene.init;
scene.run;
scene.done;
end.


Предложения по улучшению принимаются. Есть идея, например, добавить еще кое-где облака фоном (фрактальные, разумеется), возможно - звезды, Луну...

Автор: Michael_Rybak 1.12.2006 20:29

Очень красиво, спасибо smile.gif

А давай еще чтоб снег накапливался, и чтоб елка таким образом в сугроб постепенно превращалась smile.gif

Автор: Bokul 1.12.2006 22:33

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

lol.gif

Супер!!! Очень реалистично и красиво вышло yes2.gif good.gif

Автор: мисс_граффити 1.12.2006 23:45

Классно!
Когда ж на улице такая красотища будет?...

Автор: Bokul 2.12.2006 3:21

volvo, не мог бы ты выложить модуль с объектом tbase даже не в отлаженном виде?

Автор: volvo 2.12.2006 19:54

Цитата
не мог бы ты выложить модуль с объектом tbase даже не в отлаженном виде?
no1.gif Пока нет...

Вместо этого выкладываю новую версию программы, вот тут уже сглаживание присутствует в том виде, в котором я себе его представлял изначально... Правда, его реализация тоже пока скрыта, ибо есть подозрение, что возможны глюки...

Теперь вопрос: какая из реализаций более эффектно смотрится, прежняя или новая? (я про уровень снега)

Автор: Bokul 2.12.2006 23:22

Эта красивее smile.gif . Только замечены пара багов-небагов:
1 В снегу остаются пустоты, что есть очень красиво, но примерно когда снега выпадает 1-1.5 сантиметра, появляется сплошная пустота толщиной в несколько пикселей в виде почти-что горизонтальной линии. Такой эффект - периодический, и повторяется каждые 1-2 сантиметров, что есть не сильно реалистически.
2 Лампочки, они не засыпаются снегом, т.е. они засыпаются, но при перерисовки, при смене цвета, они опять появляются с под снега. В конце получим полностью белый экран с мерцающими лампочками.

Предложение сделать елку не фоновой, чтобы снег оседал на ее ветках.

Автор: volvo 2.12.2006 23:44

Цитата
но примерно когда снега выпадает 1-1.5 сантиметра, появляется сплошная пустота толщиной в несколько пикселей в виде почти-что горизонтальной линии.
yes2.gif Это была неудачная попытка сделать "таяние снега"... Теперь будем работать в правильном направлении smile.gif

Над НЕфоновой елкой работа уже ведется (это кстати задумывалось с самого начала)... + К этому, масса снежинок введена далеко не случайно, как только сумма весов снежинок, осевших на ветке, превысит некую критическую величину, снег будет обрушиваться вниз blum.gif

Автор: Archon 3.12.2006 3:46

Цитата
Только замечены пара багов-небагов:
1 В снегу остаются пустоты, что есть очень красиво, но примерно когда снега выпадает 1-1.5 сантиметра, появляется сплошная пустота толщиной в несколько пикселей в виде почти-что горизонтальной линии. Такой эффект - периодический, и повторяется каждые 1-2 сантиметров, что есть не сильно реалистически.
2 Лампочки, они не засыпаются снегом, т.е. они засыпаются, но при перерисовки, при смене цвета, они опять появляются с под снега. В конце получим полностью белый экран с мерцающими лампочками.

Ещё странно, что снежинки после падения разбухают, как возушая кукуруза при приготовлении.

Цитата
К этому, масса снежинок введена далеко не случайно, как только сумма весов снежинок, осевших на ветке, превысит некую критическую величину, снег будет обрушиваться вниз
shok.gifКруто.. good.gif

PS Сделай пару ёлочек поменьше на фоне и потемнее цветом. Сцена будет смотреться объёмно

Автор: Bokul 3.12.2006 4:32

Цитата
Ещё странно, что снежинки после падения разбухают, как возушая кукуруза при приготовлении.

Мне наоборот это нравится.

Автор: volvo 4.12.2006 3:10

Очередное обновление - драфтовая версия, я убрал цвета, чтобы был понятен замысел, кто хочет протестировать - запускайте и смотрите подольше... Как и обещал - теперь елка на совсем фоновая, на ветках накаплявается снег, и как только его накапливается много - он падает вниз...

Сразу хочу предупредить - этот архив исходников НЕ содержит вообще - только EXE, полученный после компиляции в FPC... Код УЖАСЕН, его надо сильно причесать, перед тем, как выкладывать ...


Автор: Archon 4.12.2006 3:39

lol.gif Ёлка - генератор снега. Снега с неё падает явно больше, чем на неё. Об этом можно судить по тому, что через 5 минут ёлка превратилась в сугроб. lol.gif
Кстати, снег с веток никуда не исчезает...

PS Может имеет смысл перенести тему в раздел Демо/Интро?

Автор: Altair 4.12.2006 14:48

Вы ничего не понимаете это снежный апокалипсис smile.gif

Клево, у меня на 20 примерно секунде елку просто завалило снегом smile.gif

Автор: volvo 4.12.2006 17:01

lol.gif lol.gif Это я в одном месте знак перепутал... Вместо "-" сделал "+"

Это исправлено, сейчас "причесывается" исходник, тему действительно переношу в "Демо + Интро"

Автор: Altair 5.12.2006 3:46

lol.gif *мысли вслух* На самом деле она должна была быть пылесосом smile.gif

Автор: настюша 17.12.2006 1:59

Извините что беспокою но просто очень хочется посмотреть на то как там все красиво...я оно выдает ошибку 15...о том что не найден файл GRAPH.TPU ... его надо где-то предварительно создать?....если да то скажите пожалуйста где и как unsure.gif ...

Заранее спасибо за ответ give_rose.gif

Автор: Bokul 17.12.2006 3:59

Ну как там дальнейшее развитии идет? Оно идет? Если нет, то повторю просьбу выложить модуль tbase... 10.gif

Автор: volvo 17.12.2006 4:35

Идет... Программа отлаживается, выковыриваются баги, кое-что добавляется... До НГ еще есть время... smile.gif

Цитата
оно выдает ошибку 15...о том что не найден файл GRAPH.TPU
Модуль GRAPH.TPU лежит (по крайней мере - должен лежать) в папке TP\UNITS... Скопируй его оттуда в папку с проектом, и компилируй.

Автор: Bokul 17.12.2006 10:13


{
Ниже описаны функции, позволяющие одним вызовом произвести над всеми
элементами списка какую-то операцию в зависимости от определенного условия
}

{ 1) показать лампочку (смысл: отрисовка гирлянды) }
procedure show_lights(p: ptitem);
{$ifndef FPC} far; {$endif}
begin
with ptlight(p^.info)^ do show;
end;


В связи недоступности модуля tbase smile.gif , прошу объяснить как эта функция обходит все элементы. И что за операция ptlight?

Автор: настюша 17.12.2006 17:28

Цитата

Модуль GRAPH.TPU лежит (по крайней мере - должен лежать) в папке TP\UNITS... Скопируй его оттуда в папку с проектом, и компилируй.

...наверное только должен...но там его почему то нету unsure.gif ...там есть ITEM_DX.TPU, EQUA.TPU, LIST_DX.TPU и все ... а что же тогда делать ...если нету, а?

Автор: volvo 17.12.2006 17:45

Под TP имелась в виду директория, где у тебя на компьютере установлен Turbo Pascal, а не в том архиве, который ты скачиваешь...

Автор: настюша 17.12.2006 18:46

Цитата

Под TP имелась в виду директория, где у тебя на компьютере установлен Turbo Pascal, а не в том архиве, который ты скачиваешь...

Ой mega_chok.gif ...извини те за....
....я все там внимательно просмотрела...там у меня его тоже нету....а откуда мне его тогда можно взять, а?
....просто очень хочется посмотреть что там у Вас за чудо получилось....

Автор: volvo 17.12.2006 18:58

Забирай:


Прикрепленные файлы
Прикрепленный файл  graph.rar ( 15.62 килобайт ) Кол-во скачиваний: 622

Автор: настюша 17.12.2006 19:07

Спасибо огромное give_rose.gif ...вот только оно опять не запускается уже с ошибко 116... mega_chok.gif

Оно пишет Must be in 8087 mode to compile this. и выдает это все на 68 строчке blink.gif
....почему?....что-то еще не так?...

Автор: volvo 17.12.2006 19:09

smile.gif Меню Options -> Compiler -> группа Numeric Processing все должно быть отмечено иксами...

Автор: настюша 17.12.2006 19:20

А теперь оно пишет ошибку 203 : Heap overflow error. unsure.gif
Может что-то еще надо в настройках поменять?

Автор: volvo 17.12.2006 19:28

Не знаю... У меня все работает на настройках по умолчанию...

Кстати, для TP окончательной версии программы не будет, будет только FPC версия ...

Автор: настюша 17.12.2006 19:30

ой....получилось вдруг!!!
....ВАУ КАК КРАСИВО!!!!! СУПЕР!!! Я ДАЖЕ ПОДУМАТЬ НЕ МОГЛА ЧТО ТАКУЮ КРАСОТУ МОЖНО В ПАСКАЛЕ СОТВОРИТЬ!!!!!
....ЕЛКА ПРОСТО ЗАМЕЧАТЕЛЬНАЯ....и совсем не заметно что с неё больше снега падает чем вообще в целом....это просто елка стоит на холмике таком... smile.gif и огоньки мне очень понравились!!!!

СПАСИБА БОЛЬШОЕ ЗА ТО ЧТО ПОМОГЛИ ЗАПУСТИТЬ И ТАКУЮ ЗДОРОВСКУЮ ВЕЩЬ ПРИДУМАЛИ...

Автор: Belchonok 2.09.2008 2:39

А сама программа в теме выкладывалась? Пока читала тему, поняла, что где-то выкладывалась, но нету...
Или вся (окончательная версия) программы -- в первом посте, и можно писать оттуда?
З.Ы. Насколько я представляю, это очень красиво.. Давно уже хочу посмотреть на такую программу

Автор: Lapp 19.09.2008 17:27

Цитата(Belchonok @ 1.09.2008 22:39) *
Или вся (окончательная версия) программы -- в первом посте, и можно писать оттуда?
Да, Belchonok. И дальше по теме smile.gif.
Успехов.

Автор: volvo 19.09.2008 17:34

Полная версия этой программы вообще никогда ЗДЕСЬ не выкладывалась... Полная версия лежит только у меня на сайте (кому надо - тот знает).

Автор: puporev 20.09.2008 13:20

Цитата
Полная версия этой программы вообще никогда ЗДЕСЬ не выкладывалась... Полная версия лежит только у меня на сайте (кому надо - тот знает).

Круто! Прочитал тему как детектив!

Автор: volvo 20.09.2008 15:19

puporev, флеймить будешь в созданных собой темах (причем в соответствующем разделе), ясно? Здесь не надо этого делать, это противоречит Правилам Форума (если для кого-то это словосочетание еще не потеряло всякий смысл).

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

Автор: Lapp 20.09.2008 18:52

Цитата(volvo @ 20.09.2008 11:19) *
А то, что на форуме творится беспредел и редактируются сообщения (причем анонимно, без указания, что это было откорректировано, кем и по какой причине) - это обращайся к администрации, и выясняй, в чем дело... Демо-версия здесь была, но как видно она кому-то не понравилась...
volvo, будь добр, выражайся конкретно и без недомолвок и намеков.

И еще. (С) Что ты такого усмотрел в сообщении puporev'а, что побудило тебя так резко на них отреагировать? или ты реагировал не на них?..

Добавлено через 12 мин.
И еще "И еще".
Кто сказал, что в "своих" темах можно флудить? Это что, в Правилах Форума написано? Если для кого-то это словосочетание еще не потеряло всякий смысл (С). Никто не является собственником тем - по крайней мере, когда в них уже отвечено.

Автор: Altair 13.01.2009 1:51

Цитата
volvo, будь добр, выражайся конкретно и без недомолвок и намеков.

+1 я ничего не удалял если что!

Автор: MaZaHaKa 11.12.2009 13:02

А у меня она почему-то не работает.

Автор: volvo 11.12.2009 16:38

"Почему-то не работает" - это не диагностика ошибки. Программа рабочая, проверено неоднократно. Кстати, в ближайшее время будет выложена очередная версия (ага, Новый Год все ближе и ближе yes2.gif )

Автор: MaZaHaKa 11.12.2009 20:53

А когда примерно выложешь???

Автор: volvo 11.12.2009 21:15

Может завтра, может на следующей неделе.

Автор: Error 205 12.12.2009 0:56

good.gif спасибо

Автор: MaZaHaKa 12.12.2009 9:24

дак ты её уже сделал???

Автор: volvo 15.12.2009 1:22

Сделал, сделал... Только новая версия в корне отличается от первоначальной... Если у кого слабое сердце или нервы - то исходники не стОит смотреть ни в коем случае... smile.gif

Несколько слов о программе: компилироваться код будет только под FPC, начиная с версии 2.2.0, поскольку я решил использовать Free Pascal по-полной, и задействовал Дженерики. Угу, вот так вот, хотелось проверить, что можно сделать с их помощью... Еще одно уточнение - приложение работоспособно только под Windows (я даже не стал вычищать код, там до сих пор есть "наследие" Турбо-Паскаля), возможно, в следующих версиях это изменится. Есть еще идеи, можно много добавить в эту программу, но времени сейчас не хватает.

Присоединяю 2 архива: один - с EXE-шником и DLL-кой, необходимой для его работы, второй - с исходниками. Не удивляйтесь размеру исходников, вы все поймете, как только скомпилируете и запустите программу smile.gif Нужный режим компиляции прописан в каждом файле, поэтому в настройки компилятора лазить не надо. Играться без особой надобности с условной компиляцией - тоже не надо, файлы, которые я выложил - только для тех директив, которые установлены сейчас, для других - надо еще другие файлы, но присоединять все, что есть (чтобы работало со всеми комбинациями) - сомневаюсь, что кто-то будет это качать, полный размер всей папки у меня - больше 30 Мб. smile.gif Да, еще одно. Папка, из которой программа запускается, должна иметь разрешение на запись, иначе запуска не произойдет (это к тем, кто сидит НЕ под Админом)

Вот сами архивы:



Прикрепленные файлы
Прикрепленный файл  exe_file.zip ( 480.08 килобайт ) Кол-во скачиваний: 593
Прикрепленный файл  sources.zip ( 535.34 килобайт ) Кол-во скачиваний: 577

Автор: Lapp 15.12.2009 1:50

Спасибо, volvo! Крастотища smile.gif

Цитата(volvo @ 14.12.2009 21:22) *
Папка, из которой программа запускается, должна иметь разрешение на запись, иначе запуска не произойдет
(из сопроводиловки к вирусу.. lol.gif )


Добавлено через 2 мин.
О! у меня уже сугроб по колено нападал.. smile.gif

Автор: Unconnected 15.12.2009 2:30

Куууул!!! Очень красиво good.gif.

Музыка, знакомая с детства...smile.gif

Автор: SKVOZNJAK 15.12.2009 2:46

Под вайном тоже работает. А был ли смысл запихивать mp3 в exe если без распаковки проиграть его нельзя? Может проще обозвать его elka.doc
Креатино, но белая каёмочка вокруг лампочек вроде как лишняя.

Автор: Unconnected 15.12.2009 2:55

Цитата
А был ли смысл запихивать mp3 в exe если без распаковки проиграть его нельзя?


Мм в каком плане нельзя проиграть без распаковки? Я запускал прямо из архива, без распаковки, всё играло и снег падал хорошо:)

Автор: volvo 15.12.2009 2:57

Это его под BASS-ом нельзя проиграть, не распаковывая. Виндовый PlaySound вполне справляется с проигрыванием WAV-а прямо из памяти. Но блин, тогда жутко возрастает размер исходников. Сколько-нибудь значительный фрагмент музыки становится массивом огромных размеров... Попробую еще посмотреть OpenAL, может там есть средства "сыграть прямо из памяти". А каемочку убрать действительно надо будет... Сделаем smile.gif

Добавлено через 1 мин.

Цитата
Я запускал прямо из архива, без распаковки, всё играло и снег падал хорошо:)
rolleyes.gif Ну-ну smile.gif А посмотреть (во время работы программы), что еще лежит в папке - не догадался? Создаем, играем, при выходе чистим за собой, все как положено...

Автор: Unconnected 15.12.2009 3:12

Цитата
rolleyes.gif Ну-ну smile.gif А посмотреть (во время работы программы), что еще лежит в папке - не догадался? Создаем, играем, при выходе чистим за собой, все как положено...


Запускаю программу из архива, не распаковывая, начинает играть и падать, смотрю в архив - никаких временных файлов, всё как и было - программа и библиотека, в папке с архивом тоже ничего нового:)

Автор: volvo 15.12.2009 3:50

Unconnected, ты до сих пор думаешь, что оно запускается ПРЯМО из архива (не создавая временную папку, и не распаковываясь туда)? smile.gif Вот найди ту временную папку, и посмотри, что там творится...

Автор: Unconnected 15.12.2009 3:56

Не, я знаю, что временная создаётся, кажется, в папке Temp... Просто

Цитата
А посмотреть (во время работы программы), что еще лежит в папке - не догадался?


намекало на папку с архивом)

Автор: SKVOZNJAK 15.12.2009 5:12

Цитата
при выходе чистим за собой, все как положено...

Под вайном ничего не чистится и окон создаётся два штуки. Одно с графикой и консоль. После закрытия графического окна консоль продолжает наигрывать музыку, а сугроб растёт прямо на десктопе и открытых окнах. Весело smile.gif

Автор: volvo 15.12.2009 5:45

Цитата
Под вайном ничего не чистится и окон создаётся два штуки. Одно с графикой и консоль. После закрытия графического окна консоль продолжает наигрывать музыку, а сугроб растёт прямо на десктопе и открытых окнах
lol.gif ... Вот так лучше будет:

Прикрепленный файл  exe_031.zip ( 478.43 килобайт ) Кол-во скачиваний: 733


Во-первых, не создается консольное окно, а во-вторых, я убрал каемочку... Но мне с ней нравится больше, если честно...

Автор: SKVOZNJAK 15.12.2009 8:29

Насчёт каёмочки. Включённой лампе её действительно не хватает.
Сугробы на десктопе расти перестали, но процесс выключения стал сложнее, эскейп не сразу нашёл smile.gif После закрытия графического окна музыка продолжает играть, а если вырубить процесс wineserver музыка застревает на одной ноте. Отключение main_031.exe спасает. А в этом окошке нельзя как sdl-овском при нажатии на кнопку отключения выполнять свои дополнительные действия, как при нажатии на эскейп?

Автор: andriano 15.12.2009 15:15

Цитата(volvo @ 14.12.2009 21:22) *
Сделал, сделал...
Очень симпатичные новогодние папоротники.
Цитата
Есть еще идеи, можно много добавить в эту программу, но времени сейчас не хватает.
Можно один из фракталов зеркально развернуть относительно вертикальной оси. Думаю, много времени это не займет.
Можно, наоборот, сымитировать ветер. Тогда все фракталы останутся развернутыми в одну сторону, но в том же направлении надо добавить некоторую горизонтальную составляющую всем снежинкам. Думаю, тоже много времени не понадобиться.
Когда шарики-фонарики перекрывают друг друга, получается не совсем красивый эффект, т.к. последний зажегшийся "вылезает" на первый план. Лучше либо предусмотреть экранирование, либо исключить пересечение.
Физика движущихся по экрану точек очень здорово не соответствует физике снежинок, но, возможно, и ничего страшного, т.к. чтобы заметить это нужно специально приглядываться, а "издалека" снег выглядит вполне натурально.
Периодически наблюдаются "подтормаживания". Вероятно, каждый кадр считается с фиксированным приращением времени. Т.е. внутреннее время программы связано с номером кадра, а не с физическим временем.
Через некоторое время снегопад остановился. А вместе с ним остановились и невыпавшие снежинки. Могу предположить, что снежинки, достигая сугроба, не исключаются из списка снежинок, а продолжают в нем фигурировать, из-за чего естественное ограничение на их максимальное количество приводит к невозможности продолжать счет.
Нет, ошибся. Пока писал предыдущий абзац, снегопад восстановился. Но была явная пауза минимум в несколько секунд, не прерывающаяся даже по перемещению окна и изменению фокуса.
Снова остановился...
Загадка.
Хотя картинка и не движется, приложение исправно жрет свои 50% времени.
Снег снова пошел и расход CPU снизился до 2-11%.
Снова остановился.

Автор: MaZaHaKa 15.12.2009 15:54

Вау!!!СУПЕР!!! Слов нет... good.gif

Автор: Ivan 20.11.2012 5:26

Felt so hopeless looikng for answers to my questions...until now.