Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.11.2012, 01:16   #1
tdAvenger
 
Регистрация: 07.11.2012
Сообщений: 5
По умолчанию Мультфильм на Turbo Pascal. Требуется альтернатива cleardevice. Как очистить только последний вставленный кадр?

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

Код:
uses graph,crt;
var Gd,Gm :Integer;
    x,y,step, k:integer;
begin
Gd:= detect;
InitGraph(Gd,Gm,'');
setbkcolor(lightgray);
x:=30; 
y:=200; 
step:=10; 

{дорога}
SetFillStyle(1,white);
bar(0,y+85,getmaxx,y+88);


repeat


{1 кадр}
setcolor(red);
setlinestyle(0,0,1);
setfillstyle(1,red);
fillellipse(x,y,13,40); {тело}
circle( x,y-60,20); {голова}
setlinestyle(0,0,3);
line(x-5,y+37,x-25,y+80); {левая нога}
line(x-25,y+80,x-15,y+85); {левая тапка*}
line(x+5,y+37,x+25,y+85); {правая нога}
line(x+25,y+85,x+35,y+85);  {правая тапка*}
Setcolor(blue);
setlinestyle(0,0,3);
line(x-3,y-20,x-20,y+5); {рука 1}
line(x-20,y+5,x-3,y+20); {рука 2}
setlinestyle(0,0,1);
arc(x-22,y+20,340,20,20); {карман}
setfillstyle(1,brown);
setcolor(brown);
pieslice(x,y-60,210,20,20); {волосы}
setcolor(darkgray);
setfillstyle(1,white);
pieslice( x+13,y-60, 0,360,2);
putpixel(x+13,y-59, darkgray);
putpixel(x+14,y-59, darkgray);
putpixel(x+14,y-60, darkgray);
line(x+16,y-50,x+8,y-50);
delay(100);
x:=x+step;
cleardevice;
{дорога}
SetFillStyle(1,white);
bar(0,y+85,getmaxx,y+88);
{2 кадр}
setcolor(red);
setlinestyle(0,0,1);
setfillstyle(1,red);
fillellipse(x,y,13,40); {тело}
circle( x,y-60,20); {голова}
setlinestyle(0,0,3);
line(x,y+37,x,y+85); {левая нога}
line(x,y+85,x+10,y+85); {левая тапка}
Setcolor(blue);
setlinestyle(0,0,3);
line(x-3,y-20,x-20,y+5); {рука 1}
line(x-20,y+5,x-3,y+20); {рука 2}
setlinestyle(0,0,1);
arc(x-22,y+20,340,20,20); {карман}
setfillstyle(1,brown);
setcolor(brown);
pieslice(x,y-60,210,20,20); {волосы}
setcolor(darkgray);
setfillstyle(1,white);
pieslice( x+13,y-60, 0,360,2);
putpixel(x+13,y-59, darkgray);
putpixel(x+14,y-59, darkgray);
putpixel(x+14,y-60, darkgray);
line(x+16,y-50,x+8,y-50);
delay(200);
x:=x+step;

if x=310 then
   begin
   {дорога}
SetFillStyle(1,white);
bar(0,y+85,getmaxx,y+88);
   {procedure svetofor}
    delay(3000);
	
	x:=x+step;	 
      end;
 
cleardevice;
{дорога}
SetFillStyle(1,white);
bar(0,y+85,getmaxx,y+88);
until keypressed;
Closegraph;
end.

Заранее благодарю за любые идеи по реализации.
tdAvenger вне форума Ответить с цитированием
Старый 07.11.2012, 01:38   #2
koljsch
Форумчанин
 
Регистрация: 26.01.2009
Сообщений: 360
По умолчанию

Мне кажется, что для этого достаточно запомнить ту часть которую нужно удалить, закрасить ее цветом фона и заново нарисовать уже в другом месте
koljsch вне форума Ответить с цитированием
Старый 07.11.2012, 01:54   #3
tdAvenger
 
Регистрация: 07.11.2012
Сообщений: 5
По умолчанию

вот как раз таки меня и интересует как это можно организовать.
tdAvenger вне форума Ответить с цитированием
Старый 07.11.2012, 02:13   #4
koljsch
Форумчанин
 
Регистрация: 26.01.2009
Сообщений: 360
По умолчанию

Допустим у нас нарисован квадрат по координатам 100, 100, и доходит до координат 200, 200. Цвет фона голубой. Нужно этот квадрат куда-то переместить.
Зарисовываем все голубым цветом по координатам квадрата, т.е. от 100, 100 и до 200 200 и заново рисуем его)
koljsch вне форума Ответить с цитированием
Старый 07.11.2012, 02:29   #5
tdAvenger
 
Регистрация: 07.11.2012
Сообщений: 5
По умолчанию

идея неплохая, но, к сожалению, не подойдет в данной ситуации. Если на заднем плане будут какие-то другие объекты(тот же дом, к примеру), а они будут, закрасить цветом фона уже не получится, т.к. это будет сильно бросаться в глаза. А если учесть, что человек движется с шагом в 10 пикселей, то половина дома окрасится в цвет фона)
tdAvenger вне форума Ответить с цитированием
Старый 07.11.2012, 02:32   #6
koljsch
Форумчанин
 
Регистрация: 26.01.2009
Сообщений: 360
По умолчанию

Хм, верно. Но можно тогда попробовать статические объекты рисовать функциями. Как только что-то изменили и рядом находился какой-нибудь статический объект, то по вызову функции нарисовать его заново
koljsch вне форума Ответить с цитированием
Старый 07.11.2012, 02:47   #7
tdAvenger
 
Регистрация: 07.11.2012
Сообщений: 5
По умолчанию

Завтра на работе попробую. Была идея попробовать прописать каждый кадр, как отдельную процедуру, что значительно уменьшило бы исходный код. Но насколько я понял, в любом случае придется перерисовывать статический объект после каждого cleardevice'а. Подумал, может кто предложит более изощренный вариант). Еще была мысль по поводу cleardevice'a... по логике вещей он закрашивает экран в цвет фона, а можно ли как-нибудь задать(сохранить) все нарисованные статические объекты как фон и заставить паскаль каждый раз при очистке экрана рисовать не стандартный одноцветный фон, а уже сохраненный нами изначально фон со всеми статическими элементами? Надеюсь, суть вопроса правильно изложил))
tdAvenger вне форума Ответить с цитированием
Старый 07.11.2012, 02:51   #8
koljsch
Форумчанин
 
Регистрация: 26.01.2009
Сообщений: 360
По умолчанию

Мне кажется, что самый оптимальный вариант это через процедуры.
Допустим имеем дом и дерево-прописываем это все процедуру. Далее делаем еще одну процедуру для рисования всего этого, но в параметры передаем какую область мы изменяем и если какой-либо объект входит в эту область(дом или дерево), то соответственно рисуем только один объект, т.е. если мы закрасили дом, то только дом и рисуем через вызов процедуры
koljsch вне форума Ответить с цитированием
Старый 07.11.2012, 06:39   #9
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

Не знаю, как в паскале сделать подобное, но везде это делается по такому примерно принципу:
Создаётся буфер статичной части кадра, и буфер готового кадра. Когда надо нарисовать анимированный объект, берётся буфер статики и рисуется на буфер кадра, потом рисуется анимация. Когда анимация меняется, из статики вырезается "подложка" - кусочек буфера по размеру и координатам соответствующий анимации и рисуется либо на буфер кадра (если изображение не надо перерисовать полностью) либо сперва буфер статики рисуем в буфер кадра а потом и подложку, после уже анимация рисуется в новых координатах.
В конце любого рисования на экран выводится только буфер кадра - этим же достигается и принцип двойной буферизации (устранение мерцания экрана за счёт буфера кадра, а не последовательной отрисовки кучи элементов сразу на экран).
Поглядеть работу принципа в дельфи (в принципе, можно даже как-то на паскаль прикинуть как перевести) - http://programmersforum.ru/showpost....&postcount=522
phomm вне форума Ответить с цитированием
Старый 07.11.2012, 09:37   #10
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

во-первых, в TurboPascale был такой способ работы с графикой - взять область в графическом режиме ( GetImage(...) ) и вывести область в графическом режиме ( PutImage(...) ). маленький пример могу дать, если что...

во-вторых, похоже, что то, что Вы пытаетесь организовать, называется "спрайтовая" анимация. для TurboPascal можно почитать/посмотреть исходники:
Основы спрайтовой анимации

TurboPascal Developer Network - Статьи раздела «Графика и анимация»

pascal.sources.ru - Графика

в-третьих, (и самое главное), зачем Вам этот антиквариат?! MS DOS давно уже мёртв, DOS режим поддерживается всё хуже и хуже, зачем Вам этот "головняк"?!
Учебное задание? Или Вы сделали неправильный выбор в направлении программирования?



посмотрел на DOS игрушки с исходниками на TurboPascal: "Lode Runner Live version 1.0", "Arkanoid 1.02 - Classic Game in Mode $13", "Загадки зАмка - Игра в стиле Sokoban" (там много чего есть, это то, что я посмотрел...). Впечатляет!

Последний раз редактировалось Serge_Bliznykov; 07.11.2012 в 10:00.
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Turbo Pascal. Как исправить ошибку №14? Lyubov' Помощь студентам 4 09.06.2011 16:30
как привязать вставленный объект к определенной ячейке без его подальшего по листу Excel 2003? Rybit Microsoft Office Excel 0 02.04.2011 14:09
Требуется программа на Turbo Pascal (за деньги) illspirit Фриланс 5 30.12.2007 23:12
Как использовать WinAPI в Turbo Pascal? Alar Паскаль, Turbo Pascal, PascalABC.NET 1 16.01.2007 23:48