Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Проблема: Делаю Аэрохоккей (http://www.flasher.ru/forum/showthread.php?t=118496)

SenCheR 25.11.2008 16:43

Проблема: Делаю Аэрохоккей
 
Уже готово поле, шайба отскакивает от стен.
Люди подскажите как сделать отскок от "клюшек", чтобы шайба отлетала под отраженным углом и со скоростью удара?

Добавлено через 3 минуты
Клюшки круглые - 50х50пикселей, шайба круглая 32х32.

CrazyFlasher 25.11.2008 16:53

...короче, люди, сделайте за меня
http://www.google.ee/search?hl=ru&q=...1%81%D0%BA&lr=

И ещё советую книгу "Making Things Move!"...только он для АС3...но алгоритмы везде одинаковые независимо от языка

Division 25.11.2008 17:00

При отскоке шайбы от клюшки, тебе нужно учитывать направление движения самой шайбы и клюшки? Я бы не учитывал, ИМХО так будет играбельней. Если надо, сам потом расширишь алгоритм.
Так как у нас и шайба и клюшка - это окружности, после удара шайба будет двигаться по вектору, который можно провести от центра клюшки до центра шайбы(изменишь, если не устраивает). Самое сложное - определить координаты шайбы и клюшки в момент столкновения. Простой hitTest тут естественно не подходит, так как шайба и клюшка могут двигаться с большими скоростями и пролететь друг сквозь друга. Я бы решил это через систему уровнений. Сейчас я не могу привести её, так как исходник реализующий это на домашнем компе( в своё время делал арканоид (: ), вечером если надо скину. Смысл в том что можно записать уровнение движения шайбы и клюшки как
Код:

Xш = X0ш+Vxш*t
Yш = Y0ш+Vyш*t

Где X0ш, Y0ш - начальная позиция, Vx, Vy - горизонтальная и вертикальная скорость, t - время
То де самое для клюшки
Код:

Xк = X0к+Vxк*t
Yк = Y0к+Vyк*t

Они столкнуться если расстояние между ними будет равно сумме радиусов. Дописываем в систему
Код:

(Xк-Xш)^2 + (Yк-Yш)^2 = (Rш+Rк)^2
Вообщем всё записанное это одна большая система. Найти нам надо t - время, через которое они встретятся. После нахождения t подставляем его в любые уравнения и находим X и Y шайбы или клюшки.
Если надо, вечером выложу рабочий код, на Delphi правда.

SenCheR 25.11.2008 17:13

Буду благодарен за любую помощь.

У меня столкновение определяется так:
Код:

function checkPaddle(ball) {
                       
                if (distance(paddle, ball)<paddleRadius+ballRadius) {
                        return (true);}
                        return (false);
}

function distance(clip1, clip2) {
        // find distance between two movie clips
        xx = clip1._x-clip2._x;
        yy = clip1._y-clip2._y;
        return (Math.sqrt(xx*xx+yy*yy));
}

где paddle-клюшка, ball - шайба

не могу сделать как правильно отскочить шайбе

iNils 25.11.2008 17:44

SenCheR, для оформления своего кода, надо использовать теги [code][/code].

SenCheR 25.11.2008 18:02

Спасибо. А есть ли какой-то простой вариант без времени?
Может сделать отбивные точки - 4 вверху, внизу, слева и справа и 4 по диагоналям биты?

Division 25.11.2008 18:28

Простой вариант - каким-то образом определяем, что столкнулись. То есть имеем центры шайбы(Pш) и клюшки(Pк) в момент столкновения. Тогда шайба отлетит по вектору V:

Код:

v = normalize(Pш-Pк)*Speed
Так сойдёт?

SenCheR 26.11.2008 00:10

Спасибо попробую. А исходник когда можно будет глянуть?

Division 26.11.2008 00:36

SenCher, имеешь в виду исходник о котором я говорил? Тогда вот. Еле нашёл) Страшно смотреть как я кодил пару лет назад)
Код:

function CirCollision(x1,y1,r1,a1,s1,x2,y2,r2,a2,s2:single; var t:single):boolean;
var ABx,ABy,COSA,SINA,K,A,B,D,CABx,SABy,t1,t2:single;
begin
  Result:=true;
  ABx:=x1-x2;
  ABy:=y1-y2;
  COSA:=cos(a1)*s1-cos(a2)*s2;
  SINA:=sin(a1)*s1-sin(a2)*s2;
  K:=sqr(ABx)+sqr(ABy)-sqr(r1+r2);
  CABx:=2*COSA*ABx;
  SABy:=2*SINA*ABy;
  A:=sqr(COSA) + sqr(SINA);
  B:=CABx+SABy;
  // Получаем квадратное уравнение A*t^2+B*t+K=0
  D:=B*B-4*A*K;
  if (D < 0) or (A = 0) then // Уравнение не имеет корней или A=0, что маловероятно (:
    begin
      Result:=false;
      t:=0;
      Exit;
    end;
  t1:=(-B-sqrt(D))/(2*A);
  t2:=(-B+sqrt(D))/(2*A);
  if t1<t2 then
    t:=t1
  else t:=t2;
  if t<0 then
    Result:=false;
end;

Извини, он на Delphi и переводить мне лень (:
"var t:single" - это значит примерно то же что передача параметра по ссылке в AS.
Оказывается я здесь выводил немного другое уравнение движения, с учётом угла движения, а не вектора. Вообщем, функция проверяет сталкиваются ли две окружности, начальная позиция которых x1,y1 и x2,y2; радиусы r1,r2; углы под которыми они двигаются a1 и a2; скорости s1 и s2. Углы, как видно, в радианах.
Уравнение движения таких окружностей должны быть вида
Код:

X=X0+cos(Angle)*Speed*t;
Y=Y0+sin(Angle)*Speed*t;

Иначе работать не будет) t, который получаем на выходе - это время, через которое столкнутся. Если от 0 до 1 - значит, на этом "ходу" столкнулись. Больше 1 - вероятно столкнуться в будущем, если курс не поменяют.
Даже не знаю, получится ли тебе её адаптировать под свою ситуацию.


Часовой пояс GMT +4, время: 15:55.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.