Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Обход препятсвия [D7, XP]


Страницы:   1 2

nordford ©   (2010-07-26 16:23:00) 

Здравствуйте!
Пишу небольшую игру, есть необходимость перемещения игрока из одной точки в другую на плоскости. Игроки, как и препятствия, представляют собой круги (коорд и радиус). Так как особого поиска пути мне не нужно, обход препятсвия решил делать след образом: игрок идет к цели, если впереди препятствие, то изменяем угол в одну сторону, если там тоже препятствие, то в другую.
На рисунке это выглядит так:
http://i054.radikal.ru/1007/fe/a5e3992f0361.jpg
Вот часть кода:

function collision(k:integer):boolean;
var
i:integer;
begin
collision:=false;
for i:=1 to 10 do
if (sqrt(sqr(objects[i].x1-player[k].x)+sqr(objects[i].y1-player[k].y))<15+objects[i].r)then collision:=true;
end;

//в цикле, когда идем к цели
//ygol- ф-я просчета угла
ygl:=ygol(player[i].x,player[i].y,player[i].action.x,player[i].action.y);
   player[i].x:=player[i].x+player[i].speed*cos(ygl);
   player[i].y:=player[i].y+player[i].speed*sin(ygl);
   //proverka na collision
   if collision(i) then
       begin
//если вошли в препятствие, то отходим назад
       ygl:=ygl-pi;
       player[i].x:=player[i].x+player[i].speed*cos(ygl);
       player[i].y:=player[i].y+player[i].speed*sin(ygl);
//изменяется угол коэффициентом k*pi
//k изменяется 0.7 -0.7 0.5 -0.5
       k:=0.7;
       repeat
       ygl:=ygl+pi*k;
       player[i].x:=player[i].x+player[i].speed*cos(ygl);
       player[i].y:=player[i].y+player[i].speed*sin(ygl);
       flag:=false;
       if collision(i) then
           begin
           flag:=true;
           ygl:=ygl-pi*k;
           player[i].x:=player[i].x+player[i].speed*cos(ygl);
           player[i].y:=player[i].y+player[i].speed*sin(ygl);
           if (k<0) then
           k:=-k-0.2
           else k:=-k;
           end;
       until (not flag)or(k=0.3);

В итоге правильно ходит только в одну сторону (по часовой стрелке) в другую просто стоит. Можно поменять в условии 0.7 на -0.7, тогда пойдет в другую сторону. Как бы сделать чтоб работало в обе стороны. Вроде все правильно и в теории и в коде. Единственное до чего я додумался, так это то, что программа прост не успевает записывать новые координаты игрока и правильно просчитывать коллизии. Пытался напихать application.processmessages но не помагает.
Когда-то давно была потребность в точно таком же действии, решил жутким способом, хотелось бы так, как задумано..


nordford   (2010-07-26 17:09:00) [21]


> Для этого нужно знать насколько он "небольшой". Т.е. знать
> его радиус или диаметр.

Для этого я в самом начале и написал:

> Игроки, как и препятствия, представляют собой круги (коорд
> и радиус).

У меня характеристики препятствий хранятся в objects[i].x1 objects[i].y1 objects[i].r
Или вам надо точное значение? Ну возьмите радиус игрока 15, а препятствия 30. Впрочем невижу никакой раздницы..


Сергей М.   (2010-07-26 16:59:00) [22]


> почему бы его плавно не обойти по контуру?


Для этого нужно знать насколько он "небольшой". Т.е. знать его радиус или диаметр.


nordford   (2010-07-26 16:45:00) [23]


> Стоя на месте переместиться из одной точки в другую никак
> не удастся))

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


Сергей М.   (2010-07-26 16:38:00) [24]


> если препятствий несколько, то .. будем просто стоять на месте


Стоя на месте переместиться из одной точки в другую никак не удастся))


nordford   (2010-07-26 16:32:00) [25]


> .. и вновь упираемся рогом в первое ?)

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


Сергей М.   (2010-07-26 16:27:00) [26]

> если впереди препятствие, то изменяем угол в одну сторону, если там тоже препятствие, то в другую

.. и вновь упираемся рогом в первое ?)


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо