• Добро пожаловать на компьютерный форум Tehnari.ru. Здесь разбираемся с проблемами ПК и ноутбуков: Windows, драйверы, «железо», сборка и апгрейд, софт и безопасность. Форум работает много лет, сейчас он переехал на новый движок, но старые темы и аккаунты мы постарались сохранить максимально аккуратно.

    Форум не связан с магазинами и сервисами – мы ничего не продаём и не даём «рекламу под видом совета». Отвечают обычные участники и модераторы, которые следят за порядком и качеством подсказок.

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

    Не знаете, с чего начать? Создайте тему с описанием проблемы – подскажем и при необходимости перенесём её в подходящий раздел.
    Задать вопрос Новые сообщения Как правильно спросить
    Если пришли по ссылке со старого Tehnari.ru – вы на нужном месте, просто продолжайте обсуждение.

Pascal графика тип движения

  • Автор темы Автор темы Dram
  • Дата начала Дата начала

Dram

Экономичный вид памяти
Почётный участник
Регистрация
19 Фев 2008
Сообщения
2,632
Реакции
34
Баллы
0
Pascal графика тип движения

Подскажите как в паскале реализуется движение обьектов? Нужно сделать Движение в случайном направлении. Смена направления движения производится через случайное количество тактов. Предусмотреть отражение от границ экрана.
Через что его можно выразить?

Вот собственно моя работа только здесь скопипастенное движение по диагонали.
Код:
Uses Crt,Graph;
Const FigureHight=55;
      FigureWidth=35;
      FigureColor=red;
      FigureBackground=blue;
      MenuText:array[1..3]of string = ('Svobodni','Upravlenie','Exit');
var select,i,gd,gm:integer;
    konez:boolean;
    ch:char;
procedure Gagarin(x,y,color,background:integer);
begin
 setcolor(color);
      line(x, y, x+40, y+25);
      line(x, y, x+20, y+25);
      line(x+20, y+25, x+100, y+25);
      line(x+20, y+55, x+100, y+55);
      line(x+20, y+25, x+20, y+55);
      line(x+100, y+55, x+130, y+40);
      line(x+100, y+25, x+130, y+40);
      line(x+20, y+55, x, y+80);
      line(x, y+80, x+40, y+55);
      circle(x+90, y+40, 10);
      circle(x+70, y+40, 10);
      circle(x+50, y+40, 10);
end;
procedure Upravlenie;
var x,y,ckorost:integer;
begin
 x:=getmaxx div 2;
 y:=getmaxy div 2;
 ckorost:=1;
 repeat
  Gagarin(x,y,FigureColor,FigureBackground);
  ch:=readkey;
  Gagarin(x,y,black,black);
  case ch of
   #72:if (y-ckorost)>10   then dec(y,ckorost);
   #80:if (y+ckorost+FigureWidth)<480 then inc(y,ckorost);
   #75:if (x-ckorost)>10   then dec(x,ckorost);
   #77:if (x+ckorost+FigureHight)<640 then inc(x,ckorost);
   '+':if ckorost<60 then inc(ckorost);
   '-':if ckorost>0  then dec(ckorost);
  end;
 until (ch=#27)or(ch=#13);
end;
procedure Svobodnoe;
const maxx=640-FigureWidth; minx=5;
      maxy=480-FigureHight; miny=5;
var x1,y1:integer;
    x,y,vx,vy:real;
begin
 x:=minx; y:=miny; x1:=minx; y1:=miny;
 repeat
  Gagarin(trunc(x),trunc(y),black,black);
  if(trunc(x)<=minx)and(trunc(y)<=miny)then begin x1:=maxx; y1:=miny; vx:=trunc((x1-x)/100); vy:=trunc((y1-y)/100); end;
  if(trunc(x)>=maxx)and(trunc(y)<=miny)then begin x1:=minx; y1:=maxy; vx:=trunc((x1-x)/100); vy:=trunc((y1-y)/100); end;
  if(trunc(x)<=minx)and(trunc(y)>=maxy)then begin x1:=maxx; y1:=maxy; vx:=trunc((x1-x)/100); vy:=trunc((y1-y)/100); end;
  if(trunc(x)>=maxx)and(trunc(y)>=maxy)then begin x1:=minx; y1:=miny; vx:=trunc((x1-x)/100); vy:=trunc((y1-y)/100); end;
  x:=x+vx; y:=y+vy;
  Gagarin(trunc(x),trunc(y),FigureColor, FigureBackground);
  delay(2000);
 until keypressed; readkey;
end;
Begin
 gd:=detect;
 initgraph(gd,gm,'');
 randomize;
 konez:=false;
 repeat
  cleardevice; select:=1;
  repeat
   for i:=1 to 3 do begin
    if i=select then setcolor(Red) else setcolor(green);
    outtextxy((getmaxx div 2)-50,(getmaxy div 2)-50+i*16,MenuText[i]);
   end;
   ch:=readkey;
   case ch of
    #72:dec(select);
    #80:inc(select);
   end;
   if select<1 then select:=3;
   if select>3 then select:=1;
   if ch=#27 then begin
    select:=3;
    ch:=#13;
   end;
  until (ch=#13);
  cleardevice;
  case select of
   1:Svobodnoe;
   2:Upravlenie;
   3:konez:=true;
  end;
 until konez;
 closegraph;
End.
 
Последнее редактирование:
Движение можно реализовать несколькими способами. Но основной принцип: затирание на старом месте и рисование на новом - неизменно лежит в основе движения. Pascal предоставляет следующие возможности:
а) рисование с помощью примитивов - медленно и неэффективно, но доступно любому начинающему;
б) метод PutImage и работа с памятью и графическими матрицами - быстрее но требует четкого определения размера объекта;
в) формирование изображения на странице видеопамяти и переключение между страницами - используется в игровых приложениях и сейчас.

Так, к примеру, можно задать цикл движения до тех пор, пока не будет нажата клавиша. В цикле в переменную считывать случайное значение направления движения, которое будет служить условием для вложенного цикла перемещения объекта на случайные dx и dy. По достижении границ экрана внутренний цикл прерывается и управление передается внешнему циклу, в котором опять генерируется значение для направления.

Пример использования метода PutImage. Реализовано движение только по горизонтали.
uses crt, graph;{подключение внешних модулей}
var y,x,gdriver,fonttype,gmode: integer;{определение типов переменных}
R: Pointer;{переменная для работы с памятью}
P: Pointer;
Size: Word;{положительные целочисленные переменные}
begin
gdriver:=detect;
initgraph(gdriver,gmode,'');
setfillstyle(1,9);
bar(0,0,640,480);
{----------------------------Рисуем левого таракана--------------------------------}
setfillstyle(1,11);
setcolor(0); sector(30,15,0,360,10,5); {тело}
line(35,12,35,18); line(35,15,20,15);
setcolor(8); line(40,14,47,11); Line(40,16,47,19); {усы}
{----------------------------Рисуем правого таракана--------------------------------}
setfillstyle(1,13);
setcolor(0); sector(580,15,0,360,10,5); {тело}
line(575,12,575,18); line(575,15,590,15);
setcolor(8); line(570,14,563,11); Line(570,16,563,19); {усы}

Size := ImageSize(15, 5, 65, 35); {переменная для резервирования памяти под рисунок с заданным размером}
GetMem(P,Size); {резервируем память под правого таракана}
GetMem(R,Size); {резервируем память под левого таракана}
GetImage(562,9,592,25,P^); {копируем правого таракана в память}
GetImage (19, 9,50, 25,R^);{копируем левого таракана в память}

setfillstyle(1,9); bar(0,0,640,480);{очищаем экран}
for x:=0 to 598 do {Цикл движения}
for y:=0 to 15 do {Цикл формирования вертикального ряда}
begin
PutImage (x-1,y*31+14, R^,3); {стираем старое}
PutImage (597-x,y*31, P^,3); {стираем старое}
PutImage (596-x,y*31, P^,0); {рисуем новое}
PutImage (x,y*31+14, R^,0); {рисуем новое}
if x>313 then {желтое растягиваем}
begin setcolor(14); line(x-2,y*31,x-2,y*31+30);
line(627-x,y*31-12,627-x,y*31+30); end;
end; {for y}
readln;
end.
 
У меня вот как получилось
Program RGZ;
Uses Crt,Graph;
Const FigureHight=55;
FigureWidth=35;
FigureColor=red;
FigureBackground=blue;
MenuText:array[1..3]of string = ('Svobodni','Upravlenie','Exit');
var select,i,gd,gm:integer;
konez:boolean;
ch:char;
procedure Gagarin(x,y,color,background:integer);
begin
setcolor(color);
line(x, y, x+40, y+25);
line(x, y, x+20, y+25);
line(x+20, y+25, x+100, y+25);
line(x+20, y+55, x+100, y+55);
line(x+20, y+25, x+20, y+55);
line(x+100, y+55, x+130, y+40);
line(x+100, y+25, x+130, y+40);
line(x+20, y+55, x, y+80);
line(x, y+80, x+40, y+55);
circle(x+90, y+40, 10);
circle(x+70, y+40, 10);
circle(x+50, y+40, 10);
end;
procedure Upravlenie;
var x,y,ckorost:integer;
begin
x:=getmaxx div 2;
y:=getmaxy div 2;
ckorost:=1;
repeat
Gagarin(x,y,FigureColor,FigureBackground);
ch:=readkey;
Gagarin(x,y,black,black);
case ch of
#72:if (y-ckorost)>10 then dec(y,ckorost);
#80:if (y+ckorost+FigureWidth)<480 then inc(y,ckorost);
#75:if (x-ckorost)>10 then dec(x,ckorost);
#77:if (x+ckorost+FigureHight)<640 then inc(x,ckorost);
'+':if ckorost<60 then inc(ckorost);
'-':if ckorost>0 then dec(ckorost);
end;
until (ch=#27)or(ch=#13);
end;
Procedure Svobodnoe;
Var X, Y, DX, DY : Integer;
Ch : Char;
Begin
X := Random (605);
Y := Random (480);
DX := 1;
DY := 1;
While TRUE do
Begin
ClearDevice;
Gagarin(X,Y,FigureColor,FigureBackground);
if Y >= 480 then DY := -DY;
if Y <= 0 then DY := -DY;
if X >= 640 then DX := -DX;
if X <= 0 then DX := -DX;
X := X + DX;
Y := Y + DY;
Delay (1000);
if KeyPressed then Begin
Ch := ReadKey;
if Ch = #27 then Break
End
End
End;
Begin
gd:=detect;
initgraph(gd,gm,'');
randomize;
konez:=false;
repeat
cleardevice; select:=1;
repeat
for i:=1 to 3 do begin
if i=select then setcolor(Red) else setcolor(green);
outtextxy((getmaxx div 2)-50,(getmaxy div 2)-50+i*16,MenuText);
end;
ch:=readkey;
case ch of
#72:dec(select);
#80:inc(select);
end;
if select<1 then select:=3;
if select>3 then select:=1;
if ch=#27 then begin
select:=3;
ch:=#13;
end;
until (ch=#13);
cleardevice;
case select of
1:Svobodnoe;
2:Upravlenie;
3:konez:=true;
end;
until konez;
closegraph;
End.
 
Последнее редактирование:
Назад
Сверху