2015-06-13 5 views
4

При поиске на методы обнаружения нескольких ключей сразу в SDL 2, я наткнулся на этот кусок кода для СВД 1.x:SDL_Keycodes являются слишком большими для хранения

//author: Rob Loach 
// Global key buffer 
bool keys[256]; 

while(SDL_PollEvent(&mainEvent)) 
{ 
    if(mainEvent.type == SDL_KEYDOWN) 
    { 
     keys[mainEvent.key.keysym.sym] = true; 
    } 
    else if(mainEvent.type == SDL_KEYUP) 
    { 
     keys[mainEvent.key.keysym.sym] = false; 
    } 
} 

Я попытался его реализации в SDL2 и a std::array<bool, 256>, но у меня было Segmentation fault: 11 с кнопкой вверх.

Именно тогда я посмотрел на это: https://wiki.libsdl.org/SDLKeycodeLookup.

Большинство специальных клавиш, включая стрелку, функцию, символы и т. Д., Имеют десятичные представления в миллиардах.

Даже с простым кодом printf("%d\n", e.key.keysym.sym); на, скажем, кнопка вверх дает:

1073741906 
Segmentation fault: 11 

Я на Mac, если это делает никакой разницы с кодами ошибок.

Итак, какие решения существуют в SDL 2?

+1

Вы можете использовать 'std :: map', таким образом, вы не столкнетесь с этой проблемой. Я не думаю, что есть много, чтобы помочь вам в «SDL2». – olevegard

+0

@olevegard Отлично! Не могли бы вы написать это как ответ? –

ответ

3

Прежде всего, bool s не по умолчанию ничего в C++, вам необходимо их инициализировать. Тот факт, что они кажутся всегда true, заключается в том, что они размером byte. Это означает, что они имеют размер между 0 и 255 включительно. Только 0 будет означать false, поэтому его a 255/256 шанс true.


Что касается вашего решения, вы бы просто определить ваш std::map как это:

std::map<SDLKey, bool> keyMap; 

std::map изначально пустой, так что вы должны проверить, что элементы на самом деле существует, когда вы пытаетесь посмотреть его вверх.

bool IsKeyDown(SDLKey key) 
{ 
    // Look for element 
    auto it = keyMap.find(key); 

    if (it == keyMap.end()) 
     // No element found, which means this key hasn't been pressed 
     return false; 

    // 'it' is an iterator, so we use * to return its value 
    return it->second; 
} 

При попытке установить элемент, он будет automtically получить создан, если он не существует:

bool SetIsKeyDown(SDLKey key, bool isDown) 
{ 
    keyMap[key] = isDown 
} 

Так факт, что std::map изначально пустой означает, что вам не нужно, чтобы заполнить Это. Вы можете, если хотите, но это не требуется, как с массивом.

+2

Изменил некоторые вещи в редактировании. 'it' является std :: пар, с первым объектом, содержащим ключ, и вторым объектом, содержащим значение, поэтому' return (* it); 'не будет работать,' return it-> second; 'будет работать. Кроме того, 'it' будет равен' keyMap.end(); 'если он * NOT * найден, поэтому правильный код' if (it == keyMap.end(); '. Спасибо за отличный ответ хотя :) – ThatPixelCherry

+2

@ThatPixelCherry спасибо, я должен научиться запускать свой код через компилятор, прежде чем я отправлю ... – olevegard

+0

Ха-ха не проблема :) – ThatPixelCherry