Тема: рух об’єктів: використання таймера, рух, моделювання гри мовою C++.
Мета:
Обладнання: комп'ютери зі встановленими ОС, браузером, середовищем CodeBlocks для програмування мовою С++ з використанням бібліотеки wxWidgets, (дана) інструкція.
Структура уроку
Хід уроку
1. Організаційний момент
Вітання з класом. Перевірка присутності і готовності учнів до уроку. Перевірка виконання домашнього завдання.
2. Актуалізація опорних знань
Протлумачити дію вказівок мовою С++
wxString s=wxT(""); s=TextCtrl1->GetValue(); s.ToDouble(&a); wxMessageDialog *d = new wxMessageDialog(NULL,wxT("Щось…"), wxT("Десь…"),wxOK); d->ShowModal(); wxPaintDC z(Panel1); z.SetBrush(wxColor(150,200,255)); z.SetPen(wxPen(wxColor(150,200,255),1)); z.DrawRectangle(x,y,a,b); z.DrawCircle(wxPoint(x,y),r); z.DrawBitmap(wxBitmap(wxT("b.png"),wxBITMAP_TYPE_PNG),x,y,true);
і порівняти з очікуваними відповідями:
wxString s=wxT("");
— ініціалізація порожнього рядка wxWidgets;
s=TextCtrl1->GetValue();
— зчитування даних з поля TextCtrl1 у рядок s;
s.ToDouble(&a);
— перетворення значення рядка s у значення десяткового дробу a;
d->ShowModal();
— виведення (модального) вікна d;
z.SetBrush(wxColor(150,200,255));
— встановлення (блакитного) кольору заповнення (150, 200, 255) моделі RGB;
z.SetPen(wxPen(wxColor(150,200,255),1));
— встановлення кольору (150, 200, 255) для контура ширини 1 піксель;
z.DrawRectangle(x,y,a,b);
— зображення прямокутника розміру a × b з лівим верхнім кутом у точці (x, y);
z.DrawCircle(wxPoint(x,y),r);
— зображення круга з центром (x, y ) і радіусом r;
z.DrawBitmap(wxBitmap(wxT("b.png"),wxBITMAP_TYPE_PNG),x,y,true);
— виведення зображення з файлу b.png поточної теки у прямокутник, лівий верхній кут якого — у точці (x, y).
3. Вивчення нового матеріалу
Таймер-планувальник — вбудований засіб бібліотеки wxWidgets зі вкладення Tools, що задає виклик функції OnTimer*Trigger через проміжок часу, вказаний розробником з точністю до мілісекунди.
У назві функції OnTimer*Trigger — обробника події звернення до таймера — замість зірочки буде записано номер таймера у порядку його встановлення на форму. Таймер, на відміну від циклу, дозволяє виконувати певні дії декілька разів, дозволяючи виконувати інші дії у проміжках між зверненнями таймера.
4. Інструктаж з ТБ
5. Вироблення практичних навичок
Завдання. Створити комп'ютерну програму мовою С++ для гри «Гармата». Мета гри: для даних розташування цілі й початкової швидкості підібрати кут запуску ядра для ураження цілі.
Математична модель. Для зручності програмного втілення систему координат доцільно вибрати таким чином:
Вважати, що рух тіла є рівномірним по горизонталі і зі сталим прискоренням по вертикалі при нехтуванні опором повітря. Інакше кажучи, вважати, що координати центра ядра залежать від часу t таким чином:
x = x0 + v0x · t,
y = y0 + v0y · t + g · t2/2.
Тут:
При виконанні завдання використати конкурс ідей і порівнювати з демонстраційним розв'язанням (для перегляду здійснювати перехід за гіперпосиланням).
Вказівки до виконання завдання:
У середовищі CodeBlocks у вказаній учителем теці створити проєкт game з використанням бібліотеки wxWidgets з такими параметрами:
Видалити об'єкти: MenuBar1 і StatusBar1, виділивши їхні зображення (клацнувши на них лівою кнопкою миші) над зображенням форми і натиснувши клавішу Delete.
Надати властивостям форми значення (тут і нижче у тексті вказано лише ті властивості, значення яких потрібно змінити):
розташувавши на формі об'єкти з вкладення Standard (Стандартне):
wxStaticText — 3 написи з такими значеннями властивостей:
Label | Target coordinates | Angle | Velosity |
X | 1 | 140 | 220 |
Y | 4 | 10 | 10 |
Width | 68 | 36 | 45 |
Height | 36 | 24 | 24 |
Text | 33 | 33 | 45 | 88 |
X | 70 | 100 | 180 | 270 |
Y | 6 | 6 | 6 | 6 |
Width | 30 | 30 | 24 | 70 |
Height | 24 | 24 | 24 | 240 |
Label | Fire! |
X | 360 |
Y | 6 |
Width | 36 |
Height | 24 |
wxPanel — панель з такими значеннями властивостей:
X | 0 |
Y | 50 |
Width | 800 |
Height | 400 |
Background | (150,200,255) |
Щоб змінити значення Вackground (кольору тла), потрібно клацнути лівою кнопкою миші праворуч від початкового значення, з випадного списку вибрати Custom
у вікні діалогу Choose color задати координати кольору схеми RGB і на натиснути кнопку Гаразд.
Custom — користувацький віджет (покласти на панель) з такими значеннями властивостей:
Creating code | $(THIS) = new $(CLASS)($(PARENT)); |
Include file | wx/dcclient.h |
Var name | z |
Class name | wxPaintDC |
X | 0 |
Y | 0 |
Width | 800 |
Height | 400 |
Щоб змінити значення Creating code (коду породження), потрібно клацнути лівою кнопкою миші праворуч від відповідного значення
і у вікні діалогу Creating code вилучити зайві символи, після чого натиснути на кнопку Гаразд.
Створити обробник події натискання кнопки з написом Fire! (Вогонь!):
виділити кнопку з написом Fire!, клацнувши на ній лівою кнопкою миші, і перейти до розгляду подій, натиснувши кнопку із зображенням фігурних дужок {};
навести вказівник миші на рядок з написом None (Жодного) праворуч від напису EVT_BUTTON, клацнути лівою кнопкою миші і з випадного меню вибрати Add new handler (Додати новий обробник);
у вікні діалогу New handler (Новий обробник) підтвердити створення обробника OnButton1Click події натискання кнопки Button1, натиснувши кнопку Гаразд.
Виставити на панель таймер з вкладення Tools і виставити проміжок між вмиканнями 50 мілісекунд, що відповідає частоті 20 кадрів на секунду.
Створити обробник події вмикання таймера:
виділити таймер, клацнувши на ній лівою кнопкою миші, і перейти до розгляду подій, натиснувши кнопку із зображенням фігурних дужок {};
навести вказівник миші на рядок з написом None (Жодного) праворуч від напису EVT_BUTTON, клацнути лівою кнопкою миші і з випадного меню вибрати Add new handler (Додати новий обробник);
підтвердити створення події OnTimer1Trigger вмикання таймера, натиснувши кнопку з написом Гаразд у вікні діалогу New hadler (Новий обробник);
Описати глобальні змінні:
bool b=true; double a, v0, v0x, v0y, x_1=-10, y_1=-10, x, y, t, dt=0.05, g=9.8, x_0=0, y_0=400;з таким тлумаченням:
Описати функцію OnButton1Click коду minerMain.cpp — обробник події натискання на кнопку з написом Fire!, що містить таке:
(0<x1) && (x1<800) && (0<y1) && (y1<400) && (0<a) && (a<90) && (0<v0) && (v0<900)здійснення такого:
перехід до радіанної міри кута нахилу;
обчислення складових початкової швидкості по горизонталі й по вертикалі;
надання значення t = 0; b=true;
Інакше — при хибності виразу — виведення вікна діалогу з таким повідомленням: "Хибні параметри: абсциса цілі має бути у межах від 0 до 800, ординати цілі — від 0 до 400, кут нахилу гармати — від 0 до 90, початкова швидкість — від 0 до 900."
Порівняти створене з очікуваним.
Описати функцію OnTimer1Trigger коду minerMain.cpp — обробник події вмикання таймера, що при справдженні b передбачає таке:
заповнення об'єкта для малювання блакитним кольором — (150, 200, 255) у моделі RGB;
зображення цілі — круга червогого кольору з радіусом 4 пікселів і центром з координатами x1, y1;
обчислення поточних координат ядра;
зображення ядра кругом чорного кольору з радіусом 4;
якщо відстань між центрами ядра й цілі менша від суми їхніх радіусів — виведення такого зображення
і надання значення b=false;
при виході центра ядра за межі зображуваного прямокутника [0;800]×[0;400] — надання значення b=false;
збільшення поточного значення часу t на dt;
Порівняти створене з очікуваним.
Повідомити вчителя про завершення роботи над проектом.
6. Підбиття підсумків уроку
Обговорення проблем виконання завдання. Виставлення оцінок.
7. Домашнє завдання
У разі потреби доробити завдання. Удосконалити проект, передбачивши можливість врахування сили опору повітря, що дорівнює добутку значення деякої сталої γ (передбачити введення її додатного значення з нового поля введення на формі) і швидкості руху ядра, але спрямована протилежно до напрямку цієї швидкості. Використати такі співвідношення:
x = x0 + vx0 · (1 − e − γt ) · γ − 1,
y = y0 + (vy0 · (1 − e − γt ) + gt ) · γ − 1 +
(e − γt − 1) · g · γ − 2.
Ці рівняння можна отримати, розв'язавши систему диференціальних рівнянь:
x' = vx ,
y' = vy ,
(vx)' = − γ · vx ,
(vy)' = − γ · vy + g
з такими початковими значеннями:
x(0) = x0 ,
y(0) = y0 ,
vx(0) = vx0 ,
vy(0) = vy0 .
Теорію диференціальних рівнянь вивчають у вищій школі, тому виведення рівнянь тут не подано.
Текст упорядкував Олександр Рудик.