forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Алгоритмика (http://forum.boolean.name/forumdisplay.php?f=21)
-   -   Управление. Нажатые кнопки -> угол поворота (http://forum.boolean.name/showthread.php?t=16146)

Randomize 06.01.2012 12:52

Управление. Нажатые кнопки -> угол поворота
 
Здравствуйте, друзья обращаюсь к вам со следующим вопросом.
Почти всех играх где используется клавиатура уже стало стандартом управление WSAD или стрелки.
И игрок может одновременно нажимать 1 или 2 кнопки чтоб задать направление движения.
Во многих играх есть косяк при движении по диагонали так как складываются 2 вектора направления.
Обойти это можно задавая кнопками угол движения примерно так:


* используются только WSAD

Представим что у нас есть следующие переменные:
Код:

kbW - верх
kbS - низ
kbA - лево
kbD - право

Получаем следующую таблицу:
Код:

kbD      = 0
kbD + kbS = 45
kbS      = 90
kbA + kbS = 135
kbA      = 180
kbA + kbW = 225
kbW      = 270
kbD + kbW = 315

И вот вопрос: Нельзя ли это преобразование нажатых кнопок в угол поворота оптимизировать/упаковать как либо по элегантнее?
У меня соображалки не хватет может кто из вас сооружал нечто подобное?

З.Ы. Никакой проблемы нет! Лишь спортивный интерес. Я верю что это можно упаковать если не в одну то уж в пару строчек точно.

SBJoker 06.01.2012 13:30

Ответ: Управление. Нажатые кнопки -> угол поворота
 
Ну как бы промежуточные положения это среднее от крайних.
Но мне кажется ничего более производительного чем прямое задание нет.

Ну или все переменные представить как массив, и задавать в цикле значениями вида i * 45

Платон Александрович 06.01.2012 16:50

Ответ: Управление. Нажатые кнопки -> угол поворота
 
Цитата:

Сообщение от Randomize
Во многих играх есть косяк при движении по диагонали так как складываются 2 вектора направления.
Обойти это можно задавая кнопками угол движения

что мешает нормализовывать результирующий вектор?

Цитата:

Сообщение от Randomize
Нельзя ли это преобразование нажатых кнопок в угол поворота оптимизировать/упаковать как либо по элегантнее?

по-моему лучше всего будет таблицей и битовыми флажками
w = 1
s = 2
a = 4
d = 8

и соотвественно такая табличка
-1, 270, 90, -1, 180, 225, 135, -1, 0, 315, 45, -1, -1, -1, -1, -1, -1

-1 тогда будет означать что нажаты противоположные клавиши или юзер уснул на клаве :-D

ABTOMAT 06.01.2012 22:38

Ответ: Управление. Нажатые кнопки -> угол поворота
 
Ну зачем тут углы и прочая тригонометрия?
По сути тут только 1 число используется - синус 45° (~0.74...) На него домножать и всё. У меня он даже в константу вбит. Типа
if(две кнопки жаты)
{
if(вверх+вправо){двинуть на 0.74 вперёд и 0.74 вправо}
if(вверх+влево){двинуть на 0.74 вперёд и 0.74 влево}
...
}
if(одна кнопка жата)
{
как обычно обрабатываем
}

Платон Александрович 07.01.2012 12:31

Ответ: Управление. Нажатые кнопки -> угол поворота
 
Цитата:

Сообщение от ABTOMAT (Сообщение 216203)
Ну зачем тут углы и прочая тригонометрия?
По сути тут только 1 число используется - синус 45° (~0.74...) На него домножать и всё. У меня он даже в константу вбит. Типа
if(две кнопки жаты)
{
if(вверх+вправо){двинуть на 0.74 вперёд и 0.74 вправо}
if(вверх+влево){двинуть на 0.74 вперёд и 0.74 влево}
...
}
if(одна кнопка жата)
{
как обычно обрабатываем
}

а теперь посчитай длину вектора 0.74^2 + 0.74^2 = 1.0952, а значит скорость по диагонали будет выше
в таком случае должно быть sqrt(0.5), т.е. ~0.7071
почему я и говорю что проще и универсальнее (2д\3д) нормализовать вектор после суммирования.

ABTOMAT 07.01.2012 14:06

Ответ: Управление. Нажатые кнопки -> угол поворота
 
Цитата:

а теперь посчитай длину вектора 0.74^2 + 0.74^2 = 1.0952, а значит скорость по диагонали будет выше
Хоспаде, я же по памяти написал 0.74. Да, ошибся. Синус 45 на самом деле чуток меньше. Возьми более-менее точное значение синуса 45° (как я и сказал в посте) и получишь годный результат:

var sin45 = 0.7071067811;
var length = sin45*sin45+sin45*sin45;
(извиняюсь, что пишу пример на жабаскрипте)

В length получим 0.9999999997552067.
Приемлемо, я думаю. С нормализацией будет такая же точность, но там
1. Вычисление длины вектора
2. Два деления
А тут только умножение на 0.7071067811.

Платон Александрович 07.01.2012 14:48

Ответ: Управление. Нажатые кнопки -> угол поворота
 
Цитата:

Сообщение от ABTOMAT (Сообщение 216228)
но там
1. Вычисление длины вектора
2. Два деления
А тут только умножение на 0.7071067811.

У тебя в этом месте ботлнек что-ль? Нашел где экономить :)

ABTOMAT 07.01.2012 16:21

Ответ: Управление. Нажатые кнопки -> угол поворота
 
Во-первых так логичней и проще сделать, во-вторых в реалтайме везде боттлнек — пора бы привыкнуть.
Хотя нынче стало модно говнокодить, но это уж на совести разраба.

Платон Александрович 07.01.2012 17:11

Ответ: Управление. Нажатые кнопки -> угол поворота
 
Цитата:

Сообщение от ABTOMAT (Сообщение 216238)
Во-первых так логичней и проще сделать

Логичнее? Логичнее как раз движение представить в векторной форме.
Проще? Сравни твою лапшу из условий и этот вариант (с++ псевдокод):
Код:

вектор направление
if (вперед) направление += взгляд.xz
if (назад ) направление -= взгляд.xz
if (вправо) направление += взгляд.zx
if (влево ) направление -= взгляд.zx
нормализовать(направление)
двигать(направление)

Цитата:

Сообщение от ABTOMAT (Сообщение 216238)
во-вторых в реалтайме везде боттлнек — пора бы привыкнуть.
Хотя нынче стало модно говнокодить, но это уж на совести разраба.

Везде боттлнек когда действительно говнокодишь. Надо уметь различать когда оптимизация нужна, а когда она вредна и\или бесполезна. Особенно когда пользуешься оптимизирующими компиляторами, которым проще оптимизировать оперируя высокоуровневыми конструкциями, на уровне алгоритма. Ручная (а особенно неумело выполненная) оптмизация не только мешает компилятору, но и затрудняет восприятие кода, а также, что очевидно, тормозит разработку.

ABTOMAT 07.01.2012 21:38

Ответ: Управление. Нажатые кнопки -> угол поворота
 
Okay.

moka 08.01.2012 00:39

Ответ: Управление. Нажатые кнопки -> угол поворота
 
Я делал так (псевдокод):
vec2 moveDirection = new vec2(keyD - keyA, keyW - keyS).Normalized;
Быстро и просто. Получаем вектор движения. Таким образом просто делать смешивание (изменение вектора направления), но тут уже зависит что нужно.
Но имея векторы направления, заместо углов - имхо лучше, т.к. проще писать AI да и математически быстрее. Т.к. в компьютерном представлении угол - это более сложная сущность, нежели вектор.

YellowAfterlife 15.01.2012 17:38

Ответ: Управление. Нажатые кнопки -> угол поворота
 
PHP код:

sin45 0.7071// константа для угла
/// ...
// определение 0\+1\-1 "вектора" кнопок:
keyX keyboard_check(vk_right) - keyboard_check(vk_left);
keyY keyboard_check(vk_down) - keyboard_check(vk_up);
// присваиваем это собственно вектору движения
// (тут еще можно умножить на скорость передвижения):
velX keyX;
velY keyY;
// если движение по диагонали, то умножаем на константу
// зачем тут нормализация...
if (keyX != && keyY != 0) {
    
velX *= sin45
    velY 
*= sin45
}
// теперь velX, velY хранят значения "вектора" движения. 

Вроде бы все хорошо. Никаких хранений направлений или потерь длины вектора (особенно если задавать константу большей точности)


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

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot