У меня есть общая проблема, я полагаю.
В настоящее время я изучаю C ++ и SDL 2.0. SDL предоставляет функцию, которая возвращает указатель на постоянную *, содержащую все состояния клавиш.
Вот переменные, которые я хотел бы использовать:
const Uint8* oldKeyState;
const Uint8* currentKeyState;
В конструкции моего input.cpp:
currentKeyState = SDL_GetKeyboardState(&this->length);
oldKeyState = currentKeyState;
И в методе Update () я использую:
oldKeyState = currentKeyState;
currentKeyState = SDL_GetKeyboardState(NULL);
Однако вместо того, чтобы копировать последние значения, все, что я делаю, это даю указатель на oldKeyState, который, в свою очередь, указывает на текущее состояние ключа.
Итак, как мне скопировать фактические значения из указателя переменной в текущее и старое состояние ключа? Мне не нужен указатель в моем старом состоянии ключей, так как я не смогу проверить, было ли предыдущее состояние ВВЕРХ, а новое — ВНИЗ.
Проблема, с которой вы столкнулись, заключается в том, что вы пытаетесь скопировать указатель на массив const, который никогда не изменяется. В результате вы увидите, что оба указателя идут по одному и тому же адресу памяти, и у вас никогда не будет двух копий состояния ввода, которое позволяет вам проверять наличие нажатых клавиш.
Вместо этого вы должны использовать memcpy для копирования одного массива в другой. Но чтобы сделать это, вы должны изменить тип oldKeyState на Uint8*
или вы получите ошибку при копировании в константный массив.
Итак, код должен выглядеть так:
const Uint8 * currentKeyState;
Uint8 * oldKeyState;
...
//Constructor
currentKeyState = SDL_GetKeyboardState(&this->length);
oldKeyState = new Uint8[this->length];
...
//Input update
memcpy(oldKeyState, currentKeyState, this->length);
SDL_PumpEvents(); //Copy the array before calling PumpEvents()!
currentKeyState = SDL_GetKeyboardState(NULL);
Uint8 oldKeyState[SDL_NUM_SCANCODES];
// ...
memcpy(oldkeystate, currentKeyState, length);
Подпись функции, которую вы вызываете
const Uint8* SDL_GetKeyboardState(int* numkeys)
Эта функция имеет тип возврата const Uint8*
, что означает, что он возвращает указатель на байт (ы). (Он не возвращает указатель на указатель.) Согласно документации, этот возвращаемый указатель фактически указывает на массив Uint8
(один Uint8
недостаточно велик для кодирования состояний всех клавиш на клавиатуре), а значение, на которое указывает numkeys
перезаписывается длиной этого массива (т. е. количеством ключей). Таким образом, чтобы сохранить значения в массиве, вам нужно выделить область памяти той же длины, что и хранится в this->length
и затем скопируйте эту память из массива SDL в свой. Затем вы захотите сохранить указатель на свой собственный массив для дальнейшего использования. Поскольку SDL говорит, что возвращенный указатель на массив действителен в течение всего времени жизни приложения, вы можете предположить, что длина неизменна, поэтому вам не нужно беспокоиться об изменении размера массива, но вы должны беспокоиться об освобождении этой памяти когда вы закончите с этим.
Итак, я думаю, что SDL — это в основном библиотека Си.
const Uint8*
SDL_GetKeyboardState возвращает указатель на первый элемент массива в значениях.
Если вы хотите скопировать данное состояние для дальнейшего использования, вам, как правило, понадобится массив для копирования и цикл for для копирования. например:
currentKeyState = SDL_GetKeyboardState(&this->length);
savedKeyState = malloc(this->length*sizeof(Uint8));
for(int i=0; i<&this-length, i++) savedKeyState [i] = currentKeyState[i];
Конечно, этот довольно плохой код, использующий вектор, может быть лучшим способом, например:
currentKeyState = SDL_GetKeyboardState(&this->length);
vector savedKeyState(currentKeyState, currentKeyState+length);