Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > арканоид?!


Автор: dieterb 23.8.2007, 16:34
у меня есть задача по типу арканоида, не могу решить:

условно:
SX - X шарика
SY - Y шарика
SH - высота шарика
SW - ширина шарика

SVX - вектор движения шарика по X
SVY - вектор движения шарика по Y
SS - скорость шарика (очень важно что скорость движения шарика как правило не равна 1, а больше, 
т.е. он двигается не плавно, а рывками)

BX - X блока
BY - Y блока
BH - высота блока
BW - ширина блока

вроде все написал, если какие еще нужны входные параметры, можно придумать, я реализую

Задача: правильно определить вектор шарика после столкновениея с препятствием (желательно на паскале, хотя пофиг, я переработаю)

Меня не интересует дальнейшая его скорость и пр. мне нужен только вектор (направление, "верх", "низ", "верх-лево" и т.д.), я написал сначала условие относительно центра шарика, но столкнулся с тем, что в случае, например 2 блоков подряд (горизонтально, придвинутых вплотную) при попадании в угол между этими двумя блоками, шар отлетает не под 45 градусов, а назад в обратном направлении, в этом вся проблема.

заранее спасибо !

Автор: _Y_ 23.8.2007, 17:01
Я когда-то писал подобную задачу. Все делалось по принципу "угол падения равен углу отражения". Если же шарик попадал в угол, то угол моделировался поверхностью отражения, наклоненной под 45 градусов. Шар, в результате, отлетал не под 45 градусов, но и не обратно, а, типа, под углом  90 минус начальный угол (в зависимости от того, какую стенку считать за ноль, естественно). 

Автор: kali 23.8.2007, 17:09
есть у меня подозрение, что расчет направления у тебя верный.
просто при попадании в точку соприкосновения двух блоков сначала шарик отскакивает от горизонтальной поверхности ближнего блока, а потом еще от вертикальной поверхности дальнего, в результате чего летит в обратном направлении.
просто сделай отдельную обработку для таких случаев.

Автор: dieterb 23.8.2007, 17:14
Цитата(_Y_ @ 23.8.2007,  17:01)
 то угол моделировался поверхностью отражения, наклоненной под 45 градусов. 

но ведь "наклонить  поверхность отражения" можно в 2 стороны.

допустим вот угол, это типа рисунок smile 
 _I

шар к нему летит справа-снизу, после "наклона  поверхности отражения под 45 градусов" он может отскочить как в "верх-вправо", так и "вниз-влево", в зависимости от того как мы "наклоним  поверхность", вот тут и возникает вопрос как повернуть ?

разве что смотреть есть ли рядом с этом блоком соседние...

Добавлено через 7 минут и 27 секунд
Цитата(kali @  23.8.2007,  17:09 Найти цитируемый пост)
шарик отскакивает от горизонтальной поверхности ближнего блока, а потом еще от вертикальной поверхности дальнего, 


при попадании на угол для шарика срабатывает сначала условие как будто он отлетает от горизонтали на 90 градусов обратно и от вертикали на 90 обратно, в результате получается на 180 обратно. но это при обработке только центра шарика, шарик у меня пока просто точка.

Автор: kali 23.8.2007, 17:59
dieterb, 
так я не совсем понял. в чем у тебя проблема?

Автор: dieterb 23.8.2007, 18:13
Цитата(kali @ 23.8.2007,  17:59)
dieterb, 
так я не совсем понял. в чем у тебя проблема?

У меня есть 3 простых алгоритма и все они не правльно обрабатывают попадание шарика в точку между двумя блоками.
В этом вся проблема.

1 способ:

     if SY + (SH/2) < BY then SVY:=-SVY;
      if SX + (SW/2) < BX then SVX:=-SVX;
      if SY + (SH/2) > BY + BH then SVY:=abs(SVY);
      if SX + (SW/2) > BX + BW then SVX:=abs(SVX);

2 способ:

      if SY + (SH/2) < BY then SVY:=-SVY;
       if (SX + (SW/2) < BX)
      and (SY + (SH/2) >= BY)
      and (SY + (SH/2) <= BY + BH)
      then SVX:=-SVX;

       if SY + (SH/2) > BY + BH then SVY:=abs(SVY);
       if (SX + (SW/2) > BX + BW)
      and (SY + (SH/2) >= BY)
      and (SY + (SH/2) <= BY + BH)
      then SVX:=abs(SVX);

3 способ:

 if  (SY < BY + Sh[i,j].BitH)
 and (SY + SH > BY + Sh[i,j].BitH)
 and (SX + (SW/2) > BX)
 and (SX + (SW/2) < BX + Sh[i,j].BitW)
 then  SVY:=-SVY;

 if  (SY < BY)
 and (SY + SH > BY)
 and (SX + (SW/2) > BX)
 and (SX + (SW/2) < BX + Sh[i,j].BitW)
 then  SVY:=-SVY;

 if  (SX < BX)
 and (SX + SW > BY)
 and (SY + (SH/2) > BY)
 and (SY + (SH/2) < BY + Sh[i,j].BitH)
 then  SVX:=-SVX;

 if  (SX < BX + Sh[i,j].BitW)
 and (SX + SW > BX + Sh[i,j].BitW)
 and (SY + (SH/2) > BY)
 and (SY + (SH/2) < BY + BY)
 then  SVX:=-SVX;

Автор: _Y_ 23.8.2007, 19:55
Цитата(dieterb @ 23.8.2007,  17:14)
допустим вот угол, это типа рисунок smile 
 _I

шар к нему летит справа-снизу, после "наклона  поверхности отражения под 45 градусов" он может отскочить как в "верх-вправо", так и "вниз-влево", в зависимости от того как мы "наклоним  поверхность", вот тут и возникает вопрос как повернуть ?

По мне - так прямой угол _I моделируется плоскостью / (45 градусов). Причем как в случае шарика летящего снизу-справа (внешний угол), так и сверху-слева (внутренний угол). А "варианты" получаются только если удар пришелся не точно в угол, а в одну из его сторон. Впрочем, по ощущениям, сам Арканоид давал некоторый разброс при отскоке от углов. Но это скорее было сделано специально датчиком случайных чисел, чтобы несколько усложнить игру.

Автор: dieterb 23.8.2007, 20:01
Цитата(_Y_ @ 23.8.2007,  19:55)
Цитата(dieterb @ 23.8.2007,  17:14)
допустим вот угол, это типа рисунок smile 
 _I

шар к нему летит справа-снизу, после "наклона  поверхности отражения под 45 градусов" он может отскочить как в "верх-вправо", так и "вниз-влево", в зависимости от того как мы "наклоним  поверхность", вот тут и возникает вопрос как повернуть ?

По мне - так прямой угол _I моделируется плоскостью / (45 градусов). Причем как в случае шарика летящего снизу-справа (внешний угол), так и сверху-слева (внутренний угол). А "варианты" получаются только если удар пришелся не точно в угол, а в одну из его сторон. Впрочем, по ощущениям, сам Арканоид давал некоторый разброс при отскоке от углов. Но это скорее было сделано специально датчиком случайных чисел, чтобы несколько усложнить игру.

По твоему получается что в случае поподания шарика в угол блока он отлетит обратно - и это нормально.
Хотя может быть я не правильно задачу поставил. Да, он должен отлететь обратно, но как сделать так что бы этого не произошло если к этому блоку приставлен другой и удар пришелся на стык этих двух блоков ? посмотри мои алгоритмы, может что подскажешь. Хотя бы для одного угла или стороны.

Автор: likehood 23.8.2007, 22:56
Можно несколько стоящих вплотную блоков представить в виде одного большого блока. Только придется придумать алгоритм объединения блоков.

Автор: dieterb 23.8.2007, 23:12
Цитата(likehood @ 23.8.2007,  22:56)
Можно несколько стоящих вплотную блоков представить в виде одного большого блока. Только придется придумать алгоритм объединения блоков.

я седня уже как раз над этим думал smile

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

Код

   if (SY + SH + SVY > BY)
   and (SY + SVY < BY)
   and (SX + (SW/2) + SVX > BX)
   and (SX + (SW/2) + SVX < BX + BW)
   Then SVY:=-abs(SVY);

   if (SY + SVY < BY + BH)
   and (SY + SH + SVY > BY + BH)
   and (SX + (SW/2) + SVX > BX)
   and (SX + (SW/2) + SVX < BX + BW)
   Then SVY:=abs(SVY);

   If (SX + SW + SVX > BX)
   and (SX + SVX < BX)
   and (SY + (SH/2) + SVY > BY)
   and (SY + (SH/2) + SVY < BY + BH)
   Then SVX:=-abs(SVX);

   if (SX + SVX < BX + BW)
   and (SX + SW + SVX > BX + BW)
   and (SY + (SH/2) + SVY > BY)
   and (SY + (SH/2) + SVY < BY + BH)
   Then SVX:=abs(SVX);


может кому нить понадобится.

Автор: _Y_ 24.8.2007, 09:10
Цитата(dieterb @ 23.8.2007,  20:01)
По твоему получается что в случае поподания шарика в угол блока он отлетит обратно

Нет, это не по моему smile  Попробую обьяснить на примере. К сожалению у меня здесь нет никакого графического редактора - не могу нарисовать картинку. Возмем угол _I Скажем, что направление  I это 0 градусов, а направление  _ это 90 градусов; т.е. угол считается против часовой стрелки. Вот "таблица" примеров: направление, с которого шарик прилетает - направление, в котором он отражается :
  • прилет 15 улет 75
  • прилет 30 улет 60
  • прилет 45 улет 45 - обратное отражение
  • прилет 75 улет 15
  • прилет 180 улет 270
  • прилет 190 улет260
  • прилет 225 улет 225 - обратное отражение
  • прилет 260 улет 190
  • прилет 270 улет 180
Остается проблема с прилетом из секторов 90-180 и 270-0, т.к применение того же подхода (отражение от плоскости поставленной под 45) привело бы к "странным" результатам. Я бы в этих случаях просто забыл про угол и при прлете из 90-180 отражал от стороны _, а при 270-0 - от стороны I.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)