![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Обход препятсвия [D7, XP]
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]> если впереди препятствие, то изменяем угол в одну сторону, если там тоже препятствие, то в другую
.. и вновь упираемся рогом в первое ?)