Найти тему
Сделай игру

Проектирование машинки

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

Всё хорошо в теории, а вот на практике всё оказалось немного не так просто, как хотелось бы. Начал я с того, что создал полотно, по которому будет машинка ездить, добавил машинку.

Машинка управляется мышкой. Экран делится вертикально пополам и, в зависимости от того, в какой зоне курсор - в ту сторону машина и поворачивает. В принципе - просто, однако, и немного неудобно: есть устоявшийся стереотип в играх, где пока давишь кнопку - машина поворачивает, отпустил - едет прямо. Тут такое управление не работает. Если оставить курсор в правом положении, машинка начнёт крутиться на месте. Разгоняется машинка нажатием левой кнопки мышки, тормозит - нажатием правой.

Думаю, такое управление не очень удобно. Пожалуй, следует сделать так, чтобы машинка разгонялась сама по себе (как, например, в Mario Carts), тормозила бы при нажатии правой кнопкой мышки, а рулилась курсором при нажатой левой кнопке и величина поворота была бы пропорциональная пути, который проделала мышка с зажатой кнопкой: как только курсор замрёт, поворот прекратится. Впрочем, в такой механике есть свои издержки. Ещё подумаю, как лучше сделать (управление хочу обеспечить исключительно мышкой).

Далее, отображение. Во всех старых гоночках с сильно ограниченными вычислительными "железа" - использовались матрицы действий: пользователь выполняет некоторый набор действий, машинка ведёт себя тем или иным образом. Например, уходит в занос.

В своём же решении я решил использовать сложение векторов. Есть вектор передних колёс, который тянет и задних, который немного отстаёт при резком повороте, что приводит к заносу. Складывать вектора довольно легко: каждый вектор имеет координаты [x,y]; сложение же векторов - просто сложение координат векторов. Величина и углы рассчитываются при помощи тригонометрических формул.

Зелёный - вектор передних колёс, жёлтый - задних, красный - направление машины при сложении векторов.
Зелёный - вектор передних колёс, жёлтый - задних, красный - направление машины при сложении векторов.

В интересах отладки добавил отрисовку векторов на машинке (они видны на первом изображении как цветные чёрточки).

Что дальше

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

Пока что не очень понятно, как обыгрывать взаимодействие со сложными фигурами (например, угол дома), через который авто (на рисунке ниже - звёздочка) - не может проехать. Сложность заключается в том, что нельзя допустить въезд авто в указанную зону, но не остановить его, а лишь немного скорректировать направление.

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

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

Есть другой способ - поделить фигуру на треугольники и попробовать найти вхождение точек машины в эту фигуру: не очень очевидно, вдобавок, нужно иметь больше контрольных точек авто (сейчас у меня их всего 4 - углы).

Звёздочка - объект, который должен отработать столкновение с фигурой.
Звёздочка - объект, который должен отработать столкновение с фигурой.

В общем, задач чтобы подумать хватает. Буду искать оптимальный результат. А пока исписываю тетрадку формулами, вычислениями и изрисовываю фигурами. Кажется, геометрия и тригонометрия мне, наконец-то, пригодились.