Школа создателей компьютерных игр

BannerDrive.ru
[Главная] [С чего начать?] [Дистанционное обучение] [Статьи] [Обучалки] [Книги] [Софт] [Форум] [Ссылки] [О сайте]

Ввод с клавиатуры часть 2



Подпишитесь на рассылку "Создание компьютерных игр"

Рассылки Subscribe.Ru
Создание компьютерных игр

Рассылка выходит раз в месяц.


Понравился сайт? Узнайте, как помочь сайту.


Рекомендуемые книги


Андре Ламот.
Программирование трехмерных игр для Windows. Советы профессионала по трехмерной графике и растеризации


Андре Ламот.
Программирование игр для Windows. Советы профессионала


Проголосуйте за сайт в рейтинге GameTop!
(нажмите на кнопку рейтинга)

GameTop - рейтинг игровых ресурсов. Портал Rolemancer (www.rolemancer.ru)

Не забывайте, что результаты рейтинга обновляются раз в неделю. Пожалуйста, голосуйте почаще!


Статистика посещаемости

Rambler's Top100

Ввод с клавиатуры | Все обучалки раздела | Ввод с помощью мыши

Описание

Показывается, как получать ввод с клавиатуры вне WndProc().

Программа печатает в окне текст "GameTutorials" случайным цветом, если была нажата одна из букв этого слова.

Скачать обучалку (Visual C++ 6)

Работа программы

Исходный код

Файл win_main.cpp
// Done by TheTutor -- 6/27/02
// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com

/*      Эта обучалка о том, как получать ввод с клавиатуры в вашем приложении Win32.
      Windows позволяет сделать это многими способами, но эта обучалка фокусируется
      на методе, который получает ввод с клавиатуры вне WndProc().

      Что касается приложения, мы сделаем его достаточно простым. Мы напишем
      функцию, которая будет определять, нажата ли клавиша. Мы будем проверять
      и верхний, и нижний регистры. Если вы нажмете одну из букв слова "GameTutorials",
      вы увидите на экране надпись "GameTutorials", напечатанную случайным цветом.

      Итак, приступим.
*/


#include "input.h"

typedef unsigned char uchar; // Чтобы меньше набирать

#define WIN_WIDTH 640
#define WIN_HEIGHT 480

// Откуда начинать рисование текста
#define TEXT_X 280 
#define TEXT_Y 220

#define class_name "GT_KeyboardInput2"


// Эта функция напечатает на экран передаваемый текст
// используя передаваемый RGB цвет.
void PrintColoredText(HWND hwnd, char *text, uchar R, uchar G, uchar B);

// Стандартная callback функция
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);


int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow)
{

    HWND hwnd;      // Ссылка на наше окно
    MSG msg;      // В этой переменной будут сохраняться сообщения (такие, как
                        // нажатие клавиши), которые может получить наше окно.
                        
    WNDCLASSEX wndclassex = {0};      // Это наш "класс окна". "EX" означает
                                                      // "extended style" (расширенный стиль),
                                                      // который дает нам больше опций, когда
                                                      // мы создаем наше окно (хотя мы и проигнорируем их).

    // Заполняем нужные нам поля
    wndclassex.cbSize = sizeof(WNDCLASSEX);            // Всегда должно быть установлено
    wndclassex.style = CS_HREDRAW | CS_VREDRAW; // Стиль класса окна
    wndclassex.lpfnWndProc = WinProc;                  // Указатель туда, где определена WinProc()
    wndclassex.hInstance = hinstance;                  // Ссылка на экземпляр нашего окна
    wndclassex.lpszClassName = class_name;            // Имя нашего класса окна
    wndclassex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // Устанавливаем фоновый
                                                                                                      // цвет окна - белый

    RegisterClassEx(&wndclassex);      // Регистрируем класс окна, чтобы вызовы CreateWindow()
                                                      // и CreateWindowEx() знали, какой класс окна использовать
                                                      // при создании окна

    hwnd = CreateWindowEx(NULL,                              // Дополнительные атрибуты окна, NULL - их нет
                                      class_name,                  // Имя, которое мы дали WNDCLASSEX  
                                      "Keyboard 2",            // Текст заголовка окна
                                      WS_OVERLAPPEDWINDOW,      // Стиль окна
                                      CW_USEDEFAULT,            // x левого верхнего угла окна (по умолчанию)
                                      CW_USEDEFAULT,            // y левого верхнего угла окна (по умолчанию)
                                      WIN_WIDTH,                  // Ширина окна в пикселях
                                      WIN_HEIGHT,                  // Высота окна в пикселях
                                      NULL,                              // Ссылка на "родительское окно" (у нас его нет) 
                                      NULL,                              // Ссылка на меню (у нас его нет)
                                      hinstance,                  // Ссылка на экземпляр окна (передается WinMain())
                                      NULL);                        // "Дополнительная информация" для передачи 
                                                                        // в WinProc (у нас ее нет)

            // Проверка ошибок
            if(!hwnd)
                  return EXIT_FAILURE; // Случилось что-то плохое!

    ShowWindow(hwnd, ishow); // Показать окно (сделать его видимым)
    UpdateWindow(hwnd);             // Обновить окно (нарисовать его)

    while(1)
      {
            // Получить сообщения (например, нажатие клавиши) если они есть
            if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
            {
                  if(msg.message == WM_QUIT)
                        break;
                        
                  TranslateMessage(&msg);
                  DispatchMessage(&msg);
            }
            else
            {
                  // Если нажата какая-либо буква слова "GameTutorials" (регистр важен),
                  // напечатать "GameTutorials" на экран случайным цветом
                  if (KeyPressed('G') || KeyPressed('a') ||
                        KeyPressed('m') || KeyPressed('e') ||
                        KeyPressed('T') || KeyPressed('u') ||
                        KeyPressed('t') || KeyPressed('o') ||
                        KeyPressed('r') || KeyPressed('i') ||
                        KeyPressed('l') || KeyPressed('s'))
                  {
                        uchar red = rand()%256;
                        uchar green = rand()%256;
                        uchar blue = rand()%256;

                        PrintColoredText(hwnd, "GameTutorials", red, green, blue);
                  }

                  Sleep(100); // Сделаем паузу

            }

      }

      UnregisterClass(class_name,hinstance); // Освободим память, выделенную WNDCLASSEX
            return msg.wParam; // И выходим
}

// Оконная процедура
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
      PAINTSTRUCT ps;

    // Здесь мы многого делать не будем
    switch(message)
    {
            case WM_PAINT:

                  BeginPaint(hwnd,&ps);
                  EndPaint(hwnd,&ps);
                        return 0;
      
        case WM_DESTROY:
            case WM_CLOSE:
            
                  PostQuitMessage(0);
             return 0;

    } // конец switch(message)

    return DefWindowProc(hwnd, message, wparam, lparam);
}


void PrintColoredText(HWND hwnd, char *text, uchar red, uchar green, uchar blue)
{
      // Проверка ошибок
      if(!text)
            return; // Если "text" недействителен, выходим из функции

      HDC hdc = GetDC(hwnd); // Получаем контекст устройства окна

            // Проверка ошибок
            if(!hdc)
                  return; // Не можем рисовать без HDC, выходим из функции

      RECT rect;
      GetClientRect(hwnd, &rect); // Получаем RECT клиент-области окна

      // Сбрасываем клиент-область окна в белый цвет
      FillRect(hdc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));

      // Эта функция делает то, что вы и ожидаете, она устанавливает
      // цвет текста для определенного контекста устройства в
      // передаваемые значения RGB цвета.
      SetTextColor(hdc,RGB(red,green,blue));

      /*      Эта функция печатает текст в окне. Рассмотрим ее по параметрам:
            
            hdc - контекст устройства где нужно рисовать (в нашем случае
            hdc == "наше окно").
            TEXT_X - координата Х, откуда начинать рисовать текст
            TEXT_Y - координата Y, откуда начинать рисовать текст
            text - char* (Windows определяет эту переменную как LPCSTR,
            но на самом деле это то же, что и char*), который содержит
            отображаемую строку
            strlen(text) - число символов в строке
      */

      TextOut(hdc,TEXT_X,TEXT_Y,text,strlen(text));

      ReleaseDC(hwnd,hdc); // Всегда освобождайте HDC

      /***** 
      
        Замечание:

            В SetTextColor() мы используем макрос RGB()

            RGB() это Win32 макрос, который делает COLORREF. COLORREF это
            32-битное значение, определяющее RGB цвет. Вот так COLORREF
            выглядит в шестнадцатиричном виде:

            0x00bbggrr 

            Где bb - синий компонент, gg - зеленый компонент, и rr - красный
            компонент, каждый из который может иметь беззнаковое значение
            между 0 - 255

      *****/
}


// Работа с клавиатурой

/*
      К счастью, Windows позволяет легко получать информацию с клавиатуры вне WinProc().
      Тем не менее, важно упомянуть две другие функции, которые также могут получать
      данные с клавиатуры:
      

      short GetKeyState(int virtualKey); // Эта функция в точности такая же, как мы написали.
                                                         // Вы передаете виртуальный код клавиши, и она
                                                         // возвращает short.  Если высший бит возвращаемого
                                                         // значения установлен в единицу, клавиша нажата.
                                                         // Если низший бит установлен в единицу, то клавиша
                                                         // "отжата". В другом случае клавиша не нажата.
                                                         
      А теперь, если вы пишете функции ввода для игры, и скорость критична, вы захотите
      использовать эту функцию:
      

      short GetAsyncKeyState(int virtualKey); // Эта функция пропускает нормальный процесс
                                                                  // "хорошо, клавиша была нажата, поместим ее
                                                                  // в очередь для обработки" и дает вам
                                                                  // информацию о состоянии клавиши асинхронно
                                                                  // (т.е. немедленно). Подобно другим функциям,
                                                                  // если высший бит установлен в 1, то клавиша
                                                                  // нажата. Но низший бит на этот раз равен 1,
                                                                  // если клавиша была нажата после предыдущего
                                                                  // вызова GetAsyncKeyState()


      Поэтому, если вы пишете код ввода для игры, и вам неважен регистр, вы можете
      просто написать функцию KeyPressed() вот таким образом:


      bool KeyPressed(char key) // Проверка, была ли нажата буква
      {
            key = toupper(key);

            return (GetAsyncKeyState(key) & 0x8000) == 0x8000;
      }


Задание:

      Напишите функции "key pressed" для алфавитных, цифровых или знаковых клавиш
      клавиатуры, чувствительные к регистру.
*/
/*
|  TheTutor                
|  thetutor@gametutorials.com  
|  © 2000-2002 GameTutorials  
*/

// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com

Файл input.h
#ifndef INPUT_H
#define INPUT_H

#include <windows.h>

// Это функция, которая делает все "волшебство". Эта функция берет любую букву
// (a - z и A - Z) и возвращает true, если она была нажата, и false в другом случае
bool KeyPressed(char key);


#endif

Файл input.cpp
#include "input.h"

// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com

// Это массив байтов, в котором будет храниться состояние клавиатуры
BYTE keyboard[256] = {0};

// Мы будем проверять высший бит и/или низший бит байтов нашего
// "клавиатурного" массива. Поэтому введем для удобства эти определения.
#define HIGH_BIT 0x80 // Высший бит включен (т.е. 10000000 в двоичной системе)
#define LOW_BIT 0x01  // Низший бит включен (т.е. 00000001 в двоичной системе)

// Возвращает true если клавиша (обязательно буква) была нажата,
// и false в другом случае
bool KeyPressed(char key)
{
      // Если это НЕ буква (не часть алфавита), возвратим false
      if(isalpha(key) == false)
            return false;

      /*      Эта функция заполняет наш массив "клавиатурных" байтов статусом
            всех клавиш. Каждая ячейка массива содержит виртуальный код
            клавиши (список виртуальных кодов клавиш в конце этого файла)
              
            Когда функция завершается, если высший бит - 1, значит клавиша
            нажата. Если нет - значит не нажата.
      
            А теперь для "переключающихся" клавиш (как caps lock), если низший
            бит равен 1, клавиша "включена", а если 0 - "выключена".
      */
      
      GetKeyboardState(keyboard); // Заполняем "клавиатуру" состоянием клавиш

      // Теперь у нас есть заполненный статусом клавиатуры массив. А дальше мы не
      // можем обращаться к нему напрямую. Сперва нам нужно определить, была ли
      // клавиша в нижнем регистре
      
      if(islower(key)) // Если клавиша в нижнем регистре
      {
            // Если клавиша shift нажата, или нажата caps lock, то нельзя нажать
            // клавишу в нижнем регистре
            if((keyboard[VK_SHIFT] & HIGH_BIT) || (keyboard[VK_CAPITAL] & LOW_BIT))
                  return false;

            // Так сложилось, что виртуальные коды клавиш и значения ASCII для
            // заглавных букв (A - Z) равны. Поэтому если мы хотим проверить, была ли
            // нажата определенная клавиша в нижнем регистре, нам нужно перевести ее
            // в верхний регистр и использовать ее как индекс нашего клавиатурного
            // массива

            key = toupper(key); // Перевести в верхний регистр

            // А это может выглядеть запутанным, хотя это не так.
            // Вот то что мы делаем, только более расширенно.
            //
            //      if(keyboard[key] & HIGH_BIT) // Если установлен HIGH_BIT
            //            return true;
            //      else
            //            return false;                   // Если HIGH_BIT не установлен
            // 
            return ((keyboard[key] & HIGH_BIT) == HIGH_BIT);
      }
      else
      {
            // Если мы добрались сюда, мы знаем, что клавиша в верхнем регистре.
            // Мы также знаем, что есть только два способа набрать букву в верхнем
            // регистре - либо удерживая shift, либо нажав caps lock.

            // Здесь мы проверим, была ли клавиша нажата вместе с клавишей shift
            if((keyboard[key] & HIGH_BIT) && (keyboard[VK_SHIFT] & HIGH_BIT))
                  return true; // клавиша нажата вместе с клавишей shift

            // Здесь мы проверим, была ли клавиша нажата при включенной caps lock
            else if((keyboard[key] & HIGH_BIT) && (keyboard[VK_CAPITAL] & LOW_BIT))
                  return true; // клавиша нажата при включенной caps lock
      }            
      return false; // клавиша не нажата
}


// А вот список важных виртуальных кодов
// "Пропущенные" коды как правило зависят от оборудования, поэтому
// зайдите на сайт вашей клавиатуры или MSDN, если вам нужен полный
// список кодов

/*      
      Virtual Code      Hex Value                  "Key"
      ============      =========                  =====

       VK_LBUTTON                  01                  left mouse button  
       VK_RBUTTON                  02                  right mouse button  
       VK_CANCEL                  03                  control-break processing  
       VK_MBUTTON                  04                  middle mouse button (three-button mouse)  
 
       VK_BACK                  08                        backspace  
       VK_TAB                        09                        tab  
      
       VK_CLEAR                  0C                        clear  
       VK_RETURN                  0D                        enter  

       VK_SHIFT                  10                        shift  
       VK_CONTROL                  11                        ctrl   
       VK_MENU                  12                        alt 
       VK_PAUSE                  13                        pause   
       VK_CAPITAL                  14                        caps lock  

       VK_ESCAPE                  1B                        esc  
       VK_SPACE                  20                        spacebar  
       VK_PRIOR                  21                        page up   
       VK_NEXT                  22                        page down  
       VK_END                        23                        end key  
       VK_HOME                  24                        home key  
       VK_LEFT                  25                        left arrow  
       VK_UP                        26                        up arrow  
       VK_RIGHT                  27                        right arrow  
       VK_DOWN                  28                        down arrow  
       VK_SELECT                  29                        select key  

       VK_EXECUTE                  2B                        execute key  
       VK_SNAPSHOT            2C                        print screen key  
       VK_INSERT                  2D                        insert key  
       VK_DELETE                  2E                        delete key  
       VK_HELP                  2F                        help key  
       VK_0                        30                              0   
       VK_1                        31                              1   
       VK_2                        32                              2   
       VK_3                        33                              3   
       VK_4                        34                              4   
       VK_5                        35                              5   
       VK_6                        36                              6   
       VK_7                        37                              7   
       VK_8                        38                              8   
       VK_9                        39                              9   
                                                                  
       VK_A                        41                              a   
       VK_B                        42                              b   
       VK_C                        43                              c   
       VK_D                        44                              d   
       VK_E                        45                              e   
       VK_F                        46                              f   
       VK_G                        47                              g   
       VK_H                        48                              h   
       VK_I                        49                              i   
       VK_J                        4A                              j   
       VK_K                        4B                              k   
       VK_L                        4C                              l   
       VK_M                        4D                              m   
       VK_N                        4E                              n   
       VK_O                        4F                              o   
       VK_P                        50                              p   
       VK_Q                        51                              q   
       VK_R                        52                              r   
       VK_S                        53                              s   
       VK_T                        54                              t   
       VK_U                        55                              u   
       VK_V                        56                              v   
       VK_W                        57                              w   
       VK_X                        58                              x   
       VK_Y                        59                              y   
       VK_Z                        5A                              z   
        VK_NUMPAD0                  60                  Numeric keypad 0 key  
       VK_NUMPAD1                  61                  Numeric keypad 1 key  
       VK_NUMPAD2                  62                  Numeric keypad 2 key  
       VK_NUMPAD3                  63                  Numeric keypad 3 key  
       VK_NUMPAD4                  64                  Numeric keypad 4 key  
       VK_NUMPAD5                  65                  Numeric keypad 5 key  
       VK_NUMPAD6                  66                  Numeric keypad 6 key  
       VK_NUMPAD7                  67                  Numeric keypad 7 key  
       VK_NUMPAD8                  68                  Numeric keypad 8 key  
       VK_NUMPAD9                  69                  Numeric keypad 9 key  
       VK_MULTIPLY            6A                        Multiply key  
       VK_ADD                        6B                        Add key  
       VK_SEPARATOR            6C                        Separator key  
       VK_SUBTRACT            6D                        Subtract key  
       VK_DECIMAL                  6E                        Decimal key  
       VK_DIVIDE                  6F                        Divide key  
       VK_F1                        70                        f1 key  
       VK_F2                        71                        f2 key  
       VK_F3                        72                        f3 key  
       VK_F4                        73                        f4 key  
       VK_F5                        74                        f5 key  
       VK_F6                        75                        f6 key  
       VK_F7                        76                        f7 key  
       VK_F8                        77                        f8 key  
       VK_F9                        78                        f9 key  
       VK_F10                        79                        f10 key  
       VK_F11                        7A                        f11 key  
       VK_F12                        7B                        f12 key  
                
       VK_NUMLOCK                  90                  num lock key  
       VK_SCROLL                  91                  scroll lock key  
*/


// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com

Скачать обучалку (Visual C++ 6)

Ввод с клавиатуры | Все обучалки раздела | Ввод с помощью мыши

[Главная] [С чего начать?] [Дистанционное обучение] [Статьи] [Обучалки] [Книги] [Софт] [Форум] [Ссылки] [О сайте]

Copyright © 2003-2005 Евгений Казеко. Все права защищены. E-mail: evgeniy@kazeko.com

банкоматы русский стандарт в воронеже , интернет магазин норковых шуб , Сетка сварная оцинкованная Снабжение - товары Главный способ контроля соблюдения...