Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование в широком смысле слова > Алгоритмика

Алгоритмика Об алгоритмах вообще; методы, обсуждения способов решения

Ответ
 
Опции темы
Старый 06.01.2012, 12:52   #1
Randomize
[object Object]
 
Аватар для Randomize
 
Регистрация: 01.08.2008
Адрес: В России
Сообщений: 4,355
Написано 2,471 полезных сообщений
(для 6,852 пользователей)
Управление. Нажатые кнопки -> угол поворота

Здравствуйте, друзья обращаюсь к вам со следующим вопросом.
Почти всех играх где используется клавиатура уже стало стандартом управление 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
И вот вопрос: Нельзя ли это преобразование нажатых кнопок в угол поворота оптимизировать/упаковать как либо по элегантнее?
У меня соображалки не хватет может кто из вас сооружал нечто подобное?

З.Ы. Никакой проблемы нет! Лишь спортивный интерес. Я верю что это можно упаковать если не в одну то уж в пару строчек точно.
__________________
Retry, Abort, Ignore? █
Intel Core i7-9700 4.70 Ghz; 64Gb; Nvidia RTX 3070
AMD Ryzen 7 3800X 4.3Ghz; 64Gb; Nvidia 1070Ti
AMD Ryzen 7 1700X 3.4Ghz; 8Gb; AMD RX 570
AMD Athlon II 2.6Ghz; 8Gb; Nvidia GTX 750 Ti
(Offline)
 
Ответить с цитированием
Старый 06.01.2012, 13:30   #2
SBJoker
Злобный Админ
 
Аватар для SBJoker
 
Регистрация: 04.09.2005
Сообщений: 5,926
Написано 3,415 полезных сообщений
(для 9,330 пользователей)
Ответ: Управление. Нажатые кнопки -> угол поворота

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

Ну или все переменные представить как массив, и задавать в цикле значениями вида i * 45
__________________
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Randomize (07.01.2012)
Старый 06.01.2012, 16:50   #3
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: Управление. Нажатые кнопки -> угол поворота

Сообщение от 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 тогда будет означать что нажаты противоположные клавиши или юзер уснул на клаве
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Randomize (07.01.2012)
Старый 06.01.2012, 22:38   #4
ABTOMAT
Ференька
 
Аватар для ABTOMAT
 
Регистрация: 26.01.2007
Адрес: улица Пушкина дом Колотушкина
Сообщений: 10,741
Написано 5,461 полезных сообщений
(для 15,675 пользователей)
Ответ: Управление. Нажатые кнопки -> угол поворота

Ну зачем тут углы и прочая тригонометрия?
По сути тут только 1 число используется - синус 45° (~0.74...) На него домножать и всё. У меня он даже в константу вбит. Типа
if(две кнопки жаты)
{
if(вверх+вправо){двинуть на 0.74 вперёд и 0.74 вправо}
if(вверх+влево){двинуть на 0.74 вперёд и 0.74 влево}
...
}
if(одна кнопка жата)
{
как обычно обрабатываем
}
__________________
Мои проекты:
Анальное Рабство
Зелёный Слоник
Дмитрий Маслов*
Различие**
Клюква**

* — в стадии разработки
** — в стадии проектирования
Для проектов в стадии проектирования приведены кодовые имена

(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Randomize (07.01.2012)
Старый 07.01.2012, 12:31   #5
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: Управление. Нажатые кнопки -> угол поворота

Сообщение от ABTOMAT Посмотреть сообщение
Ну зачем тут углы и прочая тригонометрия?
По сути тут только 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д) нормализовать вектор после суммирования.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
h1dd3n (07.01.2012)
Старый 07.01.2012, 14:06   #6
ABTOMAT
Ференька
 
Аватар для ABTOMAT
 
Регистрация: 26.01.2007
Адрес: улица Пушкина дом Колотушкина
Сообщений: 10,741
Написано 5,461 полезных сообщений
(для 15,675 пользователей)
Ответ: Управление. Нажатые кнопки -> угол поворота

а теперь посчитай длину вектора 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.
__________________
Мои проекты:
Анальное Рабство
Зелёный Слоник
Дмитрий Маслов*
Различие**
Клюква**

* — в стадии разработки
** — в стадии проектирования
Для проектов в стадии проектирования приведены кодовые имена

(Offline)
 
Ответить с цитированием
Старый 07.01.2012, 14:48   #7
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: Управление. Нажатые кнопки -> угол поворота

Сообщение от ABTOMAT Посмотреть сообщение
но там
1. Вычисление длины вектора
2. Два деления
А тут только умножение на 0.7071067811.
У тебя в этом месте ботлнек что-ль? Нашел где экономить
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
h1dd3n (07.01.2012)
Старый 07.01.2012, 16:21   #8
ABTOMAT
Ференька
 
Аватар для ABTOMAT
 
Регистрация: 26.01.2007
Адрес: улица Пушкина дом Колотушкина
Сообщений: 10,741
Написано 5,461 полезных сообщений
(для 15,675 пользователей)
Ответ: Управление. Нажатые кнопки -> угол поворота

Во-первых так логичней и проще сделать, во-вторых в реалтайме везде боттлнек — пора бы привыкнуть.
Хотя нынче стало модно говнокодить, но это уж на совести разраба.
__________________
Мои проекты:
Анальное Рабство
Зелёный Слоник
Дмитрий Маслов*
Различие**
Клюква**

* — в стадии разработки
** — в стадии проектирования
Для проектов в стадии проектирования приведены кодовые имена

(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо ABTOMAT за это полезное сообщение:
LLI.T.A.L.K.E.R. (07.01.2012), SBJoker (07.01.2012)
Старый 07.01.2012, 17:11   #9
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: Управление. Нажатые кнопки -> угол поворота

Сообщение от ABTOMAT Посмотреть сообщение
Во-первых так логичней и проще сделать
Логичнее? Логичнее как раз движение представить в векторной форме.
Проще? Сравни твою лапшу из условий и этот вариант (с++ псевдокод):
вектор направление
if (вперед) направление += взгляд.xz
if (назад ) направление -= взгляд.xz
if (вправо) направление += взгляд.zx
if (влево ) направление -= взгляд.zx
нормализовать(направление)
двигать(направление)
Сообщение от ABTOMAT Посмотреть сообщение
во-вторых в реалтайме везде боттлнек — пора бы привыкнуть.
Хотя нынче стало модно говнокодить, но это уж на совести разраба.
Везде боттлнек когда действительно говнокодишь. Надо уметь различать когда оптимизация нужна, а когда она вредна и\или бесполезна. Особенно когда пользуешься оптимизирующими компиляторами, которым проще оптимизировать оперируя высокоуровневыми конструкциями, на уровне алгоритма. Ручная (а особенно неумело выполненная) оптмизация не только мешает компилятору, но и затрудняет восприятие кода, а также, что очевидно, тормозит разработку.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
h1dd3n (07.01.2012)
Старый 07.01.2012, 21:38   #10
ABTOMAT
Ференька
 
Аватар для ABTOMAT
 
Регистрация: 26.01.2007
Адрес: улица Пушкина дом Колотушкина
Сообщений: 10,741
Написано 5,461 полезных сообщений
(для 15,675 пользователей)
Ответ: Управление. Нажатые кнопки -> угол поворота

Okay.
__________________
Мои проекты:
Анальное Рабство
Зелёный Слоник
Дмитрий Маслов*
Различие**
Клюква**

* — в стадии разработки
** — в стадии проектирования
Для проектов в стадии проектирования приведены кодовые имена

(Offline)
 
Ответить с цитированием
Старый 08.01.2012, 00:39   #11
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,863 пользователей)
Ответ: Управление. Нажатые кнопки -> угол поворота

Я делал так (псевдокод):
vec2 moveDirection = new vec2(keyD - keyA, keyW - keyS).Normalized;
Быстро и просто. Получаем вектор движения. Таким образом просто делать смешивание (изменение вектора направления), но тут уже зависит что нужно.
Но имея векторы направления, заместо углов - имхо лучше, т.к. проще писать AI да и математически быстрее. Т.к. в компьютерном представлении угол - это более сложная сущность, нежели вектор.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Randomize (08.01.2012)
Старый 15.01.2012, 17:38   #12
YellowAfterlife
ПроЭктировщик
 
Аватар для YellowAfterlife
 
Регистрация: 19.02.2011
Сообщений: 134
Написано 81 полезных сообщений
(для 219 пользователей)
Ответ: Управление. Нажатые кнопки -> угол поворота

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 хранят значения "вектора" движения. 
Вроде бы все хорошо. Никаких хранений направлений или потерь длины вектора (особенно если задавать константу большей точности)
__________________

Мой сайт-блог. Игры, обновления, примеры для Haxe, JavaScript(+HTML5), GameMaker, Love2d...
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


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


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com