Розробка уроку — практичної роботи

Тема: створення комп’ютерної гри з двома об’єктами, управління одним з яких здійснює людина, а управління іншими здійснюється автоматично за допомогою комп’ютера мовою програмування C++.

Мета: сформувати предметні компетенції щодо технологій імітації руху та моделювання гри.

Учень повинен пояснювати:

Учень повинен вміти:

Обладнання: комп'ютери зі встановленими ОС, браузером, середовищем CodeBlocks для програмування мовою С++ з використанням бібліотеки wxWidgets, (дана) інструкція.

Структура уроку

  1. Організаційний момент.
  2. Актуалізація опорних знань.
  3. Інструктаж з ТБ.
  4. Вироблення практичних навичок.
  5. Підбиття підсумків уроку.
  6. Домашнє завдання.

Хід уроку
1. Організаційний момент
Вітання з класом. Перевірка присутності і готовності учнів до уроку. Перевірка виконання домашнього завдання.

2. Актуалізація опорних знань

Протлумачити дію вказівок мовою С++

srand(time(NULL));
return rand()%N;
wxPaintDC z(Panel1);
z.SetBrush(wxColor(255,0,0));
z.SetPen(wxPen(wxColor(255,0,0),1));
z.DrawRectangle(x,y,W,H);
z.DrawCircle(wxPoint(x,y),r);
wxFont font1(14,wxFONTFAMILY_DEFAULT,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,"Ubuntu Calibri");
z.SetFont(font1); 
z.SetTextForeground(wxColor(255,0,0));
z.SetBackgroundMode(wxTRANSPARENT);
wxString s=wxT("");

і порівняти з очікуваними відповідями.

3. Вивчення нового матеріалу

Події від клавіатури подано класом wxKeyEvent. У бібліотеці wxWidgets є такі типи повідомлень:

Макроси подій wxKeyEvent

Якщо натиснути на клавішу і через певний час її відпустити, то, як правило, буде породжено багато подій натискання і лише одна — відпускання.

Щоб отримувати події від клавіатури, вікно програми має перебувати у фокусі. Його можна примусово отримати, викликавши метод wxWindow :: SetFocus. Наприклад, після натискання клавіші миші.

Для отримання коду ASCII введеного символа використовують функцію GetKeyCode. Для отримання введеного символа у кодуванні Unicode використовують GetUnicodeKey.

Для перевірки, чи було натиснуто певну клавішу-модифікатор, використовують функції AltDown, MetaDown, ControlDown або ShiftDown. Функція HasModifiers повертає значення true, якщо клавішу Control або Alt було натиснуто під час породження повідомлення про натискання / відпускання клавіші (але не Shift або Meta).

Замість використання функцій ControlDown або MetaDown краще використовувати CmdDown, яка викликає MetaDown на Mac OS X і ControlDown на інших платформах.

Функція GetPosition повертає позицію покажчика миші в координатах клієнтської області під час отримання відповідних подій.

Примітка. Якщо подію натискання клавіші захоплено, а її обробник не викликав метод event.Skip, то цю подію не буде передано наступним обробникам. Якщо не викликано event.Skip для подій, які не опрацьовано, то на деяких платформах можуть перестати працювати гарячі клавіші.

Не перетворюваний код натискання або відпускання для алфавітно-цифрової клавіші завжди відповідає значенню верхнього регістра. Для решти клавіш це значення виду WXK_XXX з таблиці кодів символів. Наприклад, якщо натиснути клавішу А (латиниця), то код події натискання дорівнює коду А з таблиці ASCII (65), але код події введення — символу а в ASCII (97). Але, якщо натиснуто А + Shift, код події натискання як і раніше буде А, в той час як код клавіші події введення символу тепер також стане А. З іншого боку, при натисканні клавіш Ctrl + А подія натискання передає код А, але подія введення символу матиме код 1.

Завдання 1 (для учителя при наявності проектора у класі, інакше — для учнів). Вибірково дослідити роботу клавіш, запустивши приклад wxWidgets*/samples/keyboard і понатискавши різні клавіші. Код аналізувати не потрібно.

Після натискання й відпускання клавіш у такій послідовності: A, Shift + A, Ctrl + A, ↓, ↑ можна отримати такий результат.

Клавіші-модифікатори в ОС Windows — це Control і Alt, а також клавіша Windows, яка працює як Meta. В ОС Linux, клавішу, що працює як Meta, налаштовують. Щоб дізнатися, як налаштовано систему, достатньо використати утиліту xmodmap і отримати щось, схоже на таке.

Якщо клавішу NumLock налаштовано як Meta, функція HasModifiers не повертає значення true при утриманої клавіші Meta при нормальному опрацюванні натискання клавіш з включеним NumLock.

У Mac OS X клавіша Command (з символом Apple) виконує функції Meta, а Option — функції Alt. При Mac OS X клавішу Command використовують з тією самою метою, що й Control на інших платформах, тому можна використовувати функцію CmdDown об'єкта wxKeyEvent замість ControlDown або MetaDown.

Перевірка того, чи натиснуто клавішу в обробнику події, породженою не клавіатурою — за допомогою функції wxGetKeyState, що набуває булевоого значення і аргументом якої є назва клавіші — див. перелік в алфавітному порядку. Це використовують, наприклад, при програмуванні гри з використанням таймера в обробнику породженої ним події, як у поданому далі завданні 3.

4. Інструктаж з ТБ
5. Вироблення практичних навичок


Завдання 2. Cтворити проєкт, який повідомлятиме код ASCII введеного символа і сам введений символ, виводячи рядок wxString s за допомогою функції wxMessageBox(s).

Тут перші два повідомлення отримано при українській розкладці клавіатури, третє — при російській, останні два — при англійській.

Вказівки до виконання завдання

  1. У середовищі CodeBlocks у вказаній учителем теці створити проєкт key з використанням бібліотеки wxWidgets з такими параметрами:

    • Prefered GUI — Builders;
    • Application Type — Frame Based.
  2. Видалити об'єкти: MenuBar1 і StatusBar1, виділивши їхні зображення (клацнувши на них лівою кнопкою миші) над зображенням форми і натиснувши клавішу Delete.

  3. Надати властивості Title форми значення Press any key.

  4. Розташувати на формі панель wxPanel з вкладення Standard (Стандартне).

  5. Створити обробник подій введеня символа EVT_CHAR:

    • виділити панель;
    • натиснути кнопку з фігурними дужками {};
    • серед подій вибрати EVT_CHAR;
    • натиснути кнопку праворуч;
    • вибрати Add new handler (Додати новий обробник);

    • підтвердити створення обробника OnPanel1Char, натиснувши кнопку з написом Гаразд.

  6. Створити обробник події введення символа OnPanel1Char у коді keyMain.cpp і порівняти з очікуваним.

  7. Перевірити правильність виконання проекту. Для цього на панелі інструментів середовища CodeBlocks натиснути (у вказаному порядку) такі кнопки:

    Save all files (Зберегти всі файли);
    Build (Побудувати);
    Run (Запустити).

    Замість натискання двох останніх кнопок можна натиснути одну:

    Build and run (Побудувати і запустити).

    У разі потреби внести зміни у код програми.

  8. Повідомити вчителя про завершення роботи над проектом.

Завдання 3. Cтворити гру Пінг-Понг з відбиванням м'яча від бокових меж ігрового поля, у якій однією ракеткою (червоного кольору) керує людина, а іншою (жовтого кольору) — програма.

Вказівки до виконання завдання
(словесний опис кроків 8−10 бажано отримати конкурсом ідей)

  1. У середовищі CodeBlocks у вказаній учителем теці створити проєкт PingPong з використанням бібліотеки wxWidgets з такими параметрами:

    • Prefered GUI — Builders;
    • Application Type — Frame Based.
  2. Видалити об'єкти: MenuBar1 і StatusBar1, виділивши їхні зображення (клацнувши на них лівою кнопкою миші) над зображенням форми і натиснувши клавішу Delete.

  3. Надати властивостям форми значення (тут і нижче у тексті вказано лише ті властивості, значення яких потрібно змінити):

    • Title — Ping Pong;
    • Width — 780;
    • Height — 400.
  4. Розташувати на формі панель wxPanel з вкладення Standard (Стандартне) з такими значеннями властивостей:

    X0
    Y0
    Width 780
    Height400
  5. Розташувати на панелі користувацький віджет Custom з такими значеннями властивостей:

  6. Creating code$(THIS) = new $(CLASS)($(PARENT));
    Include filewx/dcclient.h
    Var namez
    Class namewxPaintDC
    X0
    Y0
    Width 780
    Height400

    Щоб змінити значення Creating code (коду породження), потрібно клацнути лівою кнопкою миші праворуч від відповідного значення

    і у вікні діалогу Creating code вилучити зайві символи, після чого натиснути на кнопку Гаразд.

  7. Виставити на панель таймер з вкладення Tools і виставити проміжок між вмиканнями 50 мілісекунд, що відповідає частоті 20 кадрів на секунду.

  8. Створити обробник події вмикання таймера:

    • виділити таймер, клацнувши на ній лівою кнопкою миші, і перейти до розгляду подій, натиснувши кнопку із зображенням фігурних дужок {};

    • навести вказівник миші на рядок з написом None (Жодного) праворуч від напису EVT_BUTTON, клацнути лівою кнопкою миші і з випадного меню вибрати Add new handler (Додати новий обробник);

    • підтвердити створення події OnTimer1Trigger вмикання таймера, натиснувши кнопку з написом Гаразд у вікні діалогу New hadler (Новий обробник);

  9. Описати глобальні змінні — параметри математичної моделі гри:

    int j=0,  t[2]={0,0},  H=400,  W=780,  r=8,  w=5,  h=50,
        yy=0,  yr=0,  dyr=8,  xr=W-w,  Nx=50,  Ny=20;
    double x,y,dx,dy, dxmin=15, dxmax=20, dymax=10;
    wxString s;
    з таким тлумаченням:
    • j — стан гри з таким тлумаченням значення:
      • 0 — початок руху ліворуч;
      • 1 — продовження руху ліворуч;
      • 2 — початок руху праворуч;
      • 3 — продовження руху праворуч.
    • t0 — рахунок комп'ютера — кількість ударів, пропущених гравцем;
    • t1 — рахунок гравця — кількість ударів, пропущених комп'ютером;
    • H — висота ігрового поля;
    • W — ширина ігрового поля;
    • r — радіус білого круга;
    • w — ширина прямокутника — зображення ракетки;
    • h — висота прямокутника — зображення ракетки;
    • yy — ордината ВЛК жовтого прямокутника — зображення ракетки;
    • yr — ордината ВЛК червоного прямокутника — зображення ракетки;
    • dyr — приріст yr між вмиканнями таймера;
    • xr — абсциса ВЛК червоного прямокутника — зображення ракетки;
    • Nx — кількість дробів, з яких буде вибрано dx;
    • Ny — половина кількості дробів, з яких буде вибрано dy;
    • x — абсциса центра білого круга;
    • y — ордината центра білого круга;
    • dx — приріст x між вмиканнями таймера;
    • dy — приріст y між вмиканнями таймера;
    • dxmin — нижня межа абсолютної величини (модуля) dx;
    • dxmax — верхня межа абсолютної величини (модуля) dx;
    • dymax — верхня межа абсолютної величини (модуля) dу;
    • s — рахунок у форматі рядка wxString для виведення на екран монітора.
  10. Програмно втілити математичну модель гри у тілі функції OnTimer1Trigger коду PingPongMain.cpp — обробника події вмикання таймера, передбачивши таке:

    • якщо j дорівнює 1 або 3 (рух після подачі):

      • зміна yr — ординати ВЛК червоного прямокутника:
        • при натиснутій клавіші ↓ — на min(yr + dyr , H − h);
        • при натиснутій клавіші ↑ — на max(yr − dyr , 0);
      • зміна yy — ординати ВЛК жовтого прямокутника — таким чином, щоб його центр мав ту саму ординату, що й центр білого круга, якщо це можливо. Інакше кажучи:

        • при y < h/2 маємо: yy = 0;
        • при y + h/2 > H маємо: yy = Hh;
        • в усіх інших випадках маємо: yy = y

        — «ракетка» комп'ютера відстежує рух «м'яча» із запізненням час між вмиканнями таймера;

      • при виході частини білого круга за горизонтальні межі ігрового поля — зміна ординати його центра таким чином, ніби до цього відбувся пружний удар об горизонтальну межу, протягом якого dy — приріст ординати між вмиканнями таймера — змінив значення на протилежне;

      • при виході частини білого круга за вертикальні межі ігрового поля у тій частині, що перекрита жовтим чи червоним прямокутником (зображенням ракетки), — зміна абсциси його центра таким чином, ніби до цього відбувся пружний удар об ракетку, протягом якого dx — приріст абсциси між вмиканнями таймера — змінив значення на протилежне;

      • при виході частини білого круга за вертикальні межі ігрового поля відповідна зміна рахунку і зменшення значення змінної j на 1;

    • якщо j дорівнює 0 або 2 (подача) — надання значень:
      • x = xr − r при j = 0, інакше x = w + r;
      • y = H/2;
      • yy = H − h/2;
      • yr = H − h/2;
      • dx — випадковий дріб, що задовольняє такі умови:
        • dxmin ≤ |dx | ≤ dxmax;
        • dx < 0 при j = 0;
        • dx > 0 при j = 2;
      • dy — випадковий дріб, у межах від − dxmax до dxmax
      і збільшення значення змінної j на 1.

    Порівняти створене з очікуваним.

  11. Програмно втілити унаочнення процесу гри наприкінці тіла функції OnTimer1Trigger коду PingPongMain.cpp — обробника події вмикання таймера, передбачивши таке:

    • опис об'єкта для малювання;

    • заповнення об'єкта для малювання темно зеленим кольором — (0, 128, 0) моделі RGB;

    • зображення лінія поділу ігрового поля на половини і меж поля — вертикальних ліній білого кольору товщини 1 піксель;

    • зображення об'єктів для поточного стану гри:

      • числа рахунку гри — білим кольором;
      • прямокутники жовтого та червоного кольорів;
      • круг білого кольору;

    Порівняти створене з очікуваним.

  12. Перевірити правильність виконання проекту. Для цього на панелі інструментів середовища CodeBlocks натиснути (у вказаному порядку) такі кнопки:

    Save all files (Зберегти всі файли);
    Build (Побудувати);
    Run (Запустити).

    Замість натискання двох останніх кнопок можна натиснути одну:

    Build and run (Побудувати і запустити).

    У разі потреби внести зміни у код програми. Перевірити коректність ведення рахунку гри при закоментованих вказівках щодо руху жовтого прямокутника.

  13. Повідомити вчителя про завершення роботи над проектом.

6. Підбиття підсумків уроку
Обговорення проблем виконання завдання. Виставлення оцінок.

7. Домашнє завдання

У разі потреби доробити завдання. Удосконалити проект (достатньо одним з перелічених нижче шляхів):


Текст упорядкував Олександр Рудик.