Как сгладить срабатывание кода?
- Войдите на сайт для отправки комментариев
Сб, 26/02/2022 - 21:42
Я сделал управление ходьбой в играх реальными шагами с помощью датчиков на ногах. Закрепил датчики ускорения на каждую ногу на голени. Датчики имеют 3 оси. Датчики подключены параллельно к одним и тем же пинам. Оси X расположены по ходу движения вперед- назад. Оси Y обращены вниз, а Z влево- вправо. Код работает, но ходьба получается рывками, с микропаузами, в момент постановки одной ноги и начала движения другой. Подскажите, как убрать эти паузы, чтобы персонаж в игре шел так же, как и при постоянно нажатой клавише #include <SoftwareSerial.h>. #include <Keyboard.h> int x = 0; //ось x датчика расположена по направлению движения вперед int y = 0; //ось y датчика расположена по направлению вниз int z = 0; // ось z датчика расположена по направлению движения вбок unsigned long millisstep = 0; void setup() { pinMode(chek, INPUT_PULLUP); Keyboard.begin(); } void loop() { //чтение показаний ускорений со всех осей датчика ускорения if (millis() - millisstep > 100) { x = analogRead(A0); z = analogRead(A2); } y = analogRead(A1); // нажатие кнопки W при движении вперед. if (x < 330 && y > 410) { //ускорение на оси x свидетельствует о начале движения вперед Keyboard.press('w'); //ускорение на оси y обращенной вниз говорит о наличии центробежной millisstep = millis(); //силы, значит нога движется } else if (y < 410) { Keyboard.release('w'); } // нажатие кнопки S при движении назад if (x >340 && y > 410) { Keyboard.press('s'); millisstep = millis(); } else if (y < 410) { Keyboard.release('s'); } //нажатие кнопки A при движении влево if (z > 340 && y >410) { Keyboard.press('a'); millisstep = millis(); } else if (y < 410) { Keyboard.release('a'); } //нажатие D при движ вправо if (z < 330 && y > 410) { Keyboard.press('d'); millisstep = millis(); } else if (y < 410) { Keyboard.release('d'); } }
И где в этом коде "ходьба"?
Ходьба в играх работает на кнопки WSDA. Датчики на ногах, в зависимости от напраления реальной ходьбы в игре нажимается клавиша, соответствующая направлению.
Напишите алгоритм того, что Вы хотите сделать по-русски.
Я уже не знаю как еще можно объяснить.
Вы знаете что такое датчики ускорения? Вот они на ногах. Если по оси Х ускорение меньше 330, значит нога по этой оси начала движение вперед. Но так как сила на датчике возникает только в самом начале движения, то этого мало, мне нужно считывать все движение ноги, чтобы кнопка движения в игре нажималась все время шага. Для этого еще в условии ставлю ось У. Она направлена вниз. Так как голень ноги движется по дуге, то по оси У во время всего движения ноги возникает сила центробежного ускорения > 410. Когда срабатывают эти два условия, можно понять, что происходит шаг вперед. Значит в игре надо нажать кнопку вперед W.
Со всеми другими направлениями аналогично.
Проблема в том, что во время шага возникают моменты, когда обе ноги на мгновение стоят на земле, на это мгновение кнопка W отпускается и в игре получается нажал- отпустил, вместо нажал. Анимация ходьбы персонажа в игре становится дерганная, она не успевает проиграться, как кнопка уже отпускается.
Если включить не игру, а текстовый документ, то wwwwwww будет нажиматься постоянно без рывков, потому что там есть инерция, этого мгновения текстовый редактор не замечает. А игры быстро реагируют на нажатие и отпускание и с ними такое не проходит
Вы знаете что такое датчики ускорения?
Нет, не знаю.
Замерь время когда кнопка отпускается и не отпускай кнопку на это время + ещё чуть-чуть когда обе ноги на земле. Получится искусственная инерция.
Просто использовать delay ? Не получается, время это каждый раз будет немного отличаться, а значит будет пропущен момент начала шага, мгновение, когда нога только начинает движение и возникает сила на оси Х, по которой понимается направление вперед. Дальше движение ноги равноускоренное и силы почти никакой нет на датчике
Ferrit, скажите, что происходит в Вашей игре при нажатии/отпускании клавиши? Один шаг или несколько шагов, пока не отпустишь клавишу?
Если второе - то Вам нужно придумать алгоритм, который бы превращал сигналы с датчиков (на каждом шаге) в один непрерывный сигнал, состоящий из двух команд: "пошли" и "остановились".
Не начинайте писать код до тех пор, пока отчетливо по-русски не сможете записать алгоритм такого преобразования.
Просто использовать делей, как минимум, глупо. Обдумай слова Андриано, он мои слова обернул в более понятные.
В играх нет как такового шага, там просто перемещение персонажа и проигрывание анимации ходьбы.
Речь идет не о моей игре, а обо всех играх шутерах.
Там нет такого, что на нажал- отпустил будет сделан шаг, если быстро нажать и отпустить, то в игре персонаж просто немного дернется вперед на треть шага, если смотреть по расстоянию.
На счет непрерывного сигнала. Каждый шаг заканчивается остановкой передней ноги, и обгоном задней ноги переднюю. В этот момент, во время резкой остановки передней ноги, на ее датчике возникает ускорение при торможении в обратную сторону на оси Х, а на У тоже ускорение вниз при ударе о землю.
И код воспринимает этот момент как начало движения назад. Потому что движение назад включается именно по такому алгоритму. Поэтому на мгновение команда "движение вперед" прерывается на движение назад и возникает микро пауза. Как можно сделать непрерывный сигнал движения вперед, если проверку на движение назад мне нужно так же делать каждый шаг.
Вам нужно сделать саморегулирующийся таймер.
Ввести 3 переменные
булеан dvijenie
2 инт на вперёд и на вбок
Убрать иф в 20-й строке.
Дальше надо делать таймер. Внутри ифа. По каждой оси.
millis() . Этот таймер отсчитывает время с начала каждого цикла. А как сделать, чтобы таймер начинал считать с момента срабатывания датчика?
Как это преобразовать в код с использованием millis() или может какого- то другого таймера?
======================================================
Если х < 330 и у > 410 на время больше, чем 100 мс, то движение вперед
======================================================
Когда нога ставится на землю, на ней возникает обратное ускорение торможения на Х и ускорение от удара на У. В это мгновение код "думает, что это движение назад" От движения назад это отличает только то, что на оси У ускорение очень короткое от удара, а при движении назад на У ускорение от центробежной силы длится в течение всего движения ноги.
Эти микро паузы, думаю, возникают как раз по этой причине, что код "не отличает" просто постановку ноги и начало шага назад.
У меня были переменные вначале на каждую сторону. И все работало так же. Я просто их удалил, раз они ни на что не влияли.
Я почти уверен, что нужно исправить вот это, но не знаю как выразить это в коде.
Если знаете, напишите, пожалуйста, вот эту строчку
Если х < 330 и у > 410 на время больше, чем 100 мс, то движение вперед
Попробуйте так.
В 12-м сообщении убрать
<code
class
=
"plain"
> и
</code>
Keyboard.press(
'*'
);
Вставлять в каждом цикле после объявления "true". Тогда будет блок остальных движений до остановки.
А можно код написать, я не понял вообще здесь)
Код из предыдущего сообщения я сейчас пробую, пока непонятное движение рывками
Совместил. Рывки убрал.