Помощь - Поиск - Пользователи - Календарь
Полная версия: Анимация в Паскале
Форум «Всё о Паскале» > Pascal, Object Pascal > Написание игр
LHx
Я хочу сделать в игрухе постоянно (часто) обновляемый экран. Для этого меняю страницы. Изображение мелькает, раздваивается, а местами вообще исчезает. Как быть? (мне бы с игрухой до осени управиться, а то в башке засела - не вышибешь. Как заноза. ПОМОГИТЕ.)
NetAnton
для анимации используют спрайты. подробнее о них поищи в Сети, а то я не особый спец в этом. возможно, кое где придется писать асмовые вставки и оптимизировать код.
GLuk
Выложи код, поглядим...
trminator
Экран моргает. 60 раз в секунду (стандартно для граф. режимов ДОС, AFAIK) изображения на экране нет. Нужно менять страницы как раз в этот момент.

Код

procedure WaitVerticalRetrace;
begin
 while(port[$3da] and 8) = 0 do;
end;


Приблизительный метод использования:
Код

   чего-то рисуем на невидимой странице;
   WaitVerticalRetrace;
   Делаем активную страницу видимой


Поищи на osp.ru/pcworld статью "Основы спрайтовой анимации", если желаешь узнать про спрайты. Была в разделе "Компьютер дома" давненько, найти сейчас довольно сложно.
Altair
Можно использовать переключение видеостраниц.
Тогда вывод на экран будет мгновенным, и мелькание СОВСЕМ не будет заметно.

Алгоритм такой:
Код

i:=1;
1:
setActivePage(i);
{рисуем что надо...}
setvisualPage(1);
If i=1 then i:=0 else i:=1;
goto1;

Только использовать GOTO не нужно smile.gif Это я так просто. (не подумайте, что я его использую, да ни когда! ;) )
Только не все режимы поддерживают видеостраницы
GLuk
Цитата(Oleg_Z @ 4.07.04 10:16)
Можно использовать переключение видеостраниц.
Тогда вывод на экран будет мгновенным, и мелькание СОВСЕМ не будет заметно.

Алгоритм такой:
Код

i:=1;
1:
setActivePage(i);
{рисуем что надо...}
setvisualPage(1);
If i=1 then i:=0 else i:=1;
goto1;

Только использовать GOTO не нужно smile.gif Это я так просто. (не подумайте, что я его использую, да ни когда! ;) )
Только не все режимы поддерживают видеостраницы

Судя по сабжу он и так юзает переключение страниц, см. пост №1
Altair
Ага, все ясно, точно, он использует переключение видеостраниц, только использует драйвер, не поддерживающий видеостраницы, только так можно объяснить дерганье!
LHx
Мне больше нравится путь самурая oleg_7 smile.gif. Какой драйвер поддерживает такую смену страниц? :p2:
Altair
Прошу не путать, я не самурай, а извращенец! smile.gif
И еще я не Oleg 7 а Oleg_Z (Олег Зет! ) :P :P :D

Многостраничный вывод возможен только на EGA (256Кб), (S)VGA и Hercules.
LHx
А vga-никак нельзя?? Ну вы в натуре извращенец, мистер Ааз. lol.gif
BlackShadow
Ну почему нельзя?
Oleg_Z, ты же не думаешь, что максимальное кол-во видео страниц 8 - в текстовом 40x25???
Можно быть проще и, если чего-то не дают, то взять самому. Память у тебя оперативная установлена? Вот ей и воспользуйся. Если навернуть пару 32-битных команд, то копирование произвольного куска оперативки в видеобуфер производится в пару строчек и на приемлемой скорости, а, если не полениться и дождяться обратного хода луча (описано выше), то и не заметно будет...
LHx
Вообще-то, я уже попробовал ega - заработало. :D Тем не менее, из вышеперечисленного нифига не понял и прошу объяснений.
BlackShadow
Объясняю.
Есть несколько очаровательнвх режимов, которые хранят изображение в видео буфере легко и просто - под пиксель по n бит. Есть режимы с "извратом" - там память "слоиться" и приносит кучу гемороя. Под "удобные" режимы можно организовать много-много видеостраниц следующим образом:
1). Выделяешь достаточный кусок памяти и говоришь (себе), что он теперь видеостраница.
2). Рисуешь чего-то прямо в нём, а не на экране.
3). Ждёшь обратного хода луча.
4). Процедуркой типа
MOV ECX,BUF_SIZE SHL 2
MOV ESI,OFFSET MyNewPage
MOV EDI,000A0000h
CLD
REP MOVSD

или же под 16 бит:
MOV CX,BUF_SIZE SHL 1
MOV AX,SEG MyNewPage
MOV DS,AX
MOV SI,OFFSEST MyNewPage
MOV AX,0A000h
MOV ES,AX
XOR DI,DI
CLD
REP MOVSW

, но тут надо проверить, чтобы размер буфера был менее 128K.
Вот таким вот макаром и подставляешь свою "страничку" на место оригинальной.

Плюс: ты всегда работаешь с одними и теми же адресами.
Минус: аппаратное перекидывание страниц всё-таки пошустрее (хотя это и не заметно).
Резюме: при грамотном подходе у любого режима есть "BackBuffer".

З. Ы. : спасибо Oleg_Z за то, что подсказал, как оформить концовку поста smile.gif
LHx
Я бы с большой радостью все понял, но я исключительно бегинер и в ассемблере не шарю. sad.gif
Altair
LHx, сосредоточся на цели - ускорить вывод на экран. (постоянно меняющийся экран).
Какое тебе нужно видео (разрешение и цветность) ?
Все от этого зависит, если ты пойдешь на некоторый компромисс между графикой в игре и простотой программирования, то нужно использовать именно страницы!
SKVOZNJAK
Или же выбрать компилятор помощнее и наплевать на всякие там страницы, а просто вовремя вставлять паузы smile.gif
trminator
Вот цикл статей на osp.ru/pcworld

http://www.osp.ru/search?text=%2B%F1%EF%F0...ED%EE%E2&sub=9p

Фактически там хорошо расписано, как сделать свой двумерный "движок". Листинги программ прилагаются.
warner
Цитата(trminator @ 3.07.04 11:30)
Код

procedure WaitVerticalRetrace;
begin
 while(port[$3da] and 8) = 0 do;
end;


Приблизительный метод использования:
Код

   чего-то рисуем на невидимой странице;
   WaitVerticalRetrace;
   Делаем активную страницу видимой




А есть во FreePascal что-то похожее?? потому что слово port не знает.
arhimag
А помогите пожалуйста улучшить это ( мигает, а это не приятно!)
Код
program DRAW_BLAD;
uses crt, graph;
const
left  = #75;
right = #77;
up    = #72;
down = #80;

var x, y, Driver, mode: integer;
c: char;
ekran:word;

procedure drawhead(x,y: integer);
var i:integer;
begin
     setfillStyle (solidfill, yellow);
     Pieslice(x,y,0,360,4);
     setcolor(blue);
     line(x-7, y-1, x+6, y-4);
     line(x-7, y-2, x+6, y-4);
     setcolor(black);
     line(x-4, y-3, x+3, y-4);
     setcolor(lightblue);
     for i:= 1 to 3 do
         line(x-4, y-3-i, x+3, y-5-i);
     setcolor(lightblue);
     setfillstyle(solidfill, lightblue);
     pieslice(x+1,y-1,0, 360, 1);
end;

procedure drawbody(x,y: integer);
var i: integer;
begin
     x:=x;
     y:=y+7;
     setfillstyle (solidfill, lightblue);
     bar( x-2, y, x+3, y+15 );
     setcolor(red);
     line(x-4, y-3, x+3, y);
     line(x-4, y-2, x+3, y);
     line(x-4, y-1, x+3, y);
     setcolor(white);
     line(x-4, y-4, x+2, y-1);
     setfillstyle ( 1 , lightblue);
     pieslice( x-1, y+2, 0, 360, 2);
     for i:= 0 to 4 do  begin
         if (i=0) or (i=4) then
         setcolor(white)
         else
         setcolor(lightblue);
         line(x-1, y+i, x+4, y+14+i);
     end;
     setcolor(yellow);
     setfillstyle( 1, yellow);
     pieslice( x+4, y+16, 0, 360, 2);
end;

procedure drawlegs(x,y:integer);
begin
     x:=x;
     y:=y+7+15;
     setcolor(red);
     setfillstyle(1,red);
     bar(x-2, y, x+3, y+2);
     setcolor(blue);
     setfillstyle(1, lightblue);
     bar(x-2,y+2,x+3, y+12);
     setcolor(yellow);
     setfillstyle( 1, yellow);
     bar(x-1,y+12,x+1, y+14);
     setcolor(black);
     setfillstyle(1, black);
     bar(x-1,y+14,x+2, y+17);
     bar(x-2,y+15,x+5, y+18);
     pieslice( x+5, y+16, 0 , 360, 2);
end;
procedure  drawblad (x,y:integer);
begin
       drawhead(x,y);
       drawbody(x,y);
       drawlegs(x,y);
end;

Begin
     ekran:=0;
     x:=100;
     y:=200;
     driver:=9;
     Mode:=1;
     initgraph( driver, mode , '');
     setactivepage(ekran);
     setvisualpage(ekran);
     setfillstyle(1, green);
     bar(0,0, getmaxx, getmaxy);
     drawblad(x,y);
     repeat
           ekran:= ekran+1;
           ekran:= ekran mod 2;
           c:=readkey;
           setactivepage(ekran);
           case c of
                #0:
                case readkey of
                     left : begin
                          dec(x);
                          clrscr;
                          setfillstyle(1,green);
                          bar(0,0,getmaxx, getmaxy);
                          drawblad(x,y);
                          end;
                     right: begin
                            inc(x);
                            clrscr;
                            setfillstyle(1,green);
                            bar(0,0,getmaxx, getmaxy);
                            drawblad(x,y);
                            end;
                     up   : begin
                          dec(y);
                          clrscr;
                          setfillstyle(1,green);
                          bar(0,0,getmaxx, getmaxy);
                          drawblad(x,y);
                          end;
                     down : begin
                          inc(y);
                          clrscr;
                          setfillstyle(1,green);
                          bar(0,0,getmaxx, getmaxy);
                          drawblad(x,y);
                          end;
                end;
           end;
           setvisualpage(ekran);
     until x=200;
     readln;

end.
volvo
Ну, на данном этапе видеостраницы тебе только мешают... Переделай основной блок вот так, и мигание сильно уменьшится:
Begin
x:=100;
y:=200;
driver:=9;
Mode:=1;
initgraph( driver, mode , '');
setfillstyle(1, green);
bar(0,0, getmaxx, getmaxy);
drawblad(x,y);
repeat
c := readkey;
case c of
#0:
case readkey of
left : dec(x);
right: inc(x);
up : dec(y);
down : inc(y);
end;
end;

setfillstyle(1,green);
bar(x-10, y-10, x+20, y+50);
drawblad(x,y);

until x=200;
readln;

end.
arhimag
А можно ли от него совсем избавиться???
Gothic_Snake
В таком случае тебе лучше будет перевести свою программу на TMT паскаль. Он и разрешения лучшие имеет, цветов поболее, и прога твоя запустится (можеть подправить придется чуть-чуть)
arhimag
А если её перевести в фпс то ничего не измениться??
GoodWind
можно и в FPC, как больше нравится
Gothic_Snake
Цитата(arhimag @ 24.12.2005 3:12) *

А если её перевести в фпс то ничего не измениться??

Ну тот и тот в принципе 32 разрядные... Но, как я знаю (а я могу ошибаться), в TMT, в отличии FPC, мошьная графическая библиотека, работающая со стандартами VESA и VESA2, а это высокое разрешение, TrueColor и доступные страницы памяти smile.gif без никаких дополнительных действий с твоей стороны =)
ey
Народ, вопрос по теме.
Использовал раньше графический режим VGA 640 на 480...
После чего узнал о визуальных страницах, в программе, где я увидел работу визуальных страниц, использовался режим EGA 640 на 350...(( когда я перевёл на VGA 640 на 480, экран начал дергаться. Пришлесь работать в EGA 640 на 350 (пиксели длинее в высоту чем в длину). Ну ничего, изхитрялся работать и так, НО сейчас мне нужно именно 640 на 480 и чтобы работали видеостраницы... Никто по этому поводу не может высказаться и выложить код?))

заранее спасибо
volvo
Цитата
НО сейчас мне нужно именно 640 на 480 и чтобы работали видеостраницы
В режиме Graph 640*480 всего одна видеостраница, нулевая (больше не будет, потому что эта страница занимает 640*480/8 = 38400 байт в памяти видеоадаптера, что больше половины 64-килобайтного сегмента)... Так что переключать-то, собственно, нечего. Поэтому-то и использовался в том коде режим 640*350 (там уже 2 видеостраницы. Можешь использовать 640*200, там их вообще 4).
Гость
Как в ФПС переключать видео страницы?
spectrum
люди помогите плз. обясните чайнику как открыть файл из сообщения, если он в паскале длжен быть(прога есь)?
Lapp
Цитата(spectrum @ 10.10.2008 15:38) *
люди помогите плз. обясните чайнику как открыть файл из сообщения, если он в паскале длжен быть(прога есь)?
spectrum, просмотри, пожалуйста, Правила Форума.
М
Не задавай левые вопросы в чужих темах

. Делай свои темы, если нужно.
Закрыто.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.