Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Просьба о помощи с алгоритмом для игры (поведение героя в замкнутой области) (http://www.flasher.ru/forum/showthread.php?t=171717)

australian incognito 22.11.2011 19:50

Просьба о помощи с алгоритмом для игры (поведение героя в замкнутой области)
 
Я к вам с очередным вопросом, коллеги.
Представьте себе следующую ситуацию:
Есть некая круглая область (далее "арена"), внутри которой находится также круг много меньшего радиуса (далее "герой"). Мне удалось заставить героя бегать за курсором мыши в пределах арены (герой это в моем случае класс, а арена - просто мувик на сцене):
Герой:
Код AS3:

package glar.main
{
        import flash.display.MovieClip;
 
        public class Hero extends MovieClip
        {
                var step:Number = 6;
                var radius:Number = 80;
                public function Hero()
                {
                        //
                }
        }
}

Основной класс:
Код AS3:

package glar.main
{
        import flash.display.MovieClip;
        import flash.display.Stage;
        import flash.events.Event;
        import flash.geom.Point;
 
        public class Main extends MovieClip
        {
                var hero:Hero = new Hero();
                public function Main()
                {
                        super();
                        addChild(hero);
                        hero.x = stage.width/2;
                        hero.y = stage.height/2;
                        hero.addEventListener(Event.ENTER_FRAME, heroGo);
                }
                private function heroGo(event:Event):void {
                        var dx:Number = mouseX - hero.x;
                        var dy:Number = mouseY - hero.y;
                        var angle:Number = Math.atan2(dy, dx);
                        var dist:Number = Math.sqrt(dx*dx + dy*dy);
                        if(dist > hero.step) {
                                var tgtX:Number = hero.step * Math.cos(angle);
                                var tgtY:Number = hero.step * Math.sin(angle);
                                hero.rotation = angle*180/Math.PI;
                                var heroPnt:Point = new Point(hero.x, hero.y);
                                var arenaPnt:Point = new Point(arena.x, arena.y);
                                if (Point.distance(arenaPnt, heroPnt) + hero.radius/2 < arena.height/2) {
                                        hero.x += tgtX;
                                        hero.y += tgtY;
                                }
                        }
                }
        }
}

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

artcraft 22.11.2011 19:59

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


вот функция для рассчёта цели персонажа, когда курсор вне арены

Добавлено через 8 минут
Код AS3:

// Returns the point on segment [A,B] which is ratio times the total distance 
// between A and B away from A
public static function pointOnLine(a:Point, b:Point, ratio:Number):Point {
        return new Point(a.x + (b.x - a.x) * ratio, a.y + (b.y - a.y) * ratio);
}

Код AS3:

var target:Point = pointOnLine(arenaCenter, mousePosition,arenaRadius / Point.distance(arenaCenter, mousePosition) );


australian incognito 22.11.2011 20:10

Сейчас попробую.
Алгоритм мне очень нравится - настолько просто, что я удивляюсь, как сам не додумался...

Добавлено через 1 час 17 минут
Офигенно, все работает еще интеллектуальнее, чем я хотел этого изначально при минимуме циклов и исключающих проверок. Спасибо огромное еще раз.

Добавлено через 1 час 20 минут
Если не секрет, пункт 1б вы на ходу придумали за 5 минут - или это результат старых наработок?

Ookami 22.11.2011 21:36

Пункт 1б это первое что приходит в голову с заданными условиями.

artcraft 22.11.2011 21:56

Цитата:

Сообщение от australian incognito (Сообщение 1047589)
Если не секрет, пункт 1б вы на ходу придумали за 5 минут - или это результат старых наработок?

да что тут придумывать,
а вот функция для точки на прямой кочует из проекта в проект


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

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