Даю порулить - программируем движение автомобиля для флэш-игр
09.07.2008, автор Stormit, рубрики: ActionScript, Flash игрыМного есть флэш-игр, связанных с автомобилями, когда игра ведется от третьего лица при виде сверху. В основном это гонки, где нужно намотать круги и обогнать противников. В таких случаях обычно не учитывают колеса автомобиля и при поворотах, просто поворачивают клип вокруг центра. Это не соответствует правде, но если машину окружить выхлопными газами, пылью и другими эффектами, то этого никто и не заметит. Все потому, что игровой движок не на этом строится.
Другое дело, если цель игры - припарковать машину или пройти курсы вождения. Тогда без более-менее реальной модели автомобиля (передние колеса задают поворот, а задний мост - ведущий) ничего не получится.
Решение которое я предлагаю не использует физических законов, по крайней мере я пока об этом не подозреваю, но довольно хорошо имитирует реальное поведение четырехколесного автомобиля с ведущим задним приводом.
Логика здесь такая: автомобиль вначале поворачивается (если передние колеса не смотрят прямо) и едет в этом направлении. Со смещением проблем нет, но вот поворот на правильный угол не давал мне покоя. По логике, скорость поворота прямо пропорциональна поступательной скорости автомобиля и обратно пропорциональна расстоянию между передними и задними колесами. На удивление, этого хватило, и не пришлось подбирать поправочные коэффициенты.
Чтобы это проверить, нам нужен подготовленный символ автомобиля. Достаточно иметь 4 колеса и какой-либо каркас.
- Создаем символ car и внутри него 2 колеса с именами left и right. Центр символа car должен находиться строго между задними колесами. Это ВАЖНО. Это та точка, к которой прикладывается сила тяги.
- В той же линейке, где лежит символ car, кадром выше пишем код:
speed = 0; speedLimit = 8; speedStep = .5; rotLimit = 35; rotStep = 3; processKey = function () { if (Key.isDown(Key.LEFT)) { if (car.left._rotation > -rotLimit) { car.left._rotation = car.right._rotation -= rotStep; } } else if (Key.isDown(Key.RIGHT)) { if (car.left._rotation < rotLimit) { car.left._rotation = car.right._rotation += rotStep; } } if (Key.isDown(Key.UP)) { speed += (speed < speedLimit)? speedStep : 0; } else if (Key.isDown(Key.DOWN)) { speed += (speed > -speedLimit)? -speedStep : 0; } else { speed += (speed < 0)? speedStep : (speed > 0)? -speedStep : 0; } }; function move(){ if(Math.abs(speed) > 0) { car._rotation += car.left._rotation * speed / car.left._x; } angle = car._rotation * Math.PI / 180; speedX = speed * Math.cos(angle); speedY = speed * Math.sin(angle); car._x += speedX; car._y += speedY; } onEnterFrame = function() { processKey(); move(); }
Я постарался разнести все величины по переменным, так что настроить их под другой тип машины дело не сложное. Замедление с ускорением тоже есть - все как учили
- Получаем такой результат. Управление осуществляется с клавиатуры - стрелки ←,↑,→,↓.
- Сразу проверим, как это будет работать, если передвинуть передние колеса вперед. Вроде неплохой автобус.
- Небольшой пример из жизни.
Еще немного о том, как машина исчезает с одной стороны и появляется с другой.
Я люблю наглядные способы, поэтому зону для маневров будет задавать клип box с габаритами, идентичными размеру флэшки. А уже с него я считаю ограничивающие координаты по ширине и по высоте. Тогда в дополнение к вышеизложенному, дописывается такой код:
WIDTH = zone._width; HEIGHT = zone._height; LEFT = zone._x; TOP = zone._y; RIGHT = LEFT + WIDTH; BOTTOM = TOP + HEIGHT; checkCycle = function () { bounds = car.getBounds(this); boundWidth = bounds.xMax - bounds.xMin; boundHeight = bounds.yMax - bounds.yMin if(bounds.xMax < LEFT) { car._x = RIGHT + car._x - bounds.xMin; } else if(bounds.xMin > RIGHT) { car._x = LEFT - (bounds.xMax - car._x); } if(bounds.yMax < TOP) { car._y = BOTTOM + (car._y - bounds.yMin); } else if(bounds.yMin > BOTTOM) { car._y = TOP - (bounds.yMax - car._y); } };
Теперь эту функцию нужно добавить в вызов по событию EnterFrame, после вызова функции move().
Получается вполне универсальный движок для многих видов транспорта. Но все это сделано чисто интуитивно, а я бы не прочь взглянуть, как это объясняется физикой. Так что если кто-то начертит схему с силами и всеми делами,- милости просим.
Интересно на 65%


Вах
маладэц 
Супер! Спасибо. И как всегда классно оформлена флешка =)
Кто нибудь может разжевать эту сточку
” speed += (speed 0)? -speedStep : 0; ”
Просто такую форму записи я вроде ещё не видел
Это альтернативный вариант if…else
Если условие в скобках истинно, то вместо всего этого подставляется значение идущее после вопросительного знака, иначе - после двоеточия.
а реально прицеп сзади прикрутить ?
Очередной отличный урок! Спасибо!
Про прицеп - очень класный вопрос.
Если уж пошли такие навороты, можно и дрифт на скорости просчитать!
Но это уже совсем другие гигабайты кода 
Супер, а когда комбайн увидел, вспомнил Вангеров.
Но с точки зрения реализма (небольшое дополнение) колеса поворачиваться должны на разный угол, т.к. радиусы они описывают при повороте разные (дальнее колесо относительно точки поворота) должно поворачиваться на меньший угол.
ну это так - если кто будет реалистичное что то творить.
Придумаю что-нибуть с прицепом
погоняв трактор, стало ясно, что игры в гонки надо делать не вертикальные, а горизонтальные, так интереснее управлять))
Отличный пример. А траектория практически верна, маленькая неточность - не грех )
Прикольно, посмотрл подзадумался. Автор молодец одним словом! респект!
Супер! Вот это профессионал! Доделай в игру про парковку. Кстати в IE комментарии съезжают вниз некрасиво.
А какой у тебя IE?
У меня в 6-м не съезжают
Ай, зачем таким пользоваться а, IE - ну его, юзайте лучеше Оперу или Файрфокс, и наслаждайтесь творениями автора.
По поводу дрифта.Нашёл классную игруху
http://www.demonfiles.my1.ru/load/7-1-0-198
осталось тока узнать как это реализовать )))
А в этом “дрифте” машина поворачивается по центровой оси =)
А можете дать исходник, а то мне ваш трактор сильно понравился? =)
Здорова Стормит зацини прикол: http://www.free-lance.ru/blogs/view.php?tr=236455&ord=new Там в середине парню одному ответил зип архивом. Посмотри его))) и обрати внимание на даты) ты кстате никак с этим несвязан? а то уж больно похоже получилось) (зы код да разный))
Нет, я никак с этим не связан =)
Славентий (Zloba), спасибо конечно, но это не то, о чем я просил =) Мне нужен вот именно этот трактор =)
А еще, как можно сделать чтобы следы от машины оставались?
to Славентий (Zloba)
нет, не связан, этому комбайну уже несколько лет
>>Мне нужен вот именно этот трактор =)
А зачем? Плагиат это плохо, а суть движка и код приведен выше, осталось только обрисовать фото любого трактора при виде сверху.
>>А еще, как можно сделать чтобы следы от машины оставались
рисуешь квадратный отпечаток по ширине колеса и дальше либо на EnterFrame (либо когда проехал минимально допустимое расстояние) дублируешь его и ложишь точно под колесом (машине swapDepths(10000000000)). Для остальных колес тоже самое.
Еще, дублированием (по тому же типу что и огонь), можно сделать и выброс грязи из-под задних колес.
Stormit, спасибо!
А как можно сделать такой дымок, как в тракторе? Я понимаю, что по принципу огня, но непонимаю как привязать дымок в клип с машиной. Я вставляю мувик дымка в машину, а дальше что? Какой код?
Разжуйте пожалуйста.
А вот мне нужно впихнуть все это в мувиклип. Что изменить в коде, чтобы он работал?
Ну, мне кто-то поможет?
Ало-о!
Destroyer - есть ресурсы где разжовывают (чаще форумы). В этом блоге рассказывают о хитростях. Если Художник нарисовал картину - это не обязывает его рассказывать как он ложит масло на холст. Если тебе так уж хочеться такой трактор - напряги себя и сделай. В этом блоге есть все что бы сделать самостоятельно такой трактор.
Ну как еще нужно попросить…
Господа! А мне кажется, что колеса с рулем все-таки должны сами возвращаться в центральное положение во время движения! Так реалистичней!
Да, я тоже заметил что было бы неплохо сделать возвращение колес при движении в зависимости от скорости. То есть, наверное. должно получатся, что колеса должны оставаться под одним углом относительно земли если клавиша “влево” или “вправо” не нажаты.
Заметил одну вещь - при повороте скорость машинки сильно возрастает…
Занос машины не учитывается. По идее, при повороте на быстрой скорости, машину должно нести по инерции (по касательной к радиусу поворота)
to Dmitry Matyukhin
if(!Key.isDown(Key.LEFT) && !Key.isDown(Key.RIGHT)) { car.left._rotation = car.right._rotation *= .8 * (speed / speedLimit); }типа того (нужно еще и к скорости движения привязаться)
to Destroyer
Дымок так же как и в примере с огнем, остается огненный шлейф за мячиком.
Не вижу проблем чтобы все это в мувик засунуть. У меня так все и работает. Конкретно, как обернуть несколько слоев в символ описано здесь: http://xitri.com/2008/05/17/tools-for-flash.html
спасибо очень круто
Спасибо за статью оказалась очень полезной.
Отличная идея. Сначала пытался сам спрограмировать автомобиль, но потом нашел этот сайт. Идея очень понравилась. Только немножко физики добавил, ну там инерция, автоматическое возвращение колес в исходное положение, занос автомобиля при движении на большой скорости и т.д. Только вот пришлось код писать не на кадре а на самом клипе автомобиля, так как надо было сделать много автомобилей, чтобы код не переписывать для каждого в отдельности.
Здраствуйте Stormit пытался разобрать ваш код но сколько не пробую невыходит (неработает) если вам не сложно немоглибы вы выслать на SilverForce@yandex.ru исходник (рабочий). буду очень благодарен