IPB
ЛогинПароль:

> Супер бильярд, подскажите...
сообщение
Сообщение #1


Новичок
*

Группа: Ожидающие
Сообщений: 15
Пол: Мужской

Репутация: -  0  +


Решил тут я бильярд на паскале написать. Ну кий там, шарик ведущий сделал, всё пока работает(кий толкает шарик, он катиться, замедляет ход), но необходимо и другие шары в игру(какой же это будет бильярд с одним шариком), а вот соударение шариков друг с другом, что-то не осилил. Подскажите, пожалуйста!!!! Заранее спасибо.


--------------------
http://magicrown.ru
<... image(s) deleted (Admin) ...>
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
сообщение
Сообщение #2


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


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

Uses Graph,Crt;

const MaxShar=10;
type shar = object
 { переменные }
 x,y:integer; { текущие координаты шара }
 r:word;      { радиус }
 color:byte;  { цвет шара }
 dx,dy:shortint; { скорость. задается значениями
                   перемещения на каждом шаге (в точках) }
 hits:set of byte; { множество шаров с которыми данный шар уже
 столкнулся и с которыми не надо обсчитывать столкновение еще раз }
 { методы }
 constructor initShar(x0,y0:integer; r0:word; color0:byte; dx0,dy0:shortint);
 procedure Move; { двигаем }
 procedure Show; { показываем }
 procedure Hide; { прячем }
 procedure CheckBorder; { проверяем на выход за границы экрана }
 procedure CheckHit(k:byte); { проверяем на столкновение с другим шаром }
 procedure revertXDirection; { поменять Х/Y-составляющую скорости }
 procedure revertYDirection; { на противоположную }
 procedure TurnAfterHit(k:byte); { вычислить новые значения
              скорости двух шаров после удара. Первый шар - шар
              данного объекта, второй - с индексом k в массиве }
 function Value:real; { вычислить объем шара. Нужно для вычисления
      скорости. Вообще-то там масса нужна, но учитывая, что плотность
      все-равно сократиться при делении, используем объем }
 {procedure PrintState;} { отладочные печати }
 end;
var bgColor,i:byte;
   x,y,dx,dy,ErrCode:integer;
   r:word;
   shars: array[1..MaxShar] of shar; { массив шаров }
   sh:shar;
   f:text; { файл для отладочных печатей }
Procedure shar.Move;
 begin
 x:=x+dx;
 y:=y+dy;
 end;
Procedure shar.Show;
 begin
 setColor(color);
 circle(x, y, r);
 {PutPixel(x,y,color);} { уберите комментарий чтобы увидеть траекторию }
 end;
Procedure shar.Hide;
 begin
 setColor(bgColor);
 circle(x, y, r);
 end;
procedure shar.revertXDirection;
 begin
 dx:=-dx;
 x:=x+dx;
 end;
procedure shar.revertYDirection;
 begin
 dy:=-dy;
 y:=y+dy;
 end;
Constructor shar.initShar(x0, y0 :integer; r0 :word; color0 :byte; dx0, dy0 :shortint);
 begin
 x:=x0;
 y:=y0;
 r:=r0;
 color:=color0;
 dx:=dx0;
 dy:=dy0;
 hits:=[];
 end;
procedure shar.CheckBorder;
 begin
 if (r+x>=GetMaxX-1) or (x-r<=1) then revertXDirection;
 if (y+r>=GetMaxY-1) or (y-r<=1) then revertYDirection
 end;
{procedure shar.PrintState;
 begin
 writeln(f,'x=',x:3,' y=',y:3,' r=',r:3,' dx=',dx:3,' dy=',dy:3);
 end;}
procedure shar.TurnAfterHit(k:byte);
{ формулы для движения шаров взяты здесь:
 http://ferro.phys.msu.ru/prak/PDF/01-mechanics/07.pdf }
var m1, m2 :real;
   vx10,vy10,vx20,vy20:integer;
 begin
 m1 := Value;            { массы }
 m2 := shars[k].Value;
 vx10 := dx;             { начальные значения скоростей }
 vy10 := dy;
 vx20 := shars[k].dx;
 vy20 := shars[k].dy;
 { скорость первого шара после удара }
 dx := round((2*m2*vx20 + (m1-m2)*vx10)/(m1+m2));
 dy := round((2*m2*vy20 + (m1-m2)*vy10)/(m1+m2));
 { скорость второго шара после удара }
 shars[k].dx := round((2*m1*vx10 + (m2-m1)*vx20)/(m1+m2));
 shars[k].dy := round((2*m1*vy10 + (m2-m1)*vy20)/(m1+m2));
 end;
function shar.Value:real;
 begin { возвращает объем шара }
 Value:=4*Pi*r*r*r/3;
 end;
procedure shar.CheckHit(k:byte);
var i1:byte;
   dist:longint;
 begin
 for i1:=1 to MaxShar do if ((i1<>k) and not(k in hits)) then
   begin
   shars[i1].hits:=shars[i1].hits+[k];
   dist:=round(sqrt(sqr(1.0*x-shars[i1].x)+sqr(1.0*y-shars[i1].y)));
   if (dist<r+shars[i1].r) then
     begin
     TurnAfterHit(i1);

     CheckBorder;
     Move;
     shars[i1].CheckBorder;
     shars[i1].Move;

     { скорость задается значениеми dx и dy - шагами движения. Таким
     образом она дискретна. Момент столкновения определяется по
     расстоянию между шарами. Но запросто может случиться, что шары
     на каком-то шаге пересекутся и в этом случае необходимо их
     развести в разные стороны перед тем как высчитывать расстояние на
     следуещем шаге, иначе они могут пребывать в состоянии постоянного
     столкновения }
     dist:=round(sqrt(sqr(1.0*x-shars[i1].x)+sqr(1.0*y-shars[i1].y)));
     while (dist<r+shars[i1].r) do
       begin
       CheckBorder;
       Move;
       shars[i1].CheckBorder;
       shars[i1].Move;
       dist:=round(sqrt(sqr(1.0*x-shars[i1].x)+sqr(1.0*y-shars[i1].y)));
       end;
     end;
   end;
 end;

function initializeGraph:integer;
var grDriver : Integer;
     grMode : Integer;
 begin
 grDriver:=Detect;
 InitGraph(grDriver, grMode, '');
 initializeGraph:=GraphResult;
 end;

begin
ErrCode:=initializeGraph;
if ErrCode <> grOk then
  WriteLn('Ошибка инициализации графики:', GraphErrorMsg(ErrCode))
else
 begin
 assign(f,'log.txt');
 rewrite(f);
 bgColor:=0;
 rectangle(1,1,GetMaxX-1,GetMaxY-1);

 {shars[1].initShar(100,100,50,3,6,-3);
 shars[2].initShar(100,200,40,4,5,3);
 shars[3].initShar(200,200,20,5,-7,-4);
 shars[4].initShar(400,300,25,2,-9,-1);
 shars[5].initShar(500,200,35,14,-5,-8);
 if (MaxShar>5) then}

 { инициализация шаров случайным образом }
 for i:=1 to MaxShar do
   begin
   r:=20+random(10);
   shars[i].initShar(1+r+random(GetMaxX-2*r),
     1+r+random(GetMaxY-2*r),r,1+random(GetMaxColor-1),
     random(15)-7,random(12)-6);
   end;
 { обсчитываем движение пока не нажата какая-либо клавиша }
 repeat
   { показываем все шары }
   for i:=1 to MaxShar do
     shars[i].Show;
   { временная задержка - установите свое значение для вашего компьютера }
   Delay(580);
   { убираем с экрана все шары }
   for i:=1 to MaxShar do
     shars[i].Hide;
   { просчитываем следующий шаг }
   for i:=1 to MaxShar do
     begin
     shars[i].Move;
     shars[i].CheckBorder;
     shars[i].CheckHit(i);
     end;
   for i:=1 to MaxShar do
     shars[i].hits:=[];
 until keyPressed;
 CloseGraph;
 close(f);
 end
end.



--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

Сообщений в этой теме
VelarThind   Супер бильярд   11.04.2005 23:38
Altair   Вот этот пример думаю будет полезен. Код очень хор…   11.04.2005 23:58
mithquessir   Светлик, вот нашел pdfник описания какой-то лабора…   12.04.2005 0:26
AlienEmperor   А почему бы не представить игровое поле в виде мас…   12.04.2005 15:11
Бродяжник   С матричным полем возможны такие траблы: 1. Шары н…   12.04.2005 17:21
AlienEmperor   На самом деле я как раз недавно скидывал альфу игр…   12.04.2005 17:51
Atos   4. А если столкнутся больше двух шаров? :) Сейч…   12.04.2005 18:04
Бродяжник   AlienEmperor Поделитесь алгоритмом - как нужно обр…   12.04.2005 19:49
VelarThind   Тут ещё какой вопрос. Нужно то не просто их оттолк…   12.04.2005 21:18
AlienEmperor   На самом деле, в данном случае, придется немного…   13.04.2005 14:15
volvo   Ребята, вы вопрос внимательно читали? Мало ли ч…   13.04.2005 15:52
AlienEmperor   Volvo, ну так я же не спорю... И вариант решения п…   13.04.2005 15:56
VelarThind   Олег, спасибо за код, как раз то что нужно. Остало…   13.04.2005 16:15
Shura   Процедура TurnAfterHit неправильная!!…   23.04.2005 0:00
Altair   А в чем заключается неправильность? Втом, что не …   23.04.2005 0:11
Shura   Ну я ж привёл пример. Вот когда они в воздухе ста…   23.04.2005 0:22
Altair   Если не нравится, исправь!   23.04.2005 0:26
Shura   Хех, так если я б знал как, я бы не спрашивал - я…   23.04.2005 0:42
Altair   а понял :) насчет неправильности... l:=Arctan((y2-…   23.04.2005 0:49
Shura   Да не - нам то в радианах потом и нужно будет. Это…   23.04.2005 0:58
-Aleks-   Да не - нам то в радианах потом и нужно будет. Эт…   21.01.2010 13:04
Archon   Дак она и так под lazarus работает не плохо. Что п…   21.01.2010 14:34
TarasBer   Для шаров одной массы при идеально упругом столкно…   21.01.2010 23:12


 Ответить  Открыть новую тему 
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 4.05.2024 1:52
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name