Базовый курс С++
Добро пожаловать на Базовый курс программирования на С++, созданный программистом Александром Семенко, который уже более 20 лет работает программистом на различных проектах. Этот курс рассчитан на новичка, который делает свои первые шаги в программировании. Здесь мы изучаем на практике как писать программу на языке С++ в операционной системе Windows, используя среду программирования Visual Studio.
На этом курсе мы не просто изучаем особенности языка - мы активно применяем их для того, чтобы написать простую компьютерную игру. Такая игра нам нужна в качестве точки приложения наших знаний, а так же как источник множества практических заданий, решая которые вы сможете научиться программировать гораздо эффективнее, чем просто изучая особенности языка.
Весь курс состоит из 95 частей, по окончании которого вы сможете считать себя C++ Junior-Developer, т.е. начинающим С++ разработчиком (но только, если вы сами следовали по курсу и писали код сами).
Оглавление
- Все части в плейлисте: https://www.youtube.com/playlist?list=PLlheCABZdy3OZoIh9VwlYUbTSCWwDUee6
- Устанавливаем инструменты разработчика - программы, которые помогают нам писать программы.
- 00:00 - Инструменты разработчика
- 02:02 - Устанавливаем Хром (Google Chrome)
- 02:43 - Устанавливаем Double Commander
- 04:03 - Создаём каталог Downloads
- 04:26 - Что такое "Среда Разработки"
- 05:44 - Устанавливаем Visual Studio
- 08:24 - Логинимся в Visual Studio
- 09:09 - Настраиваем Visual Studio
- 11:02 - Установка видеоплейера VLC
- 11:36 - Устанавливаем Meld
- 12:54 - Устанавливаем DOSBox
- 13:36 - Устанавливаем ActivePresenter
- Как работать с файловым менеджером Double Commander.
- 00:00 - Double Commander
- 03:31 - Double Commander
- 04:18 - Панели
- 04:35 - Переходы по каталогам
- 05:47 - F3 - просмотр файла
- 06:23 - F4 - редактирование файла
- 06:42 - F7 - создание каталога
- 07:21 - F8 - удаление файлов и каталогов
- 09:06 - Shift+F4 - создание файла
- 09:35 - F5 - копирование файлов и каталогов
- 10:34 - F6 - перемещение и переименование
- 11:14 - Выделение группы файлов
- 12:36 - Поле ввода команд
- 12:58 - Запуск программы с параметром
- 14:31 - Сортировка файлов
- 15:13 - Вкладки
- Как выбрать свой первый проект.
- Ссылка на файл popcorn.zip: https://drive.google.com/file/d/1rTZy2xEh8GaSqGUSjwHhNSROV2ken4p7
- Как работают программисты.
- Начинаем разработку прототипа нашей игры.
- Знакомство с Visual Studio и справочником MSDN.
- 00:00 - Прототип 01
- 02:33 - Создаём проект в Visual Studio
- 04:52 - Компилируем проект (клавиша F7)
- 06:06 - Запуск программы (клавиша F5)
- 06:52 - Обзор шаблонного проекта
- 07:46 - Оконная процедура
- 08:22 - Сообщения Windows
- 10:47 - Что такое программа
- 11:50 - Структура нашего проекта
- 14:45 - Настройка эмулятора DOSBox
- 18:28 - Захват видео программой ActivePresenter
- 25:21 - Получаем кадр из видео
- 28:47 - Начинаем делать прототип игры
- 29:24 - Задаём цвет фона окна
- 32:52 - Ищем описание функции CreateSolidBrush() в справочнике MSDN
- 36:30 - Макрос RGB
- 37:05 - Тип данных HBRUSH
- 37:53 - Типы данных и архитектура Windows
- 42:30 - Задаём размер окна
- 46:42 - Корректируем размеры клиентской области функцией AdjustWindowRect()
- 1:00:20 - Добавляем функцию Draw_Frame() для отрисовки кадра игры
- 1:04:20 - Стиль оформления нашего кода
- 1:06:56 - Как мы пишем комментарии
- 1:08:04 - Как сохранять файл с не-английским содержимым
- 1:10:08 - Как скачать архив с проектом: https://drive.google.com/open?id=1U5b...
- 1:10:17 - Как распаковать архив с проектом
- 1:11:34 - Как открыть наш проект в Visual Studio
- Popcorn_Project.zip - https://drive.google.com/file/d/1U5bdRcv8k1gmgKTpa40FSpxWXY0V2m0R
- 00:00 - Прототип 02
- 02:23 - Два вида графики - растровая и векторная
- 03:57 - Вывод прямоугольника функцией Rectangle()
- 10:05 - Call Stack в Visual Studio
- 13:21 - Функция Rectangle() в справочнике MSDN
- 16:30 - Создаём карандаш функцией CreatePen()
- 20:49 - Выбираем карандаш функцией SelectObject()
- 21:29 - Создаём кисть функцией CreateSolidBrush()
- 23:10 - Выводим второй кирпич
- 26:27 - Выносим повторяющийся код в функцию Draw_Brick()
- 32:09 - Рефакторинг функции Draw_Brick()
- 35:09 - Вводим именованные константы
- 38:02 - Выводим в цикле 2 ряда кирпичей
- 41:43 - Заполняем всё игровое поле кирпичами
- 46:35 - Создаём текущий "срез" проекта в каталоге Backup
- 51:58 - Сравнение и слияние (мердж) двух версий проекта
- Popcorn_01.zip - https://drive.google.com/file/d/1cJvmN3isnNvf9BuRfgg1t09p1cvILofG
- 00:00 - Прототип 03
- 01:17 - Объявляем массив для описания уровня
- 06:14 - Выводим кирпичи уровня
- 08:25 - Исправляем функцию Draw_Brick() для вывода 3-х типов кирпичей
- 09:39 - Используем оператор switch/case вместо if
- 12:25 - "Magic numbers" ("магические" числа) в программе
- 13:01 - Создаём перечисление (enum) для типа кирпичей
- 19:35 - Рисуем прямоугольник со скруглёнными углами функцией RoundRect()
- 24:53 - Выносим код рисования кирпичей в функцию Draw_Level()
- 25:57 - Выносим код создания карандашей и кистей в функцию инициализации Init()
- 30:05 - Меняем цвет фона и кирпичей
- 33:03 - Ваша очередь писать код
- 33:40 - Как сравнить ваш код с очередным "срезом" проекта
- 37:07 - Popcorn_02.zip: делаем паузу, пишем код
- 37:48 - Предварительное объявление функций
- 39:20 - Рефакторим исходный файл, чтобы вынести код в другой файл
- 40:07 - Создаём фильтр Engine, а в нём - пару файлов Engine.cpp и Engine.h
- 43:02 - Переносим код из Main.cpp в Engine.cpp
- 47:25 - Popcorn_03.zip: делаем паузу, пишем код
- 47:41 - Как делать срез проекта
- 49:12 - Откатываю изменения проекта на предыдущий шаг
- 50:11 - Мерджим код (как сравнить ваш код с моим)
- Popcorn_02.zip - https://drive.google.com/file/d/1AY-FVwkB3UUcfRlh9RWmk6Ea9QfOIMvC
- Popcorn_03.zip - https://drive.google.com/file/d/12M3WEMnorPuuESBvx8q8u1Bs_KNrUxSV
- 00:00 - Прототип 04
- 02:27 - Рисуем платформу
- 04:22 - Рисуем шарик платформы функцией Ellipse()
- 10:08 - Рисуем второй шарик платформы
- 13:23 - Рисуем среднюю часть платформы
- 20:12 - Выносим код рисования в функцию Draw_Platform()
- 23:28 - Меняем цвета платформы
- 25:05 - Создаём кисти и карандаши для платформы
- 28:30 - Выносим код в функцию Create_Pen_Brush()
- 31:54 - Возврат множества значений из функции
- 36:25 - Рисуем блик на шарике функцией Arc()
- 45:25 - Создаём карандаш для рисования блика
- 48:31 - Popcorn_04.zip: пишем код
Popcorn_04.zip - https://drive.google.com/file/d/1qwtbHfbDWL4cS2CyD684ziVmjaxhrhAf
- 00:00 - Прототип 05
- 00:30 - Анализируем анимацию элемента игры
- 03:48 - Делаю раскадровку анимации
- 17:22 - Выводим падающую букву
- 21:13 - Трансформации и структура XFORM
- 22:36 - Примеры трансформаций
- 24:05 - Функция SetWorldTransform()
- 25:46 - Применяем трансформацию для поворота пространства
- 31:11 - Выносим код в функцию Draw_Brick_Letter()
- 32:15 - Поворачиваем пространство на произвольный угол
- 34:28 - Применяем функцию косинуса cos()
- 36:35 - Применяем функцию синуса sin()
- 38:47 - Поворачиваем букву разные углы
- 43:19 - Выводим каждый кадр кирпича отдельно
- 44:51 - Модифицируем матрицу поворота
- 47:02 - Смещаем центр поворота
- 50:46 - Рисуем обратную сторону буквы
- 53:29 - Динамически меняем толщину обратной стороны
- 57:37 - Функции для получения абсолютных значений abs() и fabs()
- 59:23 - Функция округления round()
- 01:01:19 - Рефакторим код для повышения читабельности
- 01:04:32 - Выводим букву в положении плашмя
- 01:11:27 - Popcorn_05.zip: пишем код
- 01:11:49 - Добавим тип кирпича, из которого выпала буква
- 01:14:14 - Добавим передний и задний фон буквы
- 01:18:45 - Выносим копипаст в функцию Set_Brick_Letter_Colors()
- 01:24:30 - Исправляем угол поворота буквы
- 01:30:16 - Рисуем саму букву
- 01:36:27 - Вводим тип буквы ELetter_Type
- Popcorn_05.zip - https://drive.google.com/file/d/1dXRMhJe2dmKM-QB6issaOfcRoo5VkDak
- Popcorn_06.zip - https://drive.google.com/file/d/1eEpEE2fPB0BTGsE-8vcjAu61PQz0xl-N
- 00:00 - Прототип 06
- 01:06 - Обработка нажатий клавиш
- 02:31 - Сообщение WM_KEYDOWN
- 05:34 - Пишем код обработки трёх клавиш
- 08:22 - Создаём функцию On_Key_Down()
- 10:00 - Вводим тип EKey_Type
- 13:47 - Обрабатываем нажатия клавиш
- 20:29 - Функция для перерисовки области окна InvalidateRect()
- 23:22 - Передаём хэндл окна через функцию Init_Engine()
- 25:18 - Пишем код функции Redraw_Platform()
- 30:04 - Очищаем область окна перед выводом платформы
- 31:18 - Создаём фоновую кисть и карандаш
- 34:15 - Описываем текущую и предыдущую области платформы
- 40:05 - Задаём минимальную позицию платформы
- 42:05 - Перерисовка той части окна, которая изменилась
- 43:05 - Функция BeginPaint()
- 44:19 - Передаём описание области рисования в функцию Draw_Frame()
- 45:37 - Функция IntersectRect()
- 48:47 - Выводим уровень только если нужно
- 54:14 - Popcorn_07.zip: пишем код
- Popcorn_07.zip - https://drive.google.com/file/d/11IjaxpdDvmhNoiEEag0yoixBobxRZTAm
- 00:00 - Прототип 07
- 00:58 - Установка таймера функцией SetTimer()
- 03:08 - Константа WM_USER
- 05:36 - Обработка сообщения WM_TIMER
- 07:48 - Добавляем функцию On_Timer()
- 11:55 - Рисуем шарик, разбивающий кирпичи
- 23:16 - Выносим код в функцию Draw_Ball()
- 24:00 - "Симметрия кода"
- 25:07 - Добавляем описание области шарика Ball_Rect
- 27:19 - Добавляем функцию Move_Ball()
- 30:26 - Исправляем движение шарика
- 34:12 - Задаём движение шарика углом и скоростью
- 36:15 - Что такое синус и косинус
- 39:08 - Применяем синус и косинус для движения шарика
- 40:53 - Делаем отражение шарика от стенок уровня
- 58:48 - Popcorn_08.zip: пишем код
- Popcorn_08.zip - https://drive.google.com/file/d/1ArJbECLdT4k1D3kYZ4EuMhfagdVOLIpl
- 00:00 - Прототип 08
- 01:12 - Рисуем рамку вокруг уровня
- 02:32 - Декомпозируем рамку на элементы
- 06:20 - Выводим элемент рамки
- 16:02 - Выводим левую сторону рамки
- 18:53 - Выводим правую сторону рамки
- 21:10 - Выносим код в функцию Draw_Bounds()
- 22:56 - Выводим верхнюю сторону рамки
- 28:40 - Ограничиваем рамкой перемещение платформы
- 35:44 - Epic Fail программиста
- 37:36 - Корректируем ограничение движения платформы
- 40:17 - Исправляем позиции отражения шарика
- 46:11 - Делаем отражение шарика от платформы
- 49:58 - Отражение шарика от кирпичей
- 54:16 - Исключение (exception) при выходе за пределы массива
- 55:20 - Выносим код в функцию Check_Level_Brick_Hit()
- 57:32 - Popcorn_09.zip: пишем код
- Popcorn_09.zip - https://drive.google.com/file/d/1kbA3do6LRgXI9eQv3-TbdA2x015Gee-6
- 00:00 - Классы в С++
- 01:27 - Обновляем Visual Studio
- 03:18 - Начинаем изучать классы в С++
- 04:38 - Глобальные функции и данные
- 05:29 - Создаём класс как коллекцию функций и данных
- 07:33 - Класс как сущность
- 11:17 - Класс как тип
- 12:12 - Экземпляры класса (объекты)
- 12:50 - Методы класса
- 15:03 - Что такое класс
- 16:02 - Особенность классов: представление данных и функций
- 17:52 - Особенность классов: объявление методов (функций класса)
- 19:05 - Особенность классов: секции доступа
- 19:34 - Публичная секция (public)
- 20:49 - Приватная секция (private)
- 24:04 - Зачем нужен прототип проекта
- 25:24 - Создаём класс нашего игрового движка - Engine
- 28:30 - Преобразовываем глобальные функции в методы класса
- 41:27 - Переносим прочие типы в заголовочный файл
- 43:06 - Переносим переменные и константы в класс
- 44:31 - Делаем константы статическими
- 46:52 - Статические члены данных
- 50:39 - Конструктор класса
- 52:05 - Переносим инициализацию переменных в конструктор
- 52:52 - Список инициализации
- 55:48 - Popcorn_10.zip: пишем код
- Popcorn_10.zip - https://drive.google.com/file/d/1VcucM1FN4EISGNZx5LNwQgTm58obUYzQ
- 00:00 - Рефакторинг сложного класса
- 01:42 - Форматирование ссылок и указателей
- 03:58 - Настройка выравнивания кода в Visual Studio
- 06:13 - Выносим сущность шарика в класс ABall
- 10:50 - Исправляем ошибки, разделяя сущности движка и шарика
- 29:15 - Указатель на себя this
- 33:44 - Переносим часть членов класса ABall в приватную секцию
- 35:53 - Popcorn_11.zip: пишем код
- 36:22 - Выносим сущность уровня в класс ALevel
- 55:07 - Рефакторим метод Init_Engine()
- 01:02:11 - Статический метод
- 01:05:21 - Popcorn_12.zip: пишем код
- 01:05:39 - Создаём функцию инициализации ABall::Init()
- 01:07:57 - Выносим сущность платформы в класс AsPlatform
- 01:29:33 - Рефакторим имена членов данных платформы
- 01:32:38 - Popcorn_13.zip: пишем код
- 01:32:50 - Выносим сущность рамки в класс AsBorder
- 01:40:26 - Рефакторим имена методов
- 01:43:00 - Подводим итог рефакторинга класса движка
- 01:43:46 - Popcorn_14.zip: пишем код
- Popcorn_11.zip https://drive.google.com/file/d/1eXtYryEBoauBjJXsL-tgI3G92smqqwzS
- Popcorn_12.zip https://drive.google.com/file/d/1txBSML3A1G6My_xdoqaYK6I7uEIBuAsF
- Popcorn_13.zip https://drive.google.com/file/d/1UfHvgeoV8hvOQfehlK0VU4mG56oMnWaV
- Popcorn_14.zip https://drive.google.com/file/d/17k7rLh-yEYs8HCAzkHAZSQOuS-iVRUfg
- 00:00 - Выносим классы в отдельные файлы
- 02:30 - Выносим класс AsBorder в отдельную пару файлов
- 02:54 - Создаём фильтр для пары файлов
- 05:02 - Добавляем пару файлов Border.cpp и Border.h
- 06:06 - Переносим код класса AsBorder в новую пару файлов
- 07:57 - Как получается циклическая зависимость файлов
- 10:27 - Избавляемся от циклической зависимости: заменяем типы
- 13:00 - Избавляемся от циклической зависимости: выносим члены в общий класс
- 16:27 - Переносим статический метод в другой класс
- 19:48 - Исправляем предупреждения (warnings)
- 33:05 - Popcorn_15.zip: пишем код
- 33:28 - Выносим класс ALevel в свою пару файлов
- 39:03 - Выносим класс AsConfig в свою пару файлов
- 41:21 - Зачем нужна директива #pragma once
- 43:51 - Popcorn_16.zip: пишем код
- 44:04 - Выносим класс ABall в свою пару файлов
- 50:13 - Переносим общие константы из классов в AsConfig
- 59:47 - Popcorn_17.zip: пишем код
- 59:59 - Выносим класс AsPlatform в свою пару файлов
- 01:04:22 - Проверяем порядок следования методов в *.h и *.cpp
- 01:07:31 - Сохраняем все исходные файлы в формате Юникода
- 01:10:41 - Popcorn_18.zip: пишем код
- Popcorn_15.zip https://drive.google.com/file/d/1wv-FJwiWcKF_mhlRi8ACt5AwkL7vUB7Z
- Popcorn_16.zip https://drive.google.com/file/d/1Wbc2ai6o9cusZ3k9iQdYjye1APbY5xAH
- Popcorn_17.zip https://drive.google.com/file/d/1x6UM5NEjoQ4ZLxUiBszeji6QCW3aIBDI
- Popcorn_18.zip https://drive.google.com/file/d/1NZMXjG1-nsejkMcymrRRzQYqAHnyfjHh
- Все части в плейлисте : https://www.youtube.com/playlist?list...
- 00:00 - Анимация активного кирпича, этап 1
- 00:34 - Исправляем форматирование в Main.cpp
- 02:59 - Исправляем параметры функции wWinMain()
- 04:43 - Корректируем функцию WndProc()
- 05:50 - Переносим массив Level_01 в класс ALevel
- 07:17 - Исправляем имя константы Y_Pos
- 08:45 - Переносим в приватную секцию члены данных класса AsEngine и ABall
- 10:27 - Инкапсуляция, как один из трёх главных принципов ООП
- 12:45 - Определение инкапсуляции
- 13:51 - Выбираем в оригинальной игре следующую фичу, которую мы воспроизведём
- 17:49 - Начинаем рисовать полутоновый кирпич
- 21:41 - Создаём кисть и карандаш
- 24:49 - Создаём формулу изменения оттенка
- 26:50 - Особенности целочисленной арифметики
- 28:25 - Создаём новый оттенок на каждый кадр
- 32:44 - Выносим код рисования угасающего кирпича в метод нового класса AActive_Brick
- 38:46 - Привязываем анимацию к таймеру
- 45:12 - Ограничиваем шаги угасания
- 46:25 - Вводим константу FPS
- 48:08 - Выносим класс AActive_Brick в отдельную пару файлов
- 52:23 - Popcorn_19.zip: пишем код
- Popcorn_19.zip - https://drive.google.com/file/d/1eDopDzN2IU9C2taxV31tk2ORVK05QttI
- 00:00 - Анимация активного кирпича, этап 2
- 01:52 - Выносим компоненты цвета в конфиг
- 04:23 - Инкапсулируем компоненты цвета в класс AColor
- 11:07 - Передаём ссылку на объект цвета вместо компонентов R,G,B
- 12:57 - Перегруженные функции
- 15:23 - Используем цвет AColor для создания полутоновых оттенков
- 18:01 - Делаем выбор полутоновых кистей и карандашей из массива
- 23:06 - Создаём статические массивы карандашей и кистей
- 26:24 - Задаём полутоновые цвета в методе Setup_Colors()
- 30:55 - Добавляем тип активного кирпича
- 32:43 - Выводим угасание активного кирпича
- 35:05 - Исправляем угасание - не до чёрного, а до фонового цвета
- 37:12 - Добавляем константу фонового цвета BG_Color
- 39:51 - Исправляем вывод последнего шага угасания
- 41:27 - Ставим условную контрольную точку для отладки угасания
- 46:22 - Создаём метод AsConfig::Setup_Colors()
- 48:47 - Выносим фоновую кисть и карандаш в конфиг
- 50:20 - Убираем лишние параметры из методов Draw()
- 54:46 - Выносим код в метод Get_Fading_Channel()
- 58:59 - Выносим код в метод Get_Fading_Color()
- 01:05:28 - Popcorn_20.zip: пишем код
- Popcorn_20.zip - https://drive.google.com/file/d/14TPFdy97yT4uA2AL7humSCQllozNQH5m
- 00:00 - Пишем план разработки программы
- 00:41 - Два подхода к разработке программ: любительский и профессиональный
- 02:22 - Что такое план разработки
- 03:00 - 2 начальника в команде
- 04:24 - Для кого мы пишем код
- 05:34 - Начинаем писать наш план, анализируя оригинальную игру
- 26:03 - Выбираем способ получения информации о кирпичах и уровнях
- 27:18 - Смотрим документацию по игре в интернете
- 29:33 - Запускаем игру в DOSBox
- 32:05 - Делаем видеозахват 4-го уровня
- 36:33 - Записываем демо 6-го и 22-го уровней
- 38:24 - Ищем потерянный видеофайл
- 40:22 - Записываем демо 7-го уровня
- 42:44 - Записываем демо 3-го уровня
- 44:10 - Записываем демо 9-го и 10-го уровней
- 45:35 - Записываем демо 5-го уровня
- 47:17 - Записываем демо 8-го уровня
- 49:14 - Дорабатываем план, детализируя описания кирпичей
- 55:38 - Описываем падающие буквы
- 01:01:07 - Записываем анимацию расширяющейся платформы
- 01:04:28 - Продолжаем описывать падающие буквы
- 01:12:47 - Составляем список монстров
- 01:15:27 - Подводим итог составления плана
- 01:17:45 - Исправляем грамматические ошибки
- 01:20:30 - Создаём архив
- 01:21:40 - Popcorn_21.zip: пишем план
- Popcorn_21.zip - https://drive.google.com/file/d/1XX25pJjlDCasUYsnSby0N328M4APCLpw
- 00:00 - Анимация расплавления платформы
- 00:42 - Делаем раскадровку анимации расплавления из оригинальной игры
- 03:27 - Анализируем анимацию и решаем, как мы будем её воспроизводить
- 06:02 - Вводим состояния платформы EPlatform_State
- 09:30 - Добавляем метод Act() для перерисовки платформы
- 12:56 - Рефакторим метод Draw() для рисования разных состояний платформы
- 16:59 - Смещаем область платформы вниз
- 23:12 - Ищем в MSDN функции для чтения и установки пикселей
- 26:41 - Анимация платформы в первом приближении
- 35:08 - Стираем фоном красные следы
- 51:46 - Смещаем столбцы платформы на случайное расстояние
- 57:27 - Выносим код в AsConfig::Rand()
- 01:00:58 - Убираем оставшиеся точки
- 01:02:34 - Замедляем анимацию, добавив подсчёт кадров в Current_Timer_Tick
- 01:07:35 - Сохраняем позицию смещения каждого столбца платформы
- 01:12:42 - Оператор sizeof
- 01:19:24 - Popcorn_22.zip: пишем код
- Popcorn_22.zip - https://drive.google.com/file/d/1yO7NoAbFN3ssJTjqxzNX8GdEiJv3d4rg
- 00:00 - Анимация выкатывающейся платформы
- 00:28 - Включаю панель Solution Explorer
- 01:44 - Исправляю угасание активного кирпича
- 03:58 - Исправляем отражение мячика от нижней грани уровня
- 06:51 - Исправляем формулу отражения от нижней грани
- 07:40 - Начинаем делать анимацию выкатывающейся платформы
- 08:40 - Делаю раскадровку оригинальной анимации
- 13:36 - Добавим новое состояние платформы - EPS_Roll_In
- 14:01 - Выносим код установки состояния в метод Set_State()
- 17:37 - Добавляем функцию Draw_Roll_In_State()
- 20:32 - Рисуем разделительную линию
- 25:18 - Рисуем блик
- 29:08 - Поворачиваем разделительную линию
- 39:36 - Анимируем поворот шарика платформы
- 42:51 - Очищаем фоном предыдущее место платформы
- 44:44 - Корректируем размер Platform_Rect для шарообразной платформы
- 46:35 - Зацикливаем шаг поворота платформы
- 48:01 - Переносим стартовую позицию платформы на правый край уровня
- 49:02 - Останавливаем мячик посреди уровня
- 56:10 - Корректируем стартовую позицию платформы
- 57:41 - Корректируем начальный угол поворота
- 59:07 - Замедляем движение платформы в 3 раза
- 01:01:48 - Особенности графического режима GM_ADVANCED
- 01:05:04 - Рисуем расширяющуюся платформу
- 01:09:38 - Корректируем область перерисовки платформы
- 01:11:10 - Делаем плавное расширение платформы
- 01:16:17 - Переносим Hwnd из движка в конфиг
- 01:20:29 - Центрируем платформу
- 01:23:15 - Сохраняем срез архива под новым именем
- 01:25:14 - Popcorn_part_22.zip: пишем код
- Popcorn_part_22.zip - https://drive.google.com/file/d/1tAWNJq6-0YPujZ-u31mjmaHmsM-4Dw7p
- 00:00 - Состояния игры и мячика
- 00:36 - Увеличиваем количество оборотов шарика платформы с 8 до 16
- 02:27 - Описываем состояния игры
- 07:16 - Зависимость действий по таймеру от текущего состояния игры
- 09:20 - Описываем различные состояния мячика
- 11:20 - Ставим мячик на платформу
- 17:33 - Исправляем отражение мячика от нижней грани уровня
- 19:30 - Делаем потерю мячика при выходе за пределы уровня
- 25:12 - Заменяем координаты мячика с целого на вещественный тип
- 31:15 - Меняем состояние мячика и платформы в зависимости от состояния игры
- 34:29 - Обрабатываем состояние игры при утрате мячика
- 38:54 - Переводим растаявшую платформу в состояние EPS_Missing
- 43:21 - Обрабатываем состояние игры EGS_Restart_Level
- 49:02 - Обрабатываем нажатие пробела
- 53:18 - Добавим метод Set_State() для установки состояния мячика
- 56:56 - Добавим метод Get_State()
- 58:28 - Добавим метод Redraw_Ball()
- 01:00:51 - Поставим платформу в состояние EPS_Ready
- 01:02:32 - Popcorn_part_23.zip: пишем код
- Popcorn_part_23.zip - https://drive.google.com/file/d/1JIXBbJ5gc6LLaFrlzQ_W0gncDj_3bhdW
- 00:00 - Правильное движение мячика
- 01:38 - Переходим к представлению мячика как окружности с центром и радиусом
- 06:18 - Делаем серию телепортаций мячика вместо одной
- 09:17 - Корректируем координаты взаимодействий с препятствиями
- 11:42 - Заменяем коррекцию пути на регистрацию столкновений
- 16:21 - Выносим код в метод Check_Border_Hit()
- 18:59 - Переносим переменную Has_Floor из уровня в конфиг
- 20:42 - Переносим метод Check_Border_Hit() из класса мячика в класс рамки
- 26:52 - Наследуем класс рамки от интерфейса AHit_Checker
- 28:50 - Базовый и производный классы
- 29:29 - Виртуальный метод
- 30:57 - Абстрактный метод, абстрактный класс или интерфейс
- 33:11 - 2-й принцип ООП: наследование
- 33:36 - 3-й принцип ООП: полиморфизм
- 34:14 - Заменяем указатель на рамку указателем на интерфейс
- 40:03 - Накапливаем оставшееся расстояние в переменной Rest_Distance
- 42:20 - Popcorn_part_24_1.zip: пишем код
- 42:40 - Обработка попаданий по кирпичам через интерфейс AHit_Checker
- 47:40 - Устраняем циклическую зависимость мячика и уровня
- 48:48 - Заменяем указатель на ALevel на указатель типа AHit_Checker
- 51:11 - Отключаем warning C26451 через набор правил компиляции
- 57:59 - Обработка попаданий по кирпичам
- 59:09 - Накапливаем булевые результаты в одной переменной got_hit
- 01:01:40 - Делаем столкновение с платформой через интерфейс AHit_Checker
- 01:06:36 - Добавим вызов обработки столкновения с платформой
- 01:09:21 - Переносим указатели в массив Hit_Checkers
- 01:14:44 - Добавляем хит-чекеры через метод Add_Hit_Checker()
- 01:19:43 - Popcorn_part_24_2.zip: пишем код
- Popcorn_part_24_1.zip - https://drive.google.com/file/d/1eW71Y2o_rNbpCFTAOkHGwziVtYqyfvm1
- Popcorn_part_24_2.zip - https://drive.google.com/file/d/1JYA_l8W6Nsdicl33-DfA16HNTc_LQ58q
- 00:00 - Столкновение с кирпичами, этап 1
- 00:24 - Устанавливаем правильное направление движения мячика
- 01:04 - Исправляем отражение от нижней грани кирпича
- 04:42 - Убираем константу AsConfig::Ball_Size
- 05:45 - Отключаем warning C26451
- 07:35 - Строим модель процесса отражения мячика от кирпича
- 12:54 - Ищем уравнение окружности
- 14:26 - Переписываем уравнение окружности относительно X и Y
- 18:42 - Применяем уравнение окружности к нашей модели отражения
- 26:36 - Выносим проверку столкновения в функцию Hit_Circle_On_Line()
- 33:41 - Делаем отражение от верхней грани кирпича
- 36:52 - Проверяем угол падения перед проверкой столкновения
- 39:56 - Исправляем позицию отражения в brick_top_y
- 41:30 - Разбираемся, почему мячик летит сквозь кирпичи
- 44:01 - Создаём свойство для Ball_Direction
- 51:28 - Добавим метод ABall::Reflect()
- 55:31 - Popcorn_part_25.zip: пишем код
- Popcorn_part_25.zip - https://drive.google.com/file/d/1sbyUZ-FDf6o-B8TPKsQTZuybkkoLg_5N
- 00:00 - Столкновение с кирпичами, этап 2
- 00:16 - Делаем отражение от боковых стенок кирпича
- 05:02 - Убираем кирпичи уровня, чтобы проверить отражения
- 10:25 - Выбираем, от какой грани следует отражаться в первую очередь
- 14:19 - Переносим код в функции Check_Vertical_Hit() и Check_Horizontal_Hit()
- 19:35 - Запрещаем отражение, если ему мешает кирпич
- 26:24 - Переносим параметры текущего кирпича в члены класса
- 31:09 - Выносим код в метод Is_Check_Horizontal_First()
- 33:43 - Исключаем из проверки лишние кирпичи
- 42:52 - Добавляем тестовый уровень
- 44:40 - Создаём текущий уровень Current_Level
- 46:18 - Очищаем массив функцией memset()
- 48:17 - Создаём метод для установки текущего уровня Set_Current_Level()
- 52:11 - Добавим состояние тестирования движка EGS_Test_Ball
- 54:29 - Добавим в класс ABall методы Set_For_Test() и Is_Test_Finished()
- 01:02:49 - Исправляем движение мячика в тестовом режиме
- 01:06:12 - Добавим в метод Set_State() параметр y_pos со значением по умолчанию
- 01:10:57 - Подбираем координаты мячика для начала теста
- 01:13:02 - Ищем причину неправильного отражения мячика
- 01:14:59 - Строим другую модель отражения мячика
- 01:16:15 - Применяем обновлённую модель отражения
- 01:19:03 - Исправляем метод Check_Hit()
- 01:23:41 - Проводим тест ещё раз
- 01:26:46 - Ещё одна ошибка при отражении
- 01:31:12 - Проводим последнюю серию тестов
- 01:33:54 - Убираем лишний код
- 01:37:19 - Popcorn_part_26.zip: пишем код
- Popcorn_part_26.zip - https://drive.google.com/file/d/1eiuAhUkvt2-5yeLWuhJHZvLk2pzWn8Rc
- 02:20 - Исправляем ошибку отражения мячика от пустоты
- 05:14 - Выясняем причину залипания мячика возле платформы
- 08:01 - Ищем подходящую задачу в плане разработки
- 10:17 - Декомпозируем задачу отражения мячика от платформы на подзадачи
- 12:02 - Пишем код отражения от центральной части платформы
- 14:34 - Применяем код отражения от кирпичей из Check_Vertical_Hit()
- 16:30 - Описываем отрезок верхней части платформы
- 22:08 - Добавим метод Is_Moving_Up()
- 25:07 - Применяем метод Is_Moving_Up() в классе ALevel вместо условий
- 26:30 - Добавим по аналогии метод Is_Moving_Left()
- 29:36 - Переносим метод Hit_Circle_On_Line() в класс AHit_Checker
- 36:33 - Делаем отражение от нижней грани
- 38:24 - Замедляем мячик для анализа стирания при отражении
- 40:46 - Меняем порядок вывода мячика в кадре
- 41:52 - Popcorn_part_27.zip: пишем код
- Popcorn_part_27.zip - https://drive.google.com/file/d/1Otx3DofFgh8qePuSRUQM8SctwsCHA9h2
- 00:00 - Отражение мячика от платформы, этап 2
- 00:17 - Строим модель отражения двух окружностей
- 18:41 - Вычисляем расстояние между центрами окружностей
- 26:06 - Выносим в конфиг константу Moving_Step_Size
- 28:47 - Вычисляем арктангенс функцией atan2()
- 32:20 - Пишем код для углов альфа и гамма, и назначаем мячику новый угол
- 36:51 - Воспроизводим в тестовом режиме ошибку отражения
- 44:39 - Строим модель для определения "улетающего" мячика
- 48:16 - Добавим проверку диапазона относительного угла отражения
- 51:12 - Тестируем отражение в другом направлении
- 54:55 - Проверяем эффект скольжения мячика вдоль платформы
- 58:22 - Тестируем отражение при вертикальном смещении стартовой точки
- 01:01:15 - Проводим финальную серию тестов
- 01:02:07 - Выносим код в метод Reflect_On_Circle()
- 01:09:06 - Тестируем отражение от правого шарика платформы
- 01:10:31 - Рефакторим код отражения от центральной части платформы
- 01:12:41 - Проверяем отражение мячика от правой грани
- 01:14:20 - Уменьшаем радиус мячика на 1/6 пикселя
- 01:17:14 - Popcorn_part_28.zip: пишем код
- Popcorn_part_28.zip - https://drive.google.com/file/d/1TUQEpT532JksMpQUlSaiImRFIfzjn9CP
- 00:00 - Применяем активные кирпичи
- 01:28 - Составляем список активных кирпичей в нашей игре
- 07:00 - Описываем задачу анимации активных кирпичей
- 08:48 - Добавляем функцию Add_Active_Brick()
- 10:41 - Создаём новый объект активного кирпича оператором new
- 14:16 - Определяем тип кирпича, в который попал мячик
- 15:49 - Создаём массив активных кирпичей
- 17:16 - Заполнение массива активными кирпичами
- 20:00 - Ограничиваем создание кирпичей только для синих и красных
- 22:14 - Выводим все активные кирпичи уровня
- 23:22 - Анимируем все активные кирпичи уровня
- 26:10 - Добавим активному кирпичу его координаты в уровне
- 28:56 - Обнуляем массив Active_Bricks при инициализации уровня
- 30:03 - Добавляем новый активный кирпич на первое свободное место в массиве
- 34:49 - Удаляем активные кирпичи оператором delete
- 37:55 - Добавляем метод Is_Finished()
- 42:00 - Popcorn_part_29.zip: пишем код
- Popcorn_part_29.zip - https://drive.google.com/file/d/1u8t_IM0JWzd44cROBz2f0CpsR8Xz6B49
- 00:00 - Выпадение буквы из кирпича
- 00:17 - Исправляем циклы вывода и анимации активных кирпичей
- 02:07 - Анализируем сценарии, при которых буквы выпадают из кирпичей
- 03:11 - Добавляем метод On_Hit()
- 06:31 - Выбираем случайным образом действие при разбитии кирпича
- 11:10 - Создаём класс падающей буквы AFalling_Letter
- 14:42 - Создаём массив падающих букв Falling_Letters
- 16:33 - Добавляем очередную падающую букву в массив
- 20:57 - Выносим код в метод Add_Falling_Letter()
- 24:34 - Переносим метод Draw_Brick_Letter() из класса ALevel в AFalling_Letter
- 26:43 - Выносим в конфиг кисти и карандаши для рисования кирпичей
- 32:22 - Popcorn_part_30_1.zip: пишем код
- 32:36 - Копируем методы Act(), Draw() и Is_Finished() из класса активного кирпича в класс падающей буквы
- 36:13 - Описываем прямоугольником Letter_Cell область падающей буквы
- 39:25 - Дорабатываем метод Draw() падающей буквы
- 44:44 - Исправляем создание падающей буквы в методе Add_Falling_Letter()
- 47:11 - Обнуляем массив Falling_Letters в методе Init()
- 47:44 - Выводим все падающие буквы
- 48:42 - Вызываем анимацию всех падающих букв
- 52:08 - Анимируем падение буквы
- 53:40 - Очищаем фон под падающей буквой
- 59:01 - Исправляем баг с остановкой падающей буквы
- 01:02:37 - Исправляем баг с белыми точками после мячика
- 01:13:35 - Анимируем вращение буквы
- 01:16:06 - Замедляем вращение буквы в 4 раза
- 01:19:03 - Смещаем начало анимации на 2 кадра вперёд
- 01:21:27 - Дописываем метод Is_Finished()
- 01:23:59 - Рисуем фоном отсутствующие кирпичи в Draw_Brick()
- 01:25:32 - Стираем из уровня разбитый кирпич
- 01:27:06 - Popcorn_part_30_2.zip: пишем код
- Popcorn_part_30_1.zip - https://drive.google.com/file/d/1YHvjwFpuXNfMmhlhSdPZMHavxuaNst0o
- Popcorn_part_30_2.zip - https://drive.google.com/file/d/17Lra3Vz9bHqlgRcCArEMzFCV-KOdnFqI
- 00:00 - Новое расплавление платформы
- 00:19 - Анализируем текущее решение для расплавления платформы
- 01:51 - Замеряем время, затрачиваемое на расплавление
- 06:41 - Изменяем время более точно
- 08:38 - Рассматриваем модель вывода платформы линиями
- 11:40 - Пишем тест для замера производительности
- 15:06 - Измеряем время для нового алгоритма
- 18:57 - Сохраняем исходное изображение платформы
- 21:05 - Создаём массив в куче
- 26:45 - Сохраняем пиксели изображения в массив
- 29:13 - Добавим деструктор класса для удаления массива из кучи
- 33:27 - Пишем алгоритм, рисующий платформу цветными штрихами
- 38:38 - Пишем метод Get_Platform_Image_Stroke_Color()
- 48:07 - Определяем карандаш, соответствующий цвету штриха
- 51:44 - Добавим 3 переменных для описания цвета карандашей платформы
- 55:04 - Добавим метод Get_RGB()
- 57:56 - Инициализируем значения цветов платформы
- 59:41 - Проверяем в отладчике, как снимается образ платформы
- 01:02:24 - Смотрим в отладчике на содержимое области памяти
- 01:06:39 - Отлаживаем вывод цветных штрихов
- 01:12:25 - Замедляем анимацию расплавления, чтобы проверить правильность работы алгоритма
- 01:14:44 - Убираем оставшиеся красные следы
- 01:16:37 - Исправляем подпрыгивание платформы на первом кадре
- 01:18:56 - Убираем "пиксельный мусор"
- 01:20:25 - Убираем лишние комментарии и добавляем нужные
- 01:22:03 - Создаём кисти и карандаши платформы через цвет AColor
- 01:23:59 - Popcorn_part_31.zip: пишем код
- Popcorn_part_31.zip - https://drive.google.com/file/d/1gZzmOuQ44cBBIcDHIRllq5s3yQdjcH9m
- 00:00 - Оптимизация кирпичей
- 00:35 - Рисуем только те кирпичи, которые надо перерисовать
- 04:10 - Передаём в Draw_Brick() ссылку на RECT вместо пары координат
- 06:00 - Выносим метод Draw() в новый базовый класс AGraphics_Object
- 10:04 - Наследуем класс падающей буквы от AGraphics_Object
- 11:02 - Выносим код в метод Draw_Objects()
- 17:37 - Добавим в класс AGraphics_Object методы Act() и Is_Finished()
- 20:12 - Выношу код из Act() в Act_Objects()
- 23:30 - Исправляем координаты вывода кирпичей
- 25:05 - Исправляем анимацию тающих кирпичей
- 28:11 - Задаём последовательность случайных чисел функцией srand()
- 31:01 - Функции Windows для получения и преобразования системного времени
- 34:55 - Задаём значение псевдослучайной последовательности в методе Init_Engine()
- 38:51 - Ускоряем угасание кирпича до 1 секунды
- 40:18 - Popcorn_part_32_1.zip: пишем код
- 40:35 - Переносим код из On_Key_Down() в новый метод Move()
- 45:37 - Выносим класс падающей буквы в отдельную пару файлов
- 48:38 - Popcorn_part_32_2.zip: пишем код
- Popcorn_part_32_1.zip - https://drive.google.com/file/d/1xZXEO9ZOxaFApzdyb2o_R60kmTCuXZEY
- Popcorn_part_32_2.zip - https://drive.google.com/file/d/1myCK06OaPJLUI8bd2hhBniZqPFePpEWp
- 00:00 - Ловим буквы платформой
- 01:13 - Отмечаем в плане сделанные задачи
- 04:02 - Рассматриваем модель столкновения букв с платформой
- 05:14 - Описываем способ реализации такого столкновения
- 07:38 - Выносим код из On_Timer() в Act()
- 08:36 - Пишем "каркас" алгоритма обработки столкновений
- 11:24 - Добавим метод On_Falling_Letter()
- 12:19 - Добавим метод Get_Next_Falling_Letter()
- 18:40 - Добавим метод Hit_By()
- 21:02 - Добавим метод Get_Letter_Cell();
- 25:22 - Проверяем в отладчике работу алгоритма
- 29:53 - Добавим метод Finalize()
- 31:41 - Финализируем падающую букву в методе рисования
- 32:33 - Корректируем методы Is_Finished() и Act()
- 34:52 - Предотвращаем смещение платформы в момент расплавления
- 36:14 - Описание состояний падающей буквы в EFalling_Letter_State
- 38:56 - Заменяем использование Got_Hit и Finished на состояние
- 41:03 - Исправляем имя класса ALevel на AsLevel
- 42:58 - Popcorn_part_33.zip: пишем код
- Popcorn_part_33.zip - https://drive.google.com/file/d/16Nu84JOOwbLqSa4mzECwE5hmkxTR3LyM
- 00:00 - Падающие буквы, этап 1
- 00:19 - Возвращаем анимацию выкатывающейся платформы
- 03:37 - Исправляем ошибку маленького размера расплавляющейся платформы
- 07:57 - Исправляем размер разделителя шарика платформы
- 10:10 - Отмечаем сделанные задачи в плане разработки
- 11:14 - Строим в перечислении список всех падающих букв
- 14:57 - Выводим раскадровку всех ракурсов падающей буквы
- 23:08 - Исправим позицию вывода падающих букв
- 29:56 - Рисуем букву "И"
- 35:32 - Исправляем матрицу поворота буквы
- 45:37 - Рефакторим метод Add_Falling_Letter()
- 47:24 - Выводим букву "Ж"
- 55:33 - Добавим метод Draw_Line()
- 58:40 - Применим Draw_Line() для рисования буквы "Ж"
- 01:00:46 - Рисуем букву "И" методом Draw_Line()
- 01:02:21 - Выносим константу Brick_Half_Height
- 01:03:34 - Popcorn_part_34.zip: пишем код
- Popcorn_part_34.zip - https://drive.google.com/file/d/10D0wnGdptlPkrkrZ2Z87_CnxNjqEoV1H
- 00:00 - Падающие буквы, этап 2
- 00:26 - Рисуем букву "М"
- 03:30 - Добавим метод Draw_Line_To()
- 04:19 - Применим Draw_Line_To() для рисования букв "М" и "И"
- 06:04 - Рисуем букву "С" методом Draw_C()
- 15:12 - Рисуем букву "К"
- 17:15 - Рисуем букву "Ш"
- 19:13 - Рисуем букву "П"
- 20:33 - Рисуем букву "Л"
- 23:05 - Рисуем букву "Т"
- 24:29 - Рисуем символ "+"
- 26:28 - Делаем случайную генерацию типа падающей буквы
- 30:59 - Неравномерное распределение вероятности
- 36:18 - Вычисляем сумму всех "весов" падающих букв в методе Init()
- 38:54 - Добавим метод Get_Random_Letter_Type()
- 43:50 - Проверяем генерацию падающих букв в отладчике
- 48:09 - Popcorn_part_35.zip: пишем код
- Popcorn_part_35.zip - https://drive.google.com/file/d/15ZOkvf_NXxSC4Z30jYdNMudaOFxEmI13
- 00:00 - Неразбиваемый кирпич, этап 1
- 00:41 - Делаем раскадровку анимации неразбиваемого кирпича
- 04:31 - Добавим код анимации в метод Act() активного кирпича
- 07:20 - Создаём копипастом класс AActive_Brick_Unbreakable
- 10:55 - Делим функциональность активных кирпичей на 2 класса
- 17:16 - Выносим общую функциональность в класс AActive_Brick
- 19:16 - Переносим данные в секцию класса protected
- 20:54 - Добавим вызовы конструктора базового класса AActive_Brick
- 23:13 - Переносим конструктор AActive_Brick в защищённую секцию
- 25:01 - Удаляем объекты производных классов через указатель на базовый
- 28:48 - Смотрим в отладчике, как происходит удаление объекта
- 31:25 - Смотрим то же действие, но в машинных кодах
- 36:37 - Добавим деструктор AGraphics_Object
- 39:35 - Делаем деструктор AGraphics_Object виртуальным
- 45:45 - Создаём неразбиваемый кирпич в Add_Active_Brick()
- 48:06 - Исключения (exceptions) в С++
- 50:10 - Смотрим, как генерируется исключение оператором throw
- 52:06 - Перехватываем исключение операторами try/catch
- 55:27 - Как нужно использовать исключения
- 58:55 - Выбросим исключение в конструкторе AActive_Brick_Red_Blue
- 01:01:13 - Фабрика объектов
- 01:02:21 - Рисуем неразбиваемый кирпич в методе Draw_Brick()
- 01:05:43 - Popcorn_part_36.zip: пишем код
- Popcorn_part_36.zip - https://drive.google.com/file/d/1WPKdOsrrZolssOlK9HnHDLIN83L48JI3
- 00:00 - Рефакторинг цвета
- 00:17 - Переносим выбор кисти и карандаша в метод AColor::Select()
- 04:14 - Инкапсулируем кисть и карандаш в класс AColor
- 07:02 - Переименуем White_Brick_Color в White_Color
- 08:08 - Применяем выбор цвета в методе Draw_Brick()
- 09:54 - Убираем кисти и карандаши из конфига
- 11:17 - Исправляем выбор фонового цвета
- 13:41 - Исправляем метод Set_Brick_Letters_Color()
- 19:18 - Исправляем использование фоновой кисти и карандаша
- 19:53 - Исправляем массивы оттенков цвета для угасающих кирпичей
- 21:46 - Добавляем конструктор по умолчанию для AColor
- 23:33 - Исправляем метод AActive_Brick_Red_Blue::Draw()
- 24:53 - Исправляем методы Get_Fading_Color() и Setup_Colors()
- 27:08 - Уберём методы Create_Pen_Brush()
- 27:35 - Исправляем использование цвета для мячика ABall
- 29:40 - Исправляем использование цвета для рамки AsBorder
- 32:29 - Исправляем использование цвета для платформы AsPlatform
- 39:16 - Удаляем из конфига карандаш Letter_Pen
- 40:28 - Удаляем метод конфига Setup_Colors()
- 41:07 - Проверяем порядок инициализации статических констант
- 43:49 - Меняем имена констант на Red_Color и Blue_Color
- 45:40 - Popcorn_part_37.zip: пишем код
- Popcorn_part_37.zip - https://drive.google.com/file/d/11a--J1Zaia6i5kD1YiSJomVHNhAypQQp/view
- 00:00 - Неразбиваемый кирпич, этап 2
- 00:28 - Начинаем рисовать анимацию неразбиваемого кирпича
- 01:51 - Выносим вызов функции RoundRect() в метод Round_Rect()
- 06:47 - Применяем Round_Rect() при выводе платформы
- 13:35 - Анализируем изображение блика на кирпиче
- 16:02 - Рисуем красный блик четырьмя линиями
- 21:28 - Ищем в MSDN функцию FloodFill()
- 23:22 - Применяем функцию FloodFill() для заливки области
- 25:40 - Рисуем блик одной толстой линией
- 32:39 - Регионы Windows
- 37:44 - Обрезаем регионом вывод блика на кирпиче
- 45:25 - Добавим толстый карандаш в класс AColor
- 50:33 - Добавим метод Select_Pen() для выбора толстого карандаша
- 53:26 - Добавим метод Get_Brush()
- 54:54 - Переносим регион в приватную секцию
- 56:35 - Делаем анимацию движения блика
- 01:01:18 - Переносим рисование кирпича в метод Draw_In_Level()
- 01:09:13 - Popcorn_part_38.zip: пишем код
- Popcorn_part_38.zip - https://drive.google.com/file/d/1nPmrNqb14YAnaN4igdsttw2Gnft-0wKi
- 00:00 - Многоразовый кирпич
- 00:26 - Готовим изображения кирпичей на разных стадиях
- 06:39 - Создаём класс AActive_Brick_Multihit
- 11:09 - Переносим throw 13 в метод AsConfig::Throw()
- 15:09 - Вызываем рисование многоразовых кирпичей в методе Draw_Brick()
- 16:42 - Рисуем многоразовый кирпич в методе Draw_In_Level()
- 25:16 - Выносим рисование стадии в метод Draw_Stage()
- 27:55 - Рисуем стадии 2, 3 и 4
- 32:11 - Добавим активный многоразовый кирпич в Add_Active_Brick()
- 35:22 - Добавим метод Redraw_Brick()
- 39:32 - Анализируем анимацию вращающейся сотни
- 41:22 - Рисуем очередной кадр анимации "100" в методе Draw()
- 47:07 - Добавим цвет Letter_Color()
- 49:29 - Корректируем размер цифр в "100"
- 52:39 - Делаем вращение сотни
- 01:06:03 - Убираем разбитый кирпич из уровня
- 01:06:51 - Тестируем в движке попадание мячика по кирпичам
- 01:08:48 - Popcorn_part_39.zip: пишем код
- Popcorn_part_39.zip - https://drive.google.com/file/d/1UzirYJTC9znxDigZjUSk59A79TYnPw9J
- 00:00 - Мячик на парашюте, этап 1
- 00:28 - Анализируем движение мячика на парашюте
- 02:49 - Выбираем архитектурное решение для рисования свёрнутого парашюта
- 06:32 - Анализируем оригинальное изображение свёрнутого парашюта
- 09:00 - Рисуем чертёж нашей версии парашюта
- 10:26 - Рисуем фрагмент парашюта в методе Draw_Parachute_In_Level()
- 12:51 - Создаём двухцветный цвет в классе AColor
- 16:46 - Рисуем пару сегментов
- 22:09 - Выносим код в метод Draw_Parachute_Part()
- 25:54 - "Ставим" мячик на парашют в AsLevel::On_Hit()
- 28:51 - Добавим метод Set_On_Parachute()
- 31:51 - Добавим состояние EBS_On_Parachute
- 32:59 - Добавим метод Draw_Parachute()
- 34:17 - Анализируем оригинальное изображение парашюта
- 35:29 - Добавим описание области парашюта Parachute_Rect
- 38:41 - Popcorn_part_40.zip: пишем код
- Popcorn_part_40.zip - https://drive.google.com/file/d/1RLkZXpl1GbrQ3OonkuaZgAxJYZqNL28l
- 00:00 - Мячик на парашюте, этап 2
- 00:25 - Анализируем изображение парашюта
- 01:50 - Смотрим в MSDN на функцию Pie()
- 02:56 - Смотрим в MSDN на функцию Chord()
- 04:14 - Рисуем купол функцией Pie()
- 11:02 - Рисуем купол функцией Chord()
- 12:19 - Рисуем левую арку под куполом
- 18:12 - Рисуем остальные 2 арки
- 24:03 - Рисуем левую стропу
- 29:50 - Рисуем остальные стропы
- 34:25 - Делаем движение мячика на парашюте
- 41:40 - Отключаем парашют при попадании в платформу
- 44:59 - Добавим обработку EBS_Off_Parachute в ABall::Set_State()
- 45:44 - Добавим метод Redraw_Parachute()
- 47:05 - Снимаем состояние EBS_Off_Parachute в ABall::Draw()
- 48:35 - Добавим метод Clear_Parachute()
- 50:14 - Запретим устанавливать состояние EBS_On_Parachute в методе ABall::Set_State()
- 52:58 - Валидация переключения других состояний в ABall::Set_State()
- 54:40 - Делаем потерю мячика на парашюте
- 59:08 - Popcorn_part_41.zip: пишем код
- Popcorn_part_41.zip - https://drive.google.com/file/d/1NiaKvFyc6G6RULIAieE8EHEUJX9tXkly
- 00:00 - Телепорт, этап 1
- 00:24 - Снимаем раскадровку анимации телепортации
- 03:24 - Создаём копипастом класс AActive_Brick_Teleport
- 06:33 - Рисуем кирпич телепортации на уровне в AsLevel::Draw_Brick()
- 08:28 - Анализируем изображение телепорта
- 09:25 - Рисуем кирпич телепортации в Draw_In_Level()
- 13:19 - Переносим Portal_Color в конфиг
- 16:05 - Переносим в конфиг цвета Blue_Highlight и Red_Highlight
- 18:53 - Корректируем размер и позицию портала
- 21:44 - Добавим активный кирпич в Add_Active_Brick()
- 23:17 - Добавим состояния мячика EBS_Teleporting
- 25:26 - Ставим мячик в центр кирпича
- 28:45 - Добавим обработку телепортации в ABall::Set_State()
- 31:31 - Устраняем лишнюю перерисовку мячика в ABall::Move()
- 33:05 - Рисуем анимацию телепорта
- 37:11 - Подключаем Ball.h к активным кирпичам
- 40:43 - Сплющиваем мячик в портале через Draw_Teleporting()
- 44:29 - Убираем лишнее рисование мячика в портале
- 46:26 - Стираем мячик, когда он переходит в режим телепортации
- 48:57 - Popcorn_part_42.zip: пишем код
- Popcorn_part_42.zip - https://drive.google.com/file/d/1B9CPlqEztYCEZEkjZd9mQHfA_hG_SZIB
- 00:00 - Телепорт, этап 2
- 00:35 - Добавим указатель на телепорт назначения
- 02:54 - Выбираем координаты телепорта назначения и выносим код в метод Select_Destination_Teleport()
- 05:05 - Подсчитываем все телепорты на уровне
- 08:29 - Добавим структуру SPoint
- 10:05 - Создаём динамический массив позиций телепортов
- 13:19 - Добавляем в массив позиции телепортов
- 14:35 - Удаляем массив в деструкторе ~AsLevel()
- 15:59 - Проверяем выбор из массива координат телепорта назначения
- 21:19 - Выносим код в метод Add_New_Active_Brick()
- 24:43 - Добавим состояния телепорта ETeleport_State
- 26:46 - Делаем переход по состояниям в методе Act()
- 28:39 - Передаём мячик телепорту назначения
- 31:41 - Рисуем расширяющийся мячик в AActive_Brick_Teleport::Draw()
- 33:20 - Переносим код в метод Set_Ball()
- 36:38 - Добавим в активный кирпич Level_X и Level_Y
- 37:58 - Проверяем работу телепортации
- 44:40 - Выпускаем мячик из телепорта назначения и добавляем метод Get_Center()
- 47:14 - Исправляем состояние мячика в методе AActive_Brick_Teleport::Draw()
- 49:17 - Popcorn_part_43.zip: пишем код
- Popcorn_part_43.zip - https://drive.google.com/file/d/1A0tchJQUkmyuNKUiirPw6cAd9I0dfuDk
- 00:00 - Телепорт, этап 3
- 00:21 - Выбираем телепорт назначения случайным образом
- 05:53 - Выносим код в Add_Active_Brick_Teleport()
- 09:24 - Определяем направление, с которого прилетел мячик
- 16:06 - Добавим описание направления в EDirection_Type
- 17:53 - Определяем направление, в котором должен улететь мячик
- 25:04 - Добавим в телепорт направление выпуска Release_Direction
- 26:48 - Выпускаем мячик в правильном направлении в AActive_Brick_Teleport::Act()
- 30:06 - Выносим код в Get_Brick_X_Pos() и Get_Brick_Y_Pos()
- 36:57 - Пробрасываем тип удара в метод Add_Active_Brick_Teleport()
- 38:15 - Проверяем выбор направления
- 40:24 - Получаем координаты телепорта назначения через Get_Level_Pos()
- 44:10 - Проверяем передачу мячика между телепортами
- 48:42 - Убираем мячик из телепорта
- 50:20 - Проверяем выход из телепорта
- 53:00 - Исправляем удаление графических объектов в Act_Objects()
- 55:23 - Исправляем метод AActive_Brick_Teleport::Is_Finished()
- 58:20 - Анализируем причину, по которой мячик сам возвращается в нижний телепорт
- 01:03:30 - Не отражаем мячик для телепортов
- 01:06:50 - Поворачиваем угол вместе с поворотом направления
- 01:10:32 - Проверим выбор направления выпуска мячика
- 01:12:03 - Popcorn_part_44.zip: пишем код
- Popcorn_part_44.zip - https://drive.google.com/file/d/1unJ46fUz1jQtzXH1ewSeYJV9dxJdeToO
- 00:00 - Реклама, этап 1
- 00:37 - Смотрим на баг, когда падающие буквы перетирают кирпичи
- 01:32 - Ставим мячик поближе на платформу
- 02:38 - Стираем все движущиеся объекты методом Clear_Objects()
- 04:17 - Добавим метод Clear() в класс AGraphics_Object
- 09:32 - Анализируем оригинальные кирпичи рекламы
- 11:41 - Создаём копипастом класс AActive_Brick_Ad
- 13:35 - Рисуем кирпич рекламы на уровне
- 16:54 - Рисуем блик на шарике
- 21:33 - Рисуем второй шарик кирпича
- 23:01 - Создаём активный кирпич в методе Create_Active_Brick()
- 24:46 - Добавим валидацию пределов уровня
- 28:52 - Снимаем раскадровку анимации прыгающего шарика
- 32:17 - Декомпозируем анимацию на элементы
- 36:35 - Создаём класс AAdvertisement, описывающий рекламу
- 42:44 - Добавим объект рекламы в уровень
- 46:58 - Popcorn_part_45_1.zip: пишем код
- 47:18 - Начинаем рисовать кадр анимации и задаём область рекламы
- 50:16 - Рисуем красный шарик
- 52:26 - Рисуем стол
- 57:32 - Заливаем стол белым цветом
- 01:00:17 - Рисуем борт стола
- 01:04:51 - Рисуем тень под шариком
- 01:08:28 - Меняем цвет каймы стола
- 01:12:06 - Корректируем размер стола
- 01:13:11 - Popcorn_part_45_2.zip: пишем код
- Popcorn_part_45_1.zip - https://drive.google.com/file/d/1PpdzlRQjC0q8Eh0o79kmGclMQMlExf1i
- Popcorn_part_45_2.zip - https://drive.google.com/file/d/1LPMSq3TPgh6SIRzJutHUGmAGDCY6585M
- 00:00 - Реклама, этап 2
- 00:21 - Перенесём рекламу под кирпичи
- 03:57 - Заказываем перерисовку для кадра анимации
- 05:17 - Добавим указатель на рекламу в кирпич рекламы
- 07:53 - Добавим метод Show_Under_Brick()
- 09:00 - Удаляем разбитые кирпичи рекламы
- 11:59 - Добавим метод Has_Brick_At()
- 13:37 - Исправим вызов метода Draw_Brick()
- 15:50 - Стираем разбитый кирпич рекламы
- 17:42 - Заменяем разбитые кирпичи рекламы невидимыми - EBT_Invisible
- 21:12 - Создаём маску кирпичей, чтобы не рисовать рекламу, которую не видно
- 25:16 - Заполняем маску при разбивании кирпичей
- 28:06 - Заказываем перерисовку областей под маской
- 32:27 - Исправим метод AActive_Brick_Ad::Draw()
- 34:09 - Popcorn_part_46.zip: пишем код
- Popcorn_part_46.zip - https://drive.google.com/file/d/1rGkFwMTPLkgCBKzI3VVBhvS3nBnZ8Gzd
- 00:00 - Реклама, этап 3
- 00:17 - Используем регион обрезки для вывода рекламы
- 02:47 - Смотрим описания регионов в MSDN
- 07:26 - Добавим пустой регион Empty_Region
- 08:59 - Переделаем маску на массив регионов Brick_Regions
- 11:43 - Создаём регионы кирпичей в методе Show_Under_Brick()
- 14:50 - Удаляем регионы в деструкторе рекламы
- 16:27 - Смотрим в отладчике, как создаются регионы
- 18:51 - Переносим код очистки рекламы в метод Draw()
- 22:04 - Исследуем причину, по которой стол не залился белым цветом
- 23:36 - Смотрим в MSDN на функцию Polygon
- 25:02 - Рисуем стол функцией Polygon()
- 28:27 - Включаем видимость всей рекламы для отладки
- 30:46 - Рисуем блик на шарике
- 38:19 - Рисуем рамку вокруг рекламы
- 43:50 - Корректируем размер борта стола
- 45:59 - Popcorn_part_47.zip: пишем код
- Popcorn_part_47.zip - https://drive.google.com/file/d/1P_ZvN0Cjnn4KtJgfkNxjwuTU6OecAw9G
- 00:00 - Реклама, этап 4
- 00:17 - Переведём представление позиции шарика к X, Y и размерам
- 07:27 - Добавим вертикальное смещение шарика
- 10:14 - Ограничим движение шарика порогами
- 13:41 - Настраиваем пороги
- 16:41 - Ищем формулу для тела, брошенного вверх
- 20:02 - Применяем формулу при анимации шарика
- 25:06 - Плющим шарик при ударе
- 32:08 - Делаем движение тени под шариком
- 36:42 - Отключаем видимость всей рекламы при отладке
- 37:32 - Уменьшаем на 1 пиксель шарики рекламных кирпичей
- 40:35 - Popcorn_part_48.zip: пишем код
- Popcorn_part_48.zip - https://drive.google.com/file/d/1RTSDqcTKPDkXvXyV9RRsD6fZJ7BrdYF7
- 00:00 - Множество мячиков на уровне
- 02:12 - Смотрим анимацию растроения мячика
- 03:01 - Добавим массив мячиков вместо одного объекта
- 10:50 - Добавим новое состояние мячика EBS_Disabled
- 15:56 - Исправляем аргументы метода Set_State()
- 20:02 - Перенесём константу Start_Ball_Y_Pos в конфиг
- 21:47 - Сделаем обработку падающих букв в зависимости от их типа
- 23:50 - Ловим букву "Т"
- 25:45 - Popcorn_part_49_1.zip: пишем код
- 26:06 - Ставим на платформу первых 3 мячика
- 28:13 - Выносим код в метод Restart_Level()
- 29:32 - Выносим код в метод Play_Level()
- 30:31 - Переводим состояние игры в EGS_Lost_Ball только при утрате всех мячиков
- 34:47 - Останавливаем уровень методом AsLevel::Stop()
- 37:43 - Удаляем объекты в методе Draw(), когда нужно отменить всю анимацию
- 40:10 - Добавим метод Cancel_All_Activity()
- 41:14 - Добавим метод Delete_Objects()
- 43:47 - Popcorn_part_49_2.zip: пишем код
- Popcorn_part_49_1.zip - https://drive.google.com/file/d/15rjfxeUMrmGZWycf2bAiOHcnhlvmaC8b
- Popcorn_part_49_2.zip - https://drive.google.com/file/d/1sdiVcqYOuqCG3NGS7KvhG0QkCaNkq20F
- 00:00 - Рефакторинг движения, этап 1
- 00:35 - Воспроизводим ошибку с пролётом мячика через платформу
- 08:15 - Два вида событий, приводящих к смещению объектов в нашей игре
- 10:09 - Анализируем текущий способ обработки нажатия клавиш
- 13:00 - Делаем обработку события отжатия клавиш WM_KEYUP
- 14:53 - Рефакторим метод On_Key_Down()
- 16:40 - Добавим перечисление EPlatform_Moving_State
- 18:54 - Добавим в метод AsPlatform::Move() поддержку состояния движения платформы
- 21:18 - Добавим переменную для скорости платформы
- 23:27 - Переносим переменную X_Step в константы
- 24:18 - Смещаем платформу в методе Play_Level()
- 28:04 - Добавим в платформу метод Advance()
- 33:13 - Проверяем смещение платформы
- 36:18 - Добавим метод Get_Middle_Pos()
- 40:05 - Убираем красные следы, появившиеся из-за ошибки округления
- 45:13 - Выносим код в метод Get_Normal_Platform_Image()
- 51:21 - Проверяем попадание мячиков внутрь платформы
- 53:02 - Вынесем в конфиг константу D_Global_Scale
- 55:49 - Popcorn_part_50.zip: пишем код
- Popcorn_part_50.zip - https://drive.google.com/file/d/1sqSHkNhW1tNpZXq75cwHLrbpVXJAt995
- 00:00 - Рефакторинг движения, этап 2
- 00:17 - Создаём класс AMover
- 03:54 - Наследуем класс платформы от AMover
- 05:40 - Добавим в движок массив Movers
- 07:49 - Смещаем все муверы в методе Play_Level()
- 11:00 - Добавим класс-контейнер для мячиков AsBall_Set
- 13:12 - Добавим метод AsBall_Set::Draw()
- 14:47 - Добавим метод Release_From_Platform()
- 17:34 - Добавим метод Set_On_Platform()
- 19:19 - Удалим метод Restart_Level()
- 20:22 - Вынесем код в метод Advance_Mover()
- 21:45 - Вынесем код в метод All_Balls_Are_Lost()
- 25:13 - Сделаем смещение всех мячиков в методе Play_Level()
- 26:58 - Popcorn_part_51_1.zip: пишем код
- 27:19 - Отнаследуем класс AsBall_Set от AMover
- 28:59 - Преобразуем метод Move() мячика в метод Advance()
- 36:39 - Добавим метод Get_Speed() в платформу
- 38:47 - Добавим метод Get_Speed() в набор мячиков
- 42:06 - Исправляем ошибку, при которой мячики не рисуются
- 44:44 - Добавим методы Begin_Movement() и Finish_Movement() в платформу
- 46:12 - Добавим методы Begin_Movement() и Finish_Movement() в набор мячиков
- 46:59 - Отнаследуем класс мячика от AMover
- 49:39 - Переносим класс AMover в файл Ball.h
- 52:29 - Начинаем и заканчиваем движения для кадра в Advance_Movers()
- 53:31 - Проверяем пересечение мячиков и платформы
- 01:03:49 - Снимаем видео с нашей игры
- 01:08:55 - Исправим X_Step платформы
- 01:09:32 - Добавим в набор мячиков метод Set_For_Test()
- 01:10:57 - Добавим в метод Is_Test_Finished()
- 01:12:17 - Перенесём переменную Rest_Distance в класс
- 01:14:15 - Popcorn_part_51_2.zip: пишем код
- Popcorn_part_51_1.zip - https://drive.google.com/file/d/1aodlF-q0fpaHWCglgZp9I75rbN2EVrks
- Popcorn_part_51_2.zip - https://drive.google.com/file/d/1ZO5kXc6DdfNTfoUPQOsvuMnhh7jkktw3
- 00:00 - Буквы Т, И, С и Ж
- 00:25 - Исправляем имя метода на Advance_Movers()
- 00:54 - Добавим метод Triple_Balls()
- 05:22 - Выбираем самый дальний мячик
- 09:36 - Размножаем самый дальний мячик
- 12:49 - Разводим боковые мячики в стороны
- 16:26 - Проверяем работу алгоритма растроения
- 27:11 - Мячики перестали растраиваться - исправляем ошибку
- 30:55 - Popcorn_part_52_1.zip: пишем код
- 31:05 - Добавим обработку буквы "И" методом Inverse_Balls()
- 36:02 - Popcorn_part_52_2.zip: пишем код
- 36:14 - Выносим набор мячиков AsBall_Set в свою пару файлов
- 39:39 - Popcorn_part_52_3.zip: пишем код
- 39:45 - Исследуем баг с уезжающей платформой и её остатком после расплавления
- 42:46 - Добавим новое состояние платформы - EPS_Pre_Meltdown
- 45:20 - Смотрим, как замедляется мячик в оригинальной игре
- 46:57 - Ускоряем все мячики в методе Accelerate()
- 50:56 - Настраиваем ускорение мячиков
- 54:23 - Сбрасываем скорость всех мячиков в методе Reset_Speed()
- 59:38 - Ловим букву "Ж" в методе On_Falling_Letter()
- 01:03:39 - Popcorn_part_52_4.zip: пишем код
- Popcorn_part_52_1.zip - https://drive.google.com/file/d/1oeQfyKmDvooUmRATzDfX59kLZuDDRYoG
- Popcorn_part_52_2.zip - https://drive.google.com/file/d/1X2IGFTDPYeg63V6eAf16lA-Rm7bZPnpQ
- Popcorn_part_52_3.zip - https://drive.google.com/file/d/1k2akUA0LpQVD-YsO0EOGVm4Ig_5tfsmA
- Popcorn_part_52_4.zip - https://drive.google.com/file/d/1kMcYqceh1txIAMafcAfldHXS0-qd-k0P
- 00:00 - Буква П (пол)
- 01:13 - Ловим букву "П" в методе On_Falling_Letter()
- 02:12 - Смотрим, как включается пол в оригинальной игре
- 05:08 - Добавим метод Redraw_Floor()
- 08:55 - Рисуем пол в методе AsBorder::Draw()
- 13:33 - Добавим проверку пересечения с областью рисования для элементов рамки
- 16:52 - Падающие буквы и мячик оставляют следы на полу
- 17:51 - Рисуем линию пола пунктиром
- 23:00 - Выносим код в метод Draw_Floor()
- 24:25 - Рисуем серию штрихов
- 27:29 - Настраиваем длину штриха
- 30:29 - Штрихи не доходят до конца рамки
- 33:09 - Исправляем "отгрызание" мячиком куска пола в методе AsBorder::Check_Hit()
- 38:05 - Проверяем рисование пола и попадание в него мячика
- 40:55 - Popcorn_part_53.zip: пишем код
- Popcorn_part_53.zip - https://drive.google.com/file/d/1kASCpBIAuXuRekFYC5vNrM6uRMuV_iVu
- 00:00 - Рефакторинг графических объектов
- 00:27 - Анализируем архитектуру объектов, имеющих метод рисования Draw()
- 03:57 - Наследуем класс мячика от графического объекта
- 10:08 - Наследуем AsBall_Set от графического объекта
- 12:24 - Наследуем AsBorder от графического объекта
- 14:32 - Наследуем AsLevel от графического объекта
- 17:12 - Наследуем AsPlatform от графического объекта
- 19:58 - Представим главные объекты движка как его модули
- 23:20 - Делаем инициализацию и отрисовку модулей движка
- 25:50 - Выносим код очистки графических объектов в методы Clear()
- 27:08 - AsLevel::Clear()
- 27:48 - AsBorder::Clear()
- 30:09 - AsPlatform::Clear()
- 32:54 - AsBall_Set::Clear()
- 33:33 - ABall::Clear()
- 34:52 - Платформа ощутимо мерцает в состоянии покоя
- 37:27 - Ищем причину мерцания платформы при её движении
- 42:04 - Исследуем "инерцию" платформы
- 45:43 - Рефакторим метод платформы Advance()
- 46:47 - Исправляем "инерцию" в методе Move() платформы
- 52:54 - Popcorn_part_54.zip: пишем код
- Popcorn_part_54.zip - https://drive.google.com/file/d/1Ziu1KGjB3c5BdW080s6l_O9Eq9ybMaU0
- 00:00 - Платформа с клеем, этап 1
- 00:29 - Смотрим на анимацию оригинальной игры
- 01:54 - Снимаем раскадровку анимации растекающегося клея
- 04:57 - Анализируем элементы анимации
- 05:58 - Описываем 3 новых состояния платформы
- 08:13 - Добавим метод Draw_Glue_State()
- 10:16 - Рисуем пятно клея
- 17:39 - Переводим платформу в состояние растекающегося клея
- 18:33 - Добавим фоновую кайму
- 19:29 - Корректируем позицию и размер капли клея
- 21:52 - Выносим код в метод Draw_Glue_Spot()
- 23:03 - Добавим в Draw_Glue_Spot() параметры для вывода различных пятен
- 25:41 - Выведем правое пятно
- 27:45 - Выведем среднее пятно
- 28:30 - Выводим общую каёмку для всех капель
- 30:18 - Корректируем размер левой капли
- 31:22 - Делаем анимацию растекающегося клея в методе Act()
- 36:47 - Ограничим регионом вывод пятен
- 41:32 - Зададим начальную высоту пятен в Set_State()
- 42:57 - Удалим регион в Draw_Glue_State()
- 44:24 - Добавим заглушки в Set_State() для обработки двух других состояний
- 45:49 - Делаем движение платформы с клеем
- 48:13 - Добавим стирание платформы в AsPlatform::Clear()
- 49:57 - Переводим платформу в состояние EPS_Glue
- 51:37 - При движении платформа с клеем стирается не полностью
- 53:11 - Смотрим, как вызывается метод Redraw_Platform()
- 56:20 - Добавим в Redraw_Platform() параметр для обновления прямоугольников
- 59:59 - Popcorn_part_55.zip: пишем код
- Popcorn_part_55.zip - https://drive.google.com/file/d/1pTGDIvGRVCXMfqme1As8smS2GmY33kOL
- 00:00 - Платформа с клеем, этап 2
- 00:28 - Ловим букву "К" в методе On_Falling_Letter()
- 01:37 - Убираем клей при старте игры и ловим букву "К"
- 02:23 - Ставим мячик на платформу в методе Check_Hit()
- 05:03 - Мячик остановился слишком высоко
- 06:50 - Выносим код в метод On_Space_Key()
- 09:16 - Добавим в платформу метод Init(), чтобы передать ей указатель на набор мячиков
- 11:31 - Отпустим следующий приклеенный мячик в On_Space_Key()
- 12:38 - Добавим метод Release_Next_Ball()
- 14:47 - Вызываем метод платформы Init()
- 16:15 - Смещаем приклеенные мячики в методе платформы Advance()
- 19:14 - Добавим метод On_Platform_Advance()
- 21:25 - Добавим метод Forced_Advance()
- 26:04 - Проверяем, как смещаются и отпускаются несколько мячиков
- 27:44 - Предотвращаем повторное растекание клея в Set_State()
- 29:27 - Баг: игра зависла из-за постоянного переотражения мячика
- 32:06 - Добавим принудительный поворот направления при зависании
- 34:58 - Баг: мячики на платформе смещаются в методе Advance()
- 38:33 - Баг: мячики перестали стартовать с платформы
- 41:17 - Сохраним направление и скорость мячика при постановке на платформу
- 42:48 - Добавим мячику метод Release()
- 46:13 - Исправим реакцию на букву "К" в Set_State() платформы
- 48:08 - Баг: мячики смещаются на платформе, если есть мячик, быстрее, чем платформа
- 53:45 - Добавим генерацию падающей буквы "О" в Add_Falling_Letter()
- 54:53 - Отменяем состояние клея в методе On_Falling_Letter()
- 55:32 - Делаем обработку оставшихся состояний клея в методе Set_State() платформы
- 57:29 - Добавим обработку состояния финализации клея в Act() платформы
- 58:56 - Баг: мячик остался на платформе после отмены клея
- 59:43 - Отпускаем очередной мячик в методе платформы Set_State()
- 01:01:57 - Добавим мячику время старта с платформы
- 01:04:18 - Отпускаем мячики в методе AsBall_Set::Act()
- 01:07:11 - Баг: мячики не стартуют сами с платформы в начале игры
- 01:09:07 - Баг: мячик стартует вправо
- 01:11:18 - Баг: платформа не двигается после автостарта мячиков
- 01:16:20 - Popcorn_part_56.zip: пишем код
- Popcorn_part_56.zip - https://drive.google.com/file/d/1lFC5G0CWWAv-gLdC10WURMKhmfFHx8HX
- 00:00 - Рефакторинг состояния клея платформы
- 00:30 - Выносим в отдельный метод вызов InvalidateRect()
- 06:31 - Выносим шаг коэффициента растекания клея в именованную константу
- 07:55 - Баг: другая буква, кроме "О" не отменяет клей
- 09:53 - Переводим платформу в нормальное состояние в On_Falling_Letter()
- 12:04 - Добавим установку состояния EPS_Normal в методе платформы Set_State()
- 15:00 - Баг: мячик летает близко к горизонтальному направлению
- 16:20 - Баг: растекание клея прерывается, если поймать другую букву
- 18:11 - Выносим состояния клея платформы в отдельное перечисление
- 22:18 - Заменяем состояния платформы на новые
- 27:32 - Исправляем приклеивание мячиков на платформу в Check_Hit()
- 28:35 - Корректируем смещение мячиков на платформе в Advance()
- 30:35 - Исправляем анимацию в методе платформы Act()
- 32:28 - Баг: буква "Т" не отключает клей и не растраивает мячик
- 34:39 - Баг: буква "Т" так и не растроила мячик
- 35:44 - Выносим угол коррекции в константу Min_Ball_Angle
- 37:52 - Корректируем угол мячика при приближении к горизонтали
- 44:07 - Popcorn_part_57.zip: пишем код
- Popcorn_part_57.zip - https://drive.google.com/file/d/12G-jY6kFBgz6blVAhMqh8TS3DU2Z3s4s
- 00:00 - Оптимизация состояний
- 02:07 - Выносим состояния расплавления в EPlatform_Substate_Meltdown
- 04:37 - Выносим код Act_For_Glue_State()
- 06:08 - Добавим метод Act_For_Meltdown_State()
- 07:52 - Уберём очистку при расплавлении из метода Clear()
- 08:48 - Исправим метод Draw() при рисовании расплавления
- 09:36 - Исправим метод Set_State() для расплавления
- 10:18 - Исправим метод Act_For_Meltdown_State()
- 12:22 - Popcorn_part_58_1.zip: пишем код
- 12:37 - Выносим состояния выкатывания в EPlatform_Substate_Rolling
- 14:37 - Исправим метод Act() для выкатывающейся платформы
- 16:11 - Добавим метод Act_For_Rolling_State()
- 17:42 - Добавим метод Draw_Rolling_State()
- 19:40 - Исправим методы Set_State(), Redraw_Platform(), Draw_Roll_In_State() и On_Timer()
- 21:58 - Переносим код из рисующих методов в Act_For_Rolling_State()
- 24:10 - Удаляем метод Draw_Expanding_Roll_In_State()
- 25:10 - Исправим метод Act_For_Rolling_State()
- 25:51 - Выносим обычные состояния платформы в EPlatform_Substate_Regular
- 26:50 - Пересечение констант EPSR_Unknown
- 28:54 - Используем новый вид перечислений - enum class
- 33:31 - Добавим переменную типа EPlatform_Substate_Regular
- 35:26 - Исправим методы Advance(), Clear() и Draw()
- 38:40 - Добавим перегруженный метод Set_State()
- 42:05 - Добавим метод Has_State()
- 44:07 - Исправим методы Move() и On_Space_Key()
- 46:18 - Исправим Act_For_Rolling_State(), Act_For_Glue_State(), Draw_Normal_State() и Draw_Meltdown_State()
- 47:37 - Исправим методы On_Timer(), Act() и On_Falling_Letter()
- 49:17 - Popcorn_part_58_2.zip: пишем код
- 49:36 - Сделаем enum class для EPlatform_Substate_Meltdown
- 51:38 - Сделаем enum class для EPlatform_Substate_Rolling
- 53:07 - Сделаем enum class для EPlatform_Substate_Glue
- 54:25 - Сделаем enum class для EPlatform_State
- 56:58 - Сделаем enum class для EPlatform_Moving_State
- 58:12 - Переносим все состояния платформы в класс AsPlatform_State
- 01:01:41 - Переносим инициализацию состояний в конструктор AsPlatform_State
- 01:03:49 - Исправляем использование переменных состояния
- 01:05:38 - Добавим оператор преобразования типа
- 01:09:17 - Добавим оператор присваивания
- 01:12:30 - Баг: платформа с клеем не двигается
- 01:14:19 - Подводим итог рефакторинга перечислений
- 01:15:13 - Popcorn_part_58_3.zip: пишем код
- Popcorn_part_58_1.zip - https://drive.google.com/file/d/126D9yJTZJdh1wU27z18i1sKHb18kSBKz
- Popcorn_part_58_2.zip - https://drive.google.com/file/d/1Wgkgp3-w6XAlZ1B4gI4LmWRr5TvxN7Ie
- Popcorn_part_58_3.zip - https://drive.google.com/file/d/18BIx5G0OxXUm9S92fVXPn0fzqidlpCi1
- 00:00 - Расширяющаяся платформа, этап 1
- 00:29 - Смотрим анимацию в оригинальной игре
- 01:11 - Делаем раскадровку анимации расширения платформы
- 02:59 - Анализируем полученные кадры
- 03:30 - Добавим новое состояние платформы EPlatform_Substate_Expanding
- 04:41 - Добавим метод Draw_Expanding_State()
- 05:41 - Рисуем в Paint-е расширенную платформу
- 11:47 - Декомпозируем платформу на компоненты
- 15:33 - Начинаем рисовать расширяющуюся платформу
- 16:49 - Рисуем среднюю часть
- 19:13 - Добавим установку расширяющегося состояния в Set_State()
- 21:28 - Позиционируем среднюю часть по середине платформы
- 24:02 - Позиционируем правый шарик платформы
- 25:53 - Вырезаем дырку под дугой
- 28:40 - Рисуем дугу
- 33:34 - Рисуем линии фермы
- 40:55 - Корректируем дугу
- 45:05 - Рисуем вторую пару линий фермы
- 47:27 - Вырезаем дырку под фермой
- 48:38 - Добавим прямоугольник над шариком платформы
- 50:33 - Дополним комментарии для рисования платформы
- 52:22 - Переносим код рисования ферм в Draw_Expanding_Truss()
- 54:42 - Переносим код рисования шарика в Draw_Expanding_Platform_Ball()
- 57:39 - Рисуем правый шарик
- 01:06:14 - Рисуем правые фермы
- 01:09:14 - Popcorn_part_59.zip: пишем код
- Popcorn_part_59.zip - https://drive.google.com/file/d/1ZGNP2c9zC25mvBqSClFmo3RzqwJzj5P8
- 00:00 - Расширяющаяся платформа, этап 2
- 00:31 - Обрабатываем столкновение с буквой "Ш" в On_Falling_Letter()
- 02:20 - Создадим копипастом метод Act_For_Expanding_State()
- 07:36 - Добавим стирание платформы в методе Clear()
- 08:44 - Корректируем ширину платформы в Redraw_Platform()
- 10:48 - Исправляем заказ перерисовки платформы в Act_For_Expanding_State()
- 11:40 - Замедляем анимацию в 10 раз
- 12:27 - Введём коэффициент расширения платформы в Draw_Expanding_Truss()
- 16:50 - Добавим смещение ферм по X и проверим анимацию
- 19:45 - Сделаем расширение относительно центра платформы в Act_For_Expanding_State()
- 21:16 - Исправляем отрисовку правого края платформы
- 23:33 - Popcorn_part_60_1.zip: пишем код
- 23:45 - Добавим условие в метод Move() для смещения расширенной платформы
- 26:19 - Обновляем предыдущий прямоугольник платформы 1 раз на кадр в Redraw_Platform()
- 31:02 - Проверяем расширение платформы с клеем
- 31:48 - Баги: платформа заезжает за правый край уровня и мячик пролетает сквозь правый край платформы
- 32:26 - Смотрим использование ширины платформы
- 34:19 - Выносим код в метод Get_Current_Width()
- 36:54 - Применяем метод Get_Current_Width() вместо обращения к переменной Width
- 38:47 - Проверяем расширение платформы
- 39:46 - Применяем коррекцию из метода Advance() в Correct_Platform_Pos()
- 45:02 - Баг: платформа не переходит из одного анимированного состояния в другое
- 46:46 - Сохраним следующее состояние платформы в Set_State()
- 48:44 - Добавим метод Set_Next_State()
- 55:37 - Применяем переход в отложенное состояние в Set_State()
- 01:02:20 - Добавим в Set_State() обработку расширенной платформы
- 01:04:23 - Проверяем переходы между анимированными состояниями
- 01:07:08 - Переносим код отпускания всех мячиков из Set_State() в Act_For_Glue_State()
- 01:10:29 - Выносим код в метод Set_Next_Or_Regular_State()
- 01:13:20 - Popcorn_part_60_2.zip: пишем код
- Popcorn_part_60_1.zip - https://drive.google.com/file/d/147UkixUPdGmd0cTVWdfvHt0jocGD2jd0
- Popcorn_part_60_2.zip - https://drive.google.com/file/d/11HvlAYXiUpbTORSNEGfn5aKDYHJBRsnH
- 00:00 - Лазерная платформа, этап 1
- 00:20 - Исправим ошибку в имени extension_ratio
- 00:51 - Смотрим анимацию лазерной платформы
- 02:01 - Снимаем раскадровку оригинальной анимации
- 04:14 - Анализируем раскадровку
- 06:23 - Добавим enum EPlatform_Substate_Laser
- 07:16 - Добавим поддержку лазерного состояния в Set_Next_State()
- 08:31 - Добавим поддержку лазерного состояния в Act(), Clear() и Draw()
- 09:13 - Добавим установку лазерного состояния в Set_State()
- 10:43 - Добавим поддержку лазера в Move() и On_Space_Key()
- 11:53 - Добавим копипастом метод Act_For_Laser_State()
- 15:13 - Допишем установку начального шага трансформации в Set_State()
- 15:54 - Добавим пустой метод Draw_Laser_State()
- 17:59 - Готовим прообраз изображения платформы
- 21:47 - Декомпозируем исходное изображение на графические примитивы
- 25:17 - Добавим регион обрезки для лазерной платформы
- 26:53 - Рисуем левое крыло
- 31:28 - Рисуем перемычку левого крыла
- 33:38 - Рисуем копипастом правое крыло и перемычку
- 37:13 - Делаем правое крыло зеркальным отражением левого
- 39:29 - Ищем способ совмещения чертежа с результатом отрисовки
- 43:02 - Корректируем высоту крыльев и перемычек
- 45:13 - Рисуем прямоугольники "ног" платформы
- 49:38 - Рисуем кабину
- 54:25 - Рисуем левую "ногу" многоугольником
- 59:52 - Рисуем правую "ногу" многоугольником
- 01:01:03 - Рисуем среднюю часть кабины
- 01:02:42 - Рисуем пушки
- 01:07:59 - Рисуем хвост
- 01:11:47 - Заливаем платформу цветом
- 01:12:42 - Выносим код в метод Draw_Laser_Wing()
- 01:14:56 - Совмещаем в одном методе рисование левого и правого крыла
- 01:19:39 - Выносим код в метод Draw_Laser_Leg()
- 01:20:50 - Совмещаем в одном методе рисование двух "ног"
- 01:23:26 - Выносим код в метод Draw_Laser_Cabin()
- 01:24:55 - Popcorn_part_61.zip: пишем код
- Popcorn_part_61.zip - https://drive.google.com/file/d/1vvAySUvf_YkHCEhQusKN2YXvy3DByKIz
- 00:00 - Лазерная платформа, этап 2
- 00:31 - Добавим обработку буквы "Л" в On_Falling_Letter()
- 02:09 - Ускоряем для отладки переход в лазерное состояние
- 03:06 - Разбираемся, как мы будем делать анимацию платформы
- 04:57 - Как мы сделаем анимацию крыла
- 06:53 - Добавим коэффициент трансформации ratio в Draw_Laser_Wing()
- 08:34 - Меняем высоту эллипса от 7 до 12 игровых пикселей
- 11:14 - Отключим рисование остальных элементов платформы
- 12:23 - Настраиваем рисование перемычки
- 13:48 - Баг: платформа анимируется не по середине уровня
- 15:35 - Исправляем позиционирование в Act_For_Rolling_Step()
- 16:42 - Анализируем анимацию перемычки
- 20:24 - Рисуем начальное и конечное состояние перемычки
- 24:45 - Добавим метод Draw_Expanding_Rectangle()
- 34:38 - Преобразуем Draw_Expanding_Rectangle() в Draw_Expanding_Figure()
- 36:22 - Применяем Draw_Expanding_Figure() для рисования крыла
- 41:19 - Анимируем правое крыло
- 46:14 - Анимируем пушку
- 54:13 - Анимируем хвост
- 56:31 - Заменяем тип аргументов в Draw_Expanding_Figure() с int на double
- 58:25 - Вынесем код в Get_Expanding_Value()
- 01:01:34 - Корректируем рост хвоста
- 01:04:47 - Анимируем внутреннюю часть кабины
- 01:09:50 - Анимируем среднее кольцо кабины
- 01:16:57 - Анимируем внешнюю часть кабины
- 01:19:37 - Смотрим анимацию всей платформы
- 01:21:55 - Анализируем анимацию ног и средней части
- 01:23:39 - Анимируем рост "ног" платформы
- 01:26:03 - Анимируем уменьшение средней части платформы
- 01:28:47 - Выносим код в Draw_Laser_Inner_Part()
- 01:31:28 - Проверяем анимацию платформы, залитой цветом
- 01:32:42 - Добавим перечисление EFigure_Type и применим его в Draw_Expanding_Figure()
- 01:37:10 - Завершаем настройку анимации платформы
- 01:39:12 - Баг: платформа обрезана слева на 2 пикселя
- 01:45:22 - Смотрим, как платформа переходит между состояниями
- 01:47:04 - Popcorn_part_62.zip: пишем код
- Popcorn_part_62.zip - https://drive.google.com/file/d/1Q6fRTvzDtXFQzE9zjKtPrpbzUUEICruB
- 00:00 - Оптимизация платформы, этап 1
- 00:38 - Признак необходимости рефакторинга большого класса
- 02:06 - Обобщим 3 перечисления в одно - EPlatform_Transformation
- 04:53 - Выносим код в Set_Transformation_State()
- 10:04 - Отрефакторим метод Set_State() для "регулярного" состояния
- 12:42 - Исправляем константы в методах анимации
- 14:34 - Проверяем работу программы
- 16:26 - Убираем лишние комментарии
- 17:36 - Описываем иерархию классов платформы
- 23:15 - Виртуальное наследование
- 27:01 - Рассматриваем альтернативу наследованию - агрегацию
- 29:07 - Выносим код в класс AsPlatform_Glue
- 33:06 - Выносим вызов Redraw_Platform() за пределы Act_For_Glue_State()
- 34:29 - Передаём в Act_For_Glue_State() указатель на набор мячиков
- 35:26 - Смотрим, как можно отрефакторить метод Set_State()
- 37:45 - Рефакторим метод Set_Next_Or_Regular_State()
- 41:33 - Переносим метод Set_State() в класс AsPlatform_State
- 43:03 - Добавим снова метод Set_State() в платформу, но уже с другой логикой
- 47:01 - Передадим ссылку на состояния платформы в AsPlatform_Glue()
- 48:06 - Вернём следующее состояние из Act_For_Glue_State()
- 50:04 - Рефакторим метод Draw_Glue_State()
- 53:23 - Рефакторим метод Draw_Glue_Spot()
- 54:07 - Исправляем инициализацию данных платформы
- 55:32 - Переносим код в метод Reset()
- 57:51 - Исправляем имена методов класса AsPlatform_Glue
- 58:46 - Убираем лишние комментарии
- 01:00:32 - Popcorn_part_63.zip: пишем код
- Popcorn_part_63.zip - https://drive.google.com/file/d/1R7ZXPGEAtwK3MO1BrhdRfHpIvhJg_mQG
- 00:00 - Оптимизация платформы, этап 2
- 00:19 - Выносим функциональность расширяющейся платформы в свой класс
- 02:54 - Добавим конструктор, принимающий ссылку на состояние платформы
- 04:29 - Рефакторим Act_For_Expanding_State()
- 05:49 - Исправим AsPlatform_Glue::Act()
- 06:35 - Передаём ссылки на позицию и следующее состояние в Act_For_Expanding_State()
- 08:03 - Возвращаем необходимость коррекции позиции через параметр
- 09:21 - Исправляем вызов Act_For_Expanding_State()
- 11:07 - Рефакторим Draw_Expanding_State()
- 13:42 - Рефакторим Draw_Expanding_Platform_Ball()
- 15:45 - Делаем отложенную инициализацию платформы
- 19:24 - Добавим переменную Inner_Color
- 21:22 - Добавим переменную Circle_Color
- 22:57 - Переносим метод Draw_Circle_Highlight()
- 26:15 - Переносим константы и исправляем инициализацию данных платформы
- 27:38 - Добавим метод AsPlatform_Expanding::Reset()
- 29:58 - Исправим имена методов и уберём лишние комментарии
- 31:11 - Popcorn_part_64_1.zip: пишем код
- 31:25 - Выносим функциональность лазерной платформы в свой класс
- 33:48 - Добавим конструктор AsPlatform_Laser
- 34:53 - Рефакторим Act_For_Laser_State()
- 36:24 - Рефакторим Draw_Laser_State()
- 37:19 - Рефакторим константы для лазерной платформы
- 39:05 - Рефакторим цвет и добавляем метод Init()
- 42:32 - Рефакторим Draw_Laser_Inner_Part()
- 43:59 - Перенесём Draw_Expanding_Figure() и Get_Expanding_Value()
- 45:33 - Исправляем инициализацию платформы
- 46:16 - Исправляем вызов Act_For_Laser_State()
- 47:09 - Добавим метод AsPlatform_Laser::Reset()
- 48:18 - Исправляем инициализацию платформы
- 49:30 - Исправим имена методов и уберём лишние комментарии
- 52:11 - Popcorn_part_64_2.zip: пишем код
- Popcorn_part_64_1.zip - https://drive.google.com/file/d/1_TS3VLfhI4caus6uOMc46ZiYpeQIxbxZ
- Popcorn_part_64_2.zip - https://drive.google.com/file/d/1uNyMCtzh3Rft3rdXXUmTsBJ4kkcWjKBX
- 00:00 - Стрельба лазерными лучами, часть 1
- 00:30 - Смотрим оригинальную анимацию лазерных лучей
- 01:00 - Делаем обработку нажатия пробела в методе Fire()
- 03:31 - Добавим в лазерную платформу массив лазерных лучей
- 05:13 - Ищем свободные лазерные лучи
- 09:02 - "Ставим" лучи в начальную позицию в методе Set_At()
- 11:40 - Планируем архитектуру классов для множества лазерных лучей
- 12:48 - Создадим копипастом классы ALaser_Beam и AsLaser_Beam_Set
- 13:54 - Переносим набор лучей из платформы в движок
- 17:55 - Добавим прототипы методов для ALaser_Beam и AsLaser_Beam_Set
- 20:27 - Переносим метод Fire() в класс AsLaser_Beam_Set
- 22:29 - Добавим в ALaser_Beam поле Is_Active и метод Set_At()
- 25:48 - Пишем копипастом методы класса AsLaser_Beam_Set
- 29:28 - Пишем код для ALaser_Beam::Draw()
- 30:40 - Пишем код для ALaser_Beam::Set_At()
- 34:56 - Рисуем луч
- 37:32 - Проверяем рисование луча
- 39:18 - Popcorn_part_65.zip: пишем код
- Popcorn_part_65.zip - https://drive.google.com/file/d/1GiOyT6CzFJJxi9pU_Cjusw3S9yjnykV8
- 00:00 - Стрельба лазерными лучами, часть 2
- 00:25 - Исправим ошибку с двумя плюсами
- 00:46 - Выносим код в метод Get_Gun_Pos()
- 04:35 - Отрефакторим методы Fire() у лазерной платформы и набора лучей
- 06:14 - Корректируем позицию центра пушек
- 13:34 - Ставим луч в стартовую позицию в ALaser_Beam::Set_At()
- 15:05 - Делаем метод Advance() лазерного луча
- 15:51 - Выносим код в метод Redraw_Beam()
- 18:27 - Заглушим метод Begin_Movement()
- 19:15 - Поправим методы Get_Speed(), Act() и Is_Finished()
- 19:56 - Проверяем первый запуск лучей
- 20:26 - Делаем метод ALaser_Beam::Clear()
- 22:32 - Удаляем точечные следы от лучей
- 25:24 - Деактивация лучей при достижении края уровня
- 27:47 - Анализируем поведение луча возле границы уровня
- 30:18 - Добавим состояния луча в ELaser_Beam_State
- 32:57 - Применим методы лазерного луча
- 38:52 - Добавим "режим" стрельбы вместо выстрела по нажатию пробела
- 40:57 - Перенесём код стрельбы из Fire() в Act()
- 43:21 - Делаем автоматическую стрельбу через интервал времени
- 46:58 - Исправим реакцию на отжатие пробела в On_Space_Key()
- 48:39 - Проверяем столкновение луча с кирпичами в методе Advance()
- 51:21 - Добавим копипастом массив хит-чекеров для лучей
- 52:08 - Добавим перегруженный метод Check_Hit() в уровень
- 58:26 - Исправим On_Hit() уровня для нулевого указателя на мячик
- 01:03:17 - Добавим перегруженный метод Check_Hit() в Hit_Checker
- 01:06:23 - Добавим копипастом метод Add_Hit_Checker()
- 01:08:28 - Баг: лучи пропадают перед кирпичами
- 01:12:42 - Проверяем переход платформы через разные состояния
- 01:13:53 - Баг: лазер стреляет сам при переходе платформы в лазерное состояние
- 01:16:37 - Popcorn_part_66.zip: пишем код
- Popcorn_part_66.zip - https://drive.google.com/file/d/1IZyD1ih6x4WXd4CQnhRRY-uWDTaPSl4F
- 00:00 - Рефакторинг платформы
- 01:26 - Выносим класс ALaser_Beam в свою пару файлов
- 05:31 - Вынесем "инструменты" в пару файлов Tools
- 08:38 - Переносим класс AColor в Tools
- 11:49 - Выносим класс AsLaser_Beam_Set в свою пару файлов
- 14:08 - Выносим класс AsPlatform_State в свою пару файлов
- 16:36 - Выносим класс AsPlatform_Glue
- 24:46 - Выносим класс AsPlatform_Expanding
- 26:31 - Выносим класс AsPlatform_Laser
- 29:31 - Добавим класс AHit_Checker_List
- 35:13 - Добавим в AHit_Checker_List метод Check_Hit()
- 36:45 - Применим AHit_Checker_List для лазерного луча
- 39:27 - Применим AHit_Checker_List для мячика
- 44:08 - Popcorn_part_67.zip: пишем код
- Popcorn_part_67.zip - https://drive.google.com/file/d/1TuB_vLGuQMLaT4FRVpENrngUJApPiido
- 00:00 - Гейты, этап 1
- 00:52 - Анализируем оригинальную анимацию
- 02:14 - Снимаем раскадровку анимации гейта
- 03:40 - Анализируем этапы анимации
- 05:41 - Создаём класс AGate
- 08:15 - Добавим заготовки методов гейта
- 09:40 - Вызовем рисование гейта в методе Draw() рамки
- 10:16 - Поставим гейт в правильную позицию
- 12:53 - Декомпозируем гейт на элементы
- 14:52 - Отключим рисование рамки справа
- 15:29 - Рисуем основу верхней чаши
- 22:59 - Добавим регион обрезки
- 27:27 - Рисуем блик на чаше снизу
- 30:12 - Рисуем "заплатку" в правом нижнем углу
- 31:37 - Рисуем перфорацию
- 32:31 - Добавим в конфиг метод Rect()
- 34:55 - Добавим в конфиг второй перегруженный метод Rect()
- 38:53 - Отрефакторим рисование чаши
- 40:17 - Рисуем перемычку перед чашей
- 41:08 - Вынесем код в метод Draw_Cup()
- 43:03 - Применим матрицу преобразования пространства для чаши
- 49:25 - Выводим отражённую чашу
- 53:36 - Выводим обе чаши
- 57:58 - Добавим метод Draw_Edge() для рисования ребра
- 01:01:33 - Рисуем рёбра под чашей
- 01:05:50 - Выносим код в Draw_Edges()
- 01:07:05 - Рисуем полный гейт
- 01:08:11 - Выводим все 8 гейтов
- 01:15:14 - Очищаем область под гейтом
- 01:20:04 - Добавим цвет Gate_Color
- 01:21:10 - Баг: платформа наезжает на гейты
- 01:22:49 - Popcorn_part_68.zip: пишем код
- Popcorn_part_68.zip - https://drive.google.com/file/d/1KH_8VC59arQ0mU9Dzg6PzpvAdmzK5NOW
- 00:00 - Гейты, этап 2
- 00:26 - Анализируем состояния анимации гейтов
- 02:21 - Добавим перечисление EGate_State
- 03:51 - Добавим перечисление EGate_Transformation
- 05:36 - Добавим метод Open_Gate() в гейт
- 07:39 - Добавим метод Open_Gate() в класс рамки
- 12:16 - Добавим Act() для рамки
- 14:08 - Исправим Clear() для рамки
- 15:13 - Добавим Act() для гейта
- 16:43 - Добавим копипастом метод Act_For_Short_Open()
- 24:23 - Анимируем короткое открытие в Draw_Edges()
- 27:58 - Баг: не работает анимация гейта
- 30:33 - Добавим метод Redraw_Gate()
- 31:32 - Баг: открытый гейт не закрывается
- 34:11 - Popcorn_part_69_1.zip: пишем код
- 35:34 - Исправим порядок открытия и выкатывания платформы в Restart_Level()
- 37:23 - Сделаем открытие гейта в AsEngine::Act()
- 39:22 - Добавим метод Is_Gate_Opened()
- 40:32 - Добавим метод Is_Opened()
- 42:04 - Ускорим анимацию короткого открытия
- 42:56 - Добавим копипастом метод Act_For_Long_Open()
- 51:30 - Добавим смещение чаш вверх
- 53:25 - Добавим смещение нижней чаши вниз
- 56:44 - Анализируем множественные баги анимации гейта
- 58:11 - Исправляем анимацию 7-го гейта
- 59:15 - Исправляем однопиксельные погрешности округления
- 01:05:31 - Баг: рамка не перерисовывается после задвигающихся чаш
- 01:07:40 - Баг: рамка мигает под гейтом
- 01:12:21 - Совместим 2 метода в один Act_For_Open()
- 01:18:21 - Анализируем оригинальную анимацию длинного раскрытия гейта
- 01:19:53 - Разделим Draw_Edges() на два метода
- 01:21:11 - Добавим метод Draw_Long_Opening_Edges()
- 01:25:01 - Добавим метод Draw_Red_Edge()
- 01:26:55 - Выведем красные рёбра
- 01:30:30 - Анализируем оригинальную анимацию разряда между чашами
- 01:31:19 - Рисуем разряд в AGate::Draw()
- 01:32:47 - Добавим метод Draw_Charge()
- 01:41:36 - Popcorn_part_69_2.zip: пишем код
- Popcorn_part_69_1.zip - https://drive.google.com/file/d/1xVkc8NUvIo6yQGtACwzPgpDdC2L83zoT
- Popcorn_part_69_2.zip - https://drive.google.com/file/d/1kAzPkz2V6ghvHoxaejxsvV9LLPbZoZCA
- 00:00 - Рефакторинг enum и игровые объекты
- 00:26 - О том, что не надо смешивать enum и enum class
- 01:40 - Переводим EBrick_Type в enum class
- 06:18 - Исправим условия в Open_Gate() и Is_Gate_Opened()
- 09:34 - Переводим EDirection_Type в enum class
- 12:00 - Переводим ETeleport_State в enum class
- 14:58 - Переводим EBall_State в enum class
- 16:17 - Переводим EKey_Type в enum class
- 17:10 - Переводим EGame_State в enum class
- 18:10 - Переводим ELetter_Type в enum class
- 20:46 - Переводим EFalling_Letter_State в enum class
- 21:48 - Группируем фильтры в #Ball
- 24:09 - Группируем фильтры в #Laser_Beam
- 25:19 - Группируем фильтры в #Platform
- 26:30 - Группируем фильтры в #Tools
- 27:42 - Вынесем класс AGate в свою пару файлов
- 30:24 - Группируем фильтры в #Border
- 31:14 - О замене вызова Rectangle() на AsConfig::Rect()
- 35:41 - Переименуем файлы Tools в Common
- 39:19 - Переносим методы конфига в класс AsTools
- 41:38 - Исправляем вызовы методов конфига
- 43:24 - Проверяем результат замены вызова Rectangle() на AsConfig::Rect()
- 45:04 - Заменяем вызов Rectangle() в AsBorder::Clear()
- 46:30 - Заменяем вызов Rectangle() в AsBorder::Draw_Element()
- 50:46 - Заменяем вызов Rectangle() в AFalling_Letter::Clear()
- 52:35 - Заменяем вызов Rectangle() в ALaser_Beam::Clear()
- 53:33 - Заменяем вызов Rectangle() в AsPlatform::Clear()
- 54:09 - Заменяем вызов Rectangle() в AsPlatform_Expanding::Draw_State()
- 55:35 - Добавим метод AsTools::Ellipse()
- 57:36 - Заменяем вызов Ellipse() в ABall::Clear()
- 58:39 - Заменяем вызов Ellipse() в ABall::Draw()
- 59:20 - Заменяем вызов Ellipse() в ABall::Draw_Parachute()
- 01:00:34 - Заменяем вызов Ellipse() в AsPlatform::Draw_Normal_State() и Draw_Expanding_Platform_Ball()
- 01:02:57 - Popcorn_part_70_1.zip: пишем код
- 01:04:00 - Создадим копипастом класс AsGame_Objects_Set
- 01:06:09 - Анализируем задачу представления разных игровых объектов в одном классе
- 01:08:37 - Пытаемся в конструкторе создать массив общих объектов
- 01:11:57 - Приведение объектов к другому типу на примере Begin_Movement()
- 01:13:36 - Приведение типов через оператор dynamic_cast
- 01:16:39 - Объединим классы AGraphics_Object и AMover в один - AGame_Object
- 01:19:44 - Сделаем доступ к игровым объектам через итератор
- 01:24:25 - Добавим метод AsBall_Set::Get_Next_Game_Object()
- 01:28:22 - Добавим копипастом интерфейсные методы в AsGame_Objects_Set
- 01:35:01 - Отнаследуем AsLaser_Beam_Set от AsGame_Objects_Set
- 01:37:46 - Представим модули и муверы в движке как игровые объекты
- 01:44:22 - Добавим в движок метод Add_Next_Module()
- 01:48:20 - Исправим стирание гейтов в AsBorder::Clear()
- 01:49:05 - Popcorn_part_70_2.zip: пишем код
- Popcorn_part_70_1.zip - https://drive.google.com/file/d/1sCPm6a4Vrk6mtYGRCAyG9m72Q8rm1Zsk
- Popcorn_part_70_2.zip - https://drive.google.com/file/d/1kK2sLU9c0rUfBFx4ni7T2LgRoFB2cmzZ
- 00:00 - Монстр "Глаз"
- 00:34 - Добавим копипастом класс AsMonster_Set
- 04:02 - Добавим класс AMonster
- 06:34 - Добавим набор монстров в движок
- 08:56 - Добавим метод Emit_At_Gate()
- 14:41 - Добавим инициализацию набора монстров
- 17:40 - Активация монстра возле указанного гейта
- 20:40 - Добавим в рамку метод Get_Gate_Pos()
- 22:09 - Добавим в гейт метод Get_Pos()
- 23:20 - Добавим монстру метод Activate() и конструктор
- 25:43 - Выбираем монстров и снимаем раскадровку анимации
- 30:33 - Декомпозируем анимацию глаза
- 32:16 - Рисуем основу монстра в AMonster::Draw()
- 36:09 - Добавим эллиптический регион обрезки
- 37:36 - Подбираем цвет "затенённой" части монстра
- 41:08 - Рисуем второй круг монстра
- 45:12 - Рисуем роговицу
- 51:30 - Рисуем радужку
- 53:11 - Рисуем зрачок
- 55:53 - Делаем переменный размер роговицы
- 01:00:48 - Обрезаем вывод по размеру роговицы
- 01:02:47 - Обводим роговицу эллиптической дугой
- 01:09:35 - Popcorn_part_71_1.zip: пишем код
- 01:09:49 - Декомпозируем анимацию мигания глаза
- 01:11:31 - Описываем состояния мигания в EEye_State
- 01:13:29 - Описываем расписание мигания всех глаз
- 01:17:29 - Задаём расписание мигания конкретного глаза
- 01:22:10 - Вычислим текущий кадр анимации по расписанию
- 01:25:51 - Вычисляем текущую высоту роговицы
- 01:31:27 - Подкорректируем расписание мигания
- 01:33:38 - Popcorn_part_71_2.zip: пишем код
- Popcorn_part_71_1.zip - https://drive.google.com/file/d/1vceTA2TzeVOQOZE4FRjrKM7G0ttHhuXS
- Popcorn_part_71_2.zip - https://drive.google.com/file/d/1N-DuljL07dpaLf_rb8YHbKT5XLDphMaY
- 00:00 - Взрыв монстра
- 00:50 - Баг: в гейте остаётся кусок платформы
- 05:09 - Анализируем анимацию взрыва монстра
- 06:45 - Добавим состояние монстра EMonster_State
- 10:38 - Добавим метод Destroy()
- 11:35 - Добавим в монстра массив взрывающихся шариков
- 13:07 - Добавим класс AExplosive_Ball
- 14:02 - Добавим объявление метода Explode()
- 15:02 - Добавим прототипы методов класса AExplosive_Ball
- 16:47 - Добавим параметры в метод Explode()
- 19:08 - Отрефакторим метод AMonster::Draw()
- 21:34 - Добавим метод Draw_Destroing()
- 23:02 - Рисуем шарик взрыва
- 24:46 - Добавим состояние взрыва EExplosive_Ball_State
- 27:28 - Делаем анимацию в AExplosive_Ball::Act()
- 31:48 - Добавим метод Redraw_Ball()
- 33:01 - Баг: метод Act() не вызывается
- 35:08 - Добавим метод Act_Destroing()
- 36:24 - Исправим заказ перерисовки
- 39:26 - Делаем анимацию угасания шарика
- 42:41 - Рисуем угасающий шарик в Draw()
- 45:33 - Добавим оттенки угасания копипастом из активного кирпича
- 49:13 - Перенесём методы получения оттенков в класс AsTools
- 52:07 - Рисуем очередной оттенок угасающего шарика
- 54:32 - Отладим угасание шарика
- 59:38 - Сделаем стирание монстра
- 01:01:14 - Взрываем 2 шарика
- 01:02:12 - Добавим смещение взрыва во времени
- 01:04:14 - Добавим состояние взрыва Charging
- 01:07:18 - Добавим белую обводку шарика взрыва
- 01:10:03 - Эмулируем множество шариков
- 01:11:25 - Взрываем все шарики
- 01:13:35 - Разнесём шарики в пространстве
- 01:17:08 - Исправим вычисление смещения шариков от центра
- 01:26:12 - Добавим синие шарики взрывов
- 01:31:36 - Popcorn_part_72.zip: пишем код
- Popcorn_part_72.zip - https://drive.google.com/file/d/18G4tTgwAO0-BGGftWnDZyEzgZg-0OoeL
- 00:00 - Движение монстра
- 00:32 - Смещение монстра в AsMonster::Advance()
- 05:39 - Добавим метод Redraw_Monster()
- 08:38 - Закажем перерисовку монстра в его методе Finish_Movement()
- 11:00 - Добавим направление движения монстра
- 12:13 - Задаём направление при активации монстра
- 14:05 - Вычисляем направление выпуска монстра в Emit_At_Gate()
- 17:06 - Вычислим позицию монстра в зависимости от гейта
- 20:29 - Применяем направление для движения монстра
- 24:50 - Делаем случайный выбор направления в Act_Alive()
- 30:01 - Стираем предыдущее изображение монстра
- 31:50 - Сделаем случайный выбор скорости для монстра
- 33:44 - Добавим собственный метод Act() в набор монстров
- 37:20 - Переименуем класс AsGame_Objects_Set
- 38:17 - Добавим состояния набора монстров EMonster_Set_State
- 40:39 - Действия набора монстров в Act() в зависимости от состояний
- 45:02 - Добавим метод активации монстров Activate()
- 46:52 - Добавим в рамку метод Is_Gate_Closed()
- 49:00 - Добавим в гейт метод Is_Closed()
- 51:32 - Добавим максимальное количество живых монстров
- 52:35 - Подсчёт живых монстров перед выпуском нового
- 55:30 - Баг: монстр выходит из гейта выше, чем надо
- 56:44 - Ускорим открытие и закрытие гейта в 2 раза
- 57:32 - Баг: гейт, закрываясь, не становится в свою исходную позицию
- 01:01:19 - Ограничиваем перемещение монстра рамкой уровня
- 01:04:13 - Баг: монстра "выстреливает" из гейта на уровень
- 01:11:00 - Добавим гейту позицию кирпича
- 01:14:34 - Задаём позиции кирпичей для всех гейтов
- 01:16:45 - Добавим метод Long_Open_Gate()
- 01:24:32 - Добавим метод Has_Brick_At()
- 01:32:55 - Popcorn_part_73.zip: пишем код
- Popcorn_part_73.zip - https://drive.google.com/file/d/1p2UXPtxSdOV1Ph6-RjSbQN5CuR86lkrH
- 00:00 - Движение монстра, этап 2
- 00:39 - Выносим класс AExplosive_Ball в свою пару файлов
- 03:47 - Выносим класс AMonster в свою пару файлов
- 05:55 - Popcorn_part_74_1.zip: пишем код
- 06:10 - Корректируем следующую позицию монстра в Advance()
- 09:46 - Выносим код в Get_Monster_Rect()
- 13:59 - Добавим в уровень метод Has_Brick_At()
- 25:34 - Выбираем свободное направление для монстра в Advance()
- 32:54 - Баг: платформа не двигается после автостарта мячика
- 36:10 - Исправляем постановку мячика на платформу в Set_On_Platform()
- 39:01 - Добавим столкновения с монстрами в Init_Engine()
- 40:25 - Наследуем AsMonster_Set от AHit_Checker
- 43:19 - Наследуем AMonster от AHit_Checker
- 46:13 - Перенесём метод Reflect_On_Circle() в класс AsTools
- 50:20 - Исправим вызов Reflect_On_Circle() в Check_Hit() платформы
- 52:55 - Почему не стоит подключать лишний заголовочный файл в *.cpp
- 56:37 - Добавим интерфейсный класс ABall_Object
- 01:00:47 - Перенесём константу Radius из мячика в конфиг
- 01:03:58 - Исправим Check_Hit() у монстра
- 01:05:06 - Заменяем использование ABall на ABall_Object
- 01:11:57 - Переносим в интерфейс все нужные методы
- 01:17:00 - Убираем лишние подключения файла Ball.h
- 01:20:23 - Баг: добавление 4-го хит-чекера игнорируется
- 01:24:21 - Баг: шарики взрывов рисуются для движущегося монстра
- 01:27:05 - Переводим состояние монстра в Missing в Act_Destroing()
- 01:31:40 - Размещаем методы ABall в правильном порядке
- 01:33:33 - Popcorn_part_74_2.zip: пишем код
- Popcorn_part_74_1.zip - https://drive.google.com/file/d/1LXsbZa_xODWoONrkb28rqmdZELfWdalI
- Popcorn_part_74_2.zip - https://drive.google.com/file/d/1FmiR_cgRjo7o6RRRr-naata04YbMe_n4
- 00:00 - Движение монстра, этап 3
- 00:17 - Уничтожаем монстра в AMonster::Check_Hit()
- 04:50 - Баг: монстры залазят за линию пола
- 06:15 - Баги: монстры остаются после утраты мячика и мячик отражается от взрывов
- 07:52 - Убираем отражение от взрывов в AMonster::Check_Hit()
- 08:59 - Баг: остаётся кусочек платформы при растаивании
- 09:20 - Баг: двойное выкатывание платформы
- 09:44 - Баг: остаются красные пиксели от растаявшей платформы
- 10:38 - Воспроизводим баг с красными пикселями
- 13:36 - Закажем перерисовку в Act_For_Meltdown_State()
- 17:31 - Запретим выход монстров в 7-м гейте в Long_Open_Gate()
- 20:00 - Делаем корректную остановку уровня в Play_Level()
- 21:52 - Добавим метод Destroy_All()
- 23:02 - Добавим метод Disable_All()
- 25:15 - Добавим в платформу список хит-чекеров
- 27:42 - Добавим обработку хит-чекеров в методе Advance() платформы
- 30:17 - Добавим третий перегруженный метод Check_Hit()
- 33:03 - Проверяем столкновение прямоугольников в AMonster::Check_Hit()
- 36:32 - Исправим баг с остатком платформы при растаивании
- 38:21 - Popcorn_part_75.zip: пишем код
- Popcorn_part_75.zip - https://drive.google.com/file/d/1xCYxI-kgzOvoW0ZujMj3gaBz3dh0t-kO
- 00:00 - Двойная буферизация
- 00:19 - Исправим мерцание мячика
- 01:56 - Анализируем причину мерцания изображения
- 03:11 - Что такое "двойная буферизация"
- 05:02 - Буфер и контекст устройства
- 06:29 - Смотрим в MSDN как создавать контекст устройства
- 18:52 - Создаём контекст и используем его при обработке WM_PAINT
- 24:51 - Вынесем код в метод On_Paint()
- 26:59 - Отрефакторим On_Paint(), чтобы не создавать контекст на каждый кадр
- 32:25 - Выносим функциональность контекста в класс AsFrame_DC
- 39:38 - Добавим деструктор ~AsFrame_DC()
- 41:18 - Зальём контекст фоновым цветом и поправим имена в AsFrame_DC
- 43:18 - Добавим класс AsMain_Window и метод Main()
- 47:03 - Перенесём методы главного окна в класс AsMain_Window
- 52:10 - Перенесём глобальные данные в класс AsMain_Window
- 55:23 - Добавим статический указатель на главное окно
- 58:31 - Отрефакторим аргументы методов класса AsMain_Window
- 01:05:39 - Popcorn_part_76.zip: пишем код
- Popcorn_part_76.zip - https://drive.google.com/file/d/1BowISKSQIQLW_cFx1a_u7hpUodez5aF_
- 00:00 - Монстр "Комета"
- 00:17 - Выбираем лучший способ реализации второго монстра
- 03:46 - Добавим пару классов AMonster_Eye и AMonster_Comet
- 05:50 - Сделаем виртуальным метод Draw_Alive()
- 08:23 - Сделаем виртуальным метод Act_Alive()
- 09:15 - Добавим пустые методы классов монстра и кометы
- 10:49 - Переносим код методов из AMonster в AMonster_Eye
- 11:34 - Разделим данные между AMonster и AMonster_Eye
- 16:31 - Вынесем код в метод On_Activation()
- 20:00 - Заменим экземпляры монстров на указатели в наборе монстров
- 22:25 - Добавим проверку на нулевой указатель
- 27:22 - Баг: монстры не появляются из гейта
- 29:59 - Удаляем монстров в методе Act()
- 32:04 - Добавим метод Is_Finished() и уберём Is_Active()
- 34:52 - Баг: монстр повторно взрывается при утрате мячика
- 37:46 - Вынсем код в метод Change_Direction()
- 40:27 - Popcorn_part_77_1.zip: пишем код
- 40:53 - Сделаем копипастом поворот пространства для Draw_Alive()
- 47:05 - Готовим чертёж монстра-кометы
- 51:43 - Рисуем фон и шарик кометы
- 58:14 - Рисуем шлейф кометы
- 59:33 - Добавим цвет Monster_Comet_Tail
- 01:00:58 - Рисуем дугу шлейфа
- 01:06:47 - Рисуем вторую дугу
- 01:10:48 - Рисуем вторую комету
- 01:14:41 - Делаем анимацию вращения комет
- 01:22:05 - Добавим монстру-комете свой метод Clear()
- 01:24:37 - Зададим случайную скорость вращения
- 01:27:19 - Добавим случайный выбор монстра
- 01:28:36 - Баг: монстры не анимируются в гейте
- 01:30:44 - Popcorn_part_77_2.zip: пишем код
- Popcorn_part_77_1.zip - https://drive.google.com/file/d/1-SrmeGtujMEjIRSPrJVZM30uLmVkr15V
- Popcorn_part_77_2.zip - https://drive.google.com/file/d/1e-SUuW89ixLFyjgBrAGjduV32RmuchcI
- 00:00 - Логотип игры
- 02:02 - Перенесём в движок константу Timer_ID
- 03:39 - Добавим класс AsInfo_Panel
- 07:04 - Добавим в движок модуль Info_Panel
- 07:28 - Добавим заготовки методов инфо-панели
- 08:50 - Определяем позиции и размеры верхней и нижней плашки
- 13:49 - Рисуем прямоугольники плашек
- 18:14 - Уберём чёрную однопиксельную полоску
- 19:38 - Решаем, как нам лучше вывести надписи
- 21:38 - Смотрим в MSDN описание функции TextOut()
- 23:55 - Выводим строку логотипа в методе Draw()
- 29:52 - Ищем в MSDN пример создания логического шрифта
- 32:57 - Добавим выбор шрифта в нашу программу
- 36:40 - Выбираем подходящие шрифты
- 41:03 - Создадим логический шрифт для Arial
- 49:38 - Вынесем код в метод Choose_Font()
- 50:33 - Ищем в MSDN функции для цвета текста
- 53:05 - Применяем функции для установки цвета текста
- 55:01 - Выводим тень под буквами
- 01:00:57 - Сделаем шрифт Logo_Pop_Font
- 01:07:22 - Popcorn_part_78.zip: пишем код
- Popcorn_part_78.zip - https://drive.google.com/file/d/1XVJklxjd2jlo1yvvfjhvyzSNFhwpfdez
- 00:00 - Информационная панель
- 00:19 - Определяем, как рисовать рамку
- 02:10 - Рисуем белую линию
- 05:14 - Выносим значения координат в переменные
- 09:00 - Добавим цвет и отрисуем фоновую линию
- 11:22 - Перенесём цвета рамки в класс AsInfo_Panel и проинициализируем их в методе Init()
- 15:31 - Добавим деструктор класса AsInfo_Panel
- 16:00 - Перенесём код создания шрифтов в Init()
- 16:53 - Вызовем Init() в методе движка Init_Engine()
- 17:40 - Добавим деструктор цвета ~AColor()
- 19:30 - Подберём оттенок цвета для фона
- 21:08 - Добавим цвет фона Dark_Blue и применим его
- 23:57 - Повышаем эффективность отрисовки рамки
- 26:03 - Рисуем плашку под именем игрока
- 28:32 - Добавим цвет Dark_Red
- 30:22 - Добавим вторую плашку под счёт
- 31:32 - Добавим шрифт для имени игрока Name_Font
- 32:25 - Выводим имя игрока
- 33:34 - Вычисляем длину строки
- 35:29 - Увеличим шрифт и отцентрируем имя игрока
- 37:01 - Применим моноширинный шрифт
- 42:11 - Вычисляем длину строки
- 46:02 - Центрируем строку в плашке
- 48:33 - Вынесем координаты плашки в RECT
- 51:57 - Перенесём код в метод Draw_String()
- 53:54 - Выведем строку счёта
- 55:45 - Добавим тень под текстом
- 58:57 - Вынесем константы счёта в класс
- 01:01:07 - Добавим шрифт для счёта Score_Font
- 01:04:44 - Выведем счёт белым цветом
- 01:06:34 - Выведем падающую букву "П" для индикатора пола
- 01:10:51 - Добавим в падающую букву метод Show_Full_Size()
- 01:13:09 - Добавим буквы для жизней и монстров
- 01:15:59 - Рисуем индикатор пола
- 01:21:20 - Рисуем два оставшихся индикатора
- 01:23:03 - Выравниваем индикаторы и буквы
- 01:28:21 - Рисуем дополнительную жизнь
- 01:35:05 - Выносим код в метод Draw_Extra_Life()
- 01:36:56 - Выводим все дополнительные жизни
- 01:41:33 - Popcorn_part_79.zip: пишем код
- Popcorn_part_79.zip - https://drive.google.com/file/d/1fi9zfvdCnyFSz_BOWySIfvR37hmiaTE1
- 00:00 - Строки в информационной панели
- 00:19 - Выносим класс инфопанели в отдельную пару файлов
- 02:39 - Создадим фильтр #Screen
- 04:13 - Popcorn_part_80_1.zip: пишем код
- 04:32 - Про строки из стандартной библиотеки
- 05:56 - Краткий обзор стандартной библиотеки
- 09:49 - Обзор строкового класса std::string
- 17:15 - Добавим переменную Player_Name
- 19:52 - Добавим переменную Score
- 20:54 - Выведем текущий счёт игрока
- 22:54 - Про функцию itoa()
- 26:45 - Добавим к строке строковое представление числа
- 30:35 - Выведем каждый тик таймера
- 32:39 - Добавим наш строковый класс AString
- 35:36 - Добавим пару конструкторов в AString
- 37:17 - Будем передавать ссылку на наш AString вместо const wchar_t *
- 38:10 - Добавим метод Append()
- 40:17 - Добавим метод Get_Content()
- 41:46 - Добавим метод Get_Length()
- 43:31 - Про функцию sprintf()
- 46:04 - Про формат вывода функции sprintf()
- 48:05 - Применим sprintf() для вывода счёта
- 50:08 - Перенесём класс AString в Common.cpp/h
- 51:19 - Вынесем код в метод Show_Extra_Lives()
- 52:55 - Выведем количество оставшихся жизней
- 56:05 - Popcorn_part_80_2.zip: пишем код
- Popcorn_part_80_1.zip - https://drive.google.com/file/d/1891W55S7eh8c-PesYwVDr1IBDf34IQDS
- Popcorn_part_80_2.zip - https://drive.google.com/file/d/1PYdOBXqdyP67R3CicrcKwIaNsqqKUokF
- 00:00 - Вектор std::vector
- 00:19 - Контейнеры стандартной библиотеки
- 03:33 - Пример применения вектора
- 11:10 - Как мы могли бы применить вектор в нашей программе
- 13:15 - Пример создания вектора произвольного размера
- 16:16 - Заменим в движке массив модулей на вектор
- 21:38 - Исправим добавление модуля в Add_Next_Module()
- 26:07 - Делаем range-based for цикл по вектору в Act()
- 32:03 - Исправим циклы в Draw_Frame()
- 33:28 - Исправим циклы в Advance_Movers()
- 36:02 - Какие массивы лучше не переводить в вектор
- 38:13 - Заменим массив падающих букв на вектор
- 41:14 - Исправим цикл в методе Act_Objects()
- 43:53 - Цикл по вектору через итератор
- 56:22 - Исправим цикл в Clear_Objects()
- 59:02 - Исправим цикл из Draw_Objects()
- 01:00:35 - Исправим Get_Next_Falling_Letter()
- 01:02:24 - Исправим Add_Falling_Letter()
- 01:04:16 - Исправим Delete_Objects()
- 01:07:32 - Заменим массив активных кирпичей на вектор
- 01:08:17 - Изменим тип элементов наших векторов
- 01:10:10 - Исправим Act_Objects(), Get_Next_Falling_Letter() и Create_Active_Brick()
- 01:11:29 - Исправим Add_New_Active_Brick()
- 01:12:36 - Удалим лишние методы Delete_Objects(), Act_Objects() и Draw_Objects()
- 01:14:22 - Popcorn_part_81.zip: пишем код
- Popcorn_part_81.zip - https://drive.google.com/file/d/1RWS_nYyCKEsCrYtv0s76SFggri_t6A8T
- 00:00 - Замена массивов на вектора
- 01:20 - Выбираем массивы для замены на вектора
- 09:15 - Заменим массив мячиков на вектор
- 10:57 - Добавим конструктор AsBall_Set
- 12:58 - Исправим цикл в Act()
- 15:22 - Исправим все циклы по мячикам
- 20:25 - Исправим Get_Next_Game_Object()
- 21:19 - Заменим массив гейтов на вектор и исправим деструктор рамки
- 24:22 - Исправим конструктор рамки
- 25:20 - Исправим метод Open_Gate()
- 26:48 - Исправим метод Long_Open_Gate()
- 27:56 - Исправим остальные методы рамки
- 31:25 - Заменим массив хит-чекеров на вектор
- 34:33 - Заменим массив лазерных лучей на вектор
- 38:11 - Заменим массив взрывающихся шариков на вектор
- 41:32 - Заменим массив тиков моргания глаза на вектор
- 43:38 - Заменим массив монстров на вектор
- 51:10 - Исправим выпускание монстра в Emit_At_Gate()
- 54:06 - Исправим Destroy_All() и Get_Next_Game_Object()
- 56:27 - Переключим проект обратно в архитектуру x86
- 58:59 - Исправляем предупреждения компилятора
- 01:02:02 - Баг: шарики взрыва угасают не правильно
- 01:09:57 - Добавим operator = в класс AColor
- 01:13:07 - Заменим operator = на метод Set_As()
- 01:17:14 - Перенесём класс AColor в Common.cpp/h
- 01:18:46 - Assertion при растраивании кирпичей
- 01:23:15 - Баг: первый кирпич тает не до конца
- 01:27:05 - Баг: мячики не правильно растроились
- 01:30:52 - Вычислим разницу между текущим и новым направлением
- 01:33:43 - Пытаемся воспроизвести баг
- 01:37:05 - Схема того, как надо разводить мячики
- 01:38:55 - Исправляем поворот мячиков
- 01:40:23 - Вынесем код в метод Turn_Tripled_Ball()
- 01:45:48 - Popcorn_part_82.zip: пишем код
- Popcorn_part_82.zip - https://drive.google.com/file/d/1MwvWew_3poNwRFJyblNZakN35PYptu4G
- 00:00 - Подсчёт очков и убывающие индикаторы
- 00:59 - Смотрим, сколько очков дают за действия в оригинальной игре
- 05:57 - Опишем типы игровых событий через EScore_Event_Type
- 07:33 - Добавим метод Update_Score()
- 10:07 - Подсчитываем очки при попадании в кирпич
- 11:48 - Подсчитываем очки при попадании в монстра
- 12:27 - Подсчитываем очки при ловле буквы
- 13:05 - Перенесём подсчёт очков и жизней в инфопанель
- 14:57 - Закажем перерисовку инфопанели в Update_Score()
- 18:23 - Разделим область инфопанели на две части
- 24:13 - Исправим метод Draw() рисования инфопанели
- 26:58 - Вынесем позиции логотипа в константы
- 29:30 - Смотрим, как угасают индикаторы в оригинальной игре
- 31:10 - Рисуем внутреннюю часть индикатора
- 33:16 - Добавим класс AIndicator
- 36:02 - Добавим два индикатора в инфопанель
- 38:05 - Добавим код рисования индикаторов в метод Draw()
- 41:22 - Включаем индикатор пола
- 45:25 - Рисуем убывающую шкалу индикатора
- 50:26 - Добавим анимацию убывания шкалы
- 55:04 - Отладим анимацию индикатора
- 01:00:05 - Popcorn_part_83.zip: пишем код
- Popcorn_part_83.zip - https://drive.google.com/file/d/1YX58m7S80Kf0B5wjtFLjXNVJekLcmFqH
- 00:00 - Передача и обработка сообщений индикаторов
- 00:17 - Как сейчас работают наши индикаторы
- 03:04 - Делаем прототип передачи сообщения
- 05:35 - Делаем прототип приёма и обработки сообщения
- 08:57 - Добавим тип и класс сообщений
- 11:22 - Добавим методы для приёма и передачи сообщений
- 17:23 - Вынесем очередь сообщений и её методы в AsMessage_Manager
- 21:20 - Проверяем работу очереди сообщений
- 25:34 - Баг: отключённый пол не стирается
- 29:04 - Добавим тип сообщения в индикатор
- 31:28 - Выносим код обработки сообщения в Handle_Message()
- 33:13 - Добавим остановку монстров Freeze()
- 35:59 - Исправим Freeze() на Set_Freeze_State()
- 38:49 - Баг: замёрзший монстр выходит из гейта
- 42:59 - Баг: гейты открываются для замороженных монстров
- 44:35 - Исправляем баг с застрявшим в гейте монстром
- 49:25 - Добавим индикаторам метод сброса Reset()
- 52:09 - Исправим Message_Was_Sent на Neet_To_Notify
- 54:05 - Вынесем AIndicator в свою пару файлов
- 55:32 - Popcorn_part_84_1: пишем код
- 56:27 - Обновим план разработки
- 58:55 - Отобразим изменение дополнительных жизней на индикаторе
- 01:04:01 - Уменьшим количество жизней при утрате мячика
- 01:08:49 - Сделаем обработку отмены действий методом Cancel()
- 01:13:08 - Посмотрим, как отменяются состояния платформы
- 01:14:53 - Баг: лазерная платформа не отменяется
- 01:21:53 - Popcorn_part_84_2: пишем код
- Popcorn_part_84_1.zip - https://drive.google.com/file/d/1mv0nvwEqUX1nUdQ_kWSYkKWLt37kU5ve
- Popcorn_part_84_2.zip - https://drive.google.com/file/d/1W3DRQ4guI5XP8ynsDCGDD2Oazw2ZwTGx
- 00:00 - Делаем первые 4 уровня игры
- 00:43 - Как представлены уровни в нашей игре
- 01:43 - Исправим 1-й уровень
- 02:31 - Сделаем 2-й уровень
- 06:37 - Заменим массив Teleport_Brick_Pos на вектор
- 08:59 - Исправим сканирование телепортов в Set_Current_Level()
- 10:51 - Добавим конструкторы в структуру SPoint
- 15:23 - Продолжим исправление Set_Current_Level()
- 17:28 - Применим метод вектора emplace_back()
- 19:58 - Исправим использование размера вектора телепортов
- 22:06 - Вынесем данные уровня в класс ALevel_Data
- 27:11 - Исправим метод Set_Current_Level()
- 29:55 - Добавим вектор уровней
- 32:00 - Создадим уровни в методе уровня Init()
- 36:25 - Вынесем класс ALevel_Data в отдельную пару файлов
- 38:31 - Popcorn_part_85_1.zip: пишем код
- 38:46 - Добавим заготовки под остальные 8 уровней
- 40:26 - Сделаем 3-й уровень
- 43:03 - Баг: монстры застряют в гейтах
- 49:24 - Сделаем 4-й уровень
- 52:17 - Поднимем гейты 2 и 3 на 1 игровой пиксель
- 54:12 - Опустим монстра на полпикселя
- 57:11 - Баг: монстр цепляется за ячейку
- 01:08:32 - Баг: монстры ходят сквозь кирпичи
- 01:20:18 - Уменьшим шаг поворота угла для монстра
- 01:24:51 - Popcorn_part_85_2.zip: пишем код
- Popcorn_part_85_1.zip - https://drive.google.com/file/d/1-yaNOLMRWwzPrZ0b1aC4c4Y2mPysEh9I
- Popcorn_part_85_2.zip - https://drive.google.com/file/d/122t5JcSCJDheGp5y6dEWytsoCnCfo2Qn
- 00:00 - Делаем остальные 6 уровней игры
- 00:22 - Добавим 5-й уровень
- 03:11 - Добавим 6-й уровень
- 06:17 - Мячик пролетел сквозь кирпичи
- 14:50 - Баг: мячик, приклеенный на платформу, не смещается
- 19:00 - Баг: монстры застряют в нижних гейтах
- 26:14 - Баг: монстры заходят на кирпичи
- 35:39 - Исправим период выбора направления движения монстров
- 38:01 - Добавим 7-й уровень
- 40:45 - Баг: мячик на парашюте улетает вверх
- 44:11 - Баг: мячик на парашюте стирает кирпичи
- 46:39 - Уберём отражение от кирпича для мячика на парашюте
- 50:39 - Баг: мячик летает почти вертикально
- 01:01:10 - Добавим 8-й уровень
- 01:05:38 - Поместим указатели на уровни в массив Levels_Array
- 01:09:04 - Добавим в описание уровня указатель на рекламу
- 01:14:36 - Добавим 9-й уровень
- 01:19:18 - Добавим 10-й уровень
- 01:23:45 - Исправим генерацию случайного числа в Rand()
- 01:26:02 - Popcorn_part_86.zip: пишем код
- Popcorn_part_86.zip - https://drive.google.com/file/d/1KnYiIcOqBTG7ScIYEMb7JVC3isTGdt3y
- 00:00 - Рисуем швабру, стирающую уровень
- 00:19 - Обновим статус задач проекта
- 01:53 - Смотрим на оригинальную анимацию перехода на новый уровень
- 08:09 - Подбираем имя класса для швабры
- 12:28 - Создадим класс AsMop
- 15:16 - Рисуем стирающую часть швабры
- 20:13 - Рисуем индикатор швабры
- 30:44 - Рисуем синий индикатор
- 33:22 - Добавим класс AMop_Indicator
- 36:28 - Перенесём код рисования индикатора в его метод Draw()
- 39:42 - Добавим Indicator_Rect
- 43:12 - Создадим множество индикаторов
- 51:15 - Добавим угасающие оттенки цвета индикаторов
- 54:20 - Вынесем код в класс AColor_Fade
- 59:23 - Заменим массив оттенков на AColor_Fade для шариков взрыва монстра
- 01:03:53 - Исправим Get_Fading_Color()
- 01:11:40 - Применим AColor_Fade для красно-синих кирпичей и перенесём AColor_Fade в конфиг
- 01:15:47 - Применим AColor_Fade для индикаторов швабры
- 01:16:40 - Сделаем анимацию индикатора
- 01:26:39 - Добавим перегрузку метода Get_Fading_Color()
- 01:29:20 - Сделаем растяжку от синего к красному для индикаторов
- 01:31:29 - Добавим смещение по времени для индикаторов
- 01:33:02 - Настроим анимацию индикаторов
- 01:35:04 - Popcorn_part_87.zip: пишем код
- Popcorn_part_87.zip - https://drive.google.com/file/d/1bF53twI8CbclhFAmqTNhwuSn00yvIoTn
- 00:00 - Анимация швабры
- 00:49 - Добавим класс AMop_Cylinder
- 03:54 - Добавим первый цилиндр в швабру
- 08:26 - Рисуем основную часть цилиндра
- 12:20 - Рисуем крепление цилиндра
- 17:59 - Рисуем все цилиндры швабры
- 23:18 - Добавим очистку уровня в Erase_Level()
- 28:07 - Сделаем изменение позиции по Y для индикаторов и цилиндров
- 34:08 - Сделаем анимацию раздвигания цилиндров
- 38:11 - Добавим в швабру метод Set_Mop()
- 40:32 - Добавим в цилиндр метод Set_Height_For()
- 44:09 - Померяем высоту цилиндров
- 48:03 - Добавим перерисовку прямоугольника швабры
- 50:58 - Вычислим высоту всех цилиндров
- 54:15 - Добавим перерисовку предыдущего прямоугольника швабры
- 55:24 - Добавим стирание для швабры в методе Clear()
- 57:49 - Добавим сеттер для позиции по Y цилиндра
- 01:02:04 - Вычислим текущую высоту каждого цилиндра
- 01:05:47 - Добавим стирание цилиндра в методе Clear()
- 01:08:05 - Исправим высоту стирания цилиндра
- 01:09:51 - Исправим интерпретацию высоты цилиндра
- 01:18:18 - Исправим массив с высотой цилиндров
- 01:21:55 - Увеличим скорость анимации
- 01:23:17 - Вынесем класс AsMop в свою пару файлов
- 01:25:13 - Вынесем класс AMop_Indicator в свою пару файлов
- 01:26:25 - Вынесем класс AMop_Cylinder в свою пару файлов
- 01:28:15 - Popcorn_part_88.zip: пишем код
- Popcorn_part_88.zip - https://drive.google.com/file/d/1yQ9kOMpbCZbxwoM4ZSO84nKdtxx068P_
- 00:00 - Смена уровней
- 00:31 - Стираем уровень под шваброй
- 02:22 - Добавим метод Clear_Area()
- 05:09 - Добавим новое игровое состояние Mop_Level
- 08:35 - Добавим в уровень метод Mop_Level()
- 11:05 - Добавим в уровень метод Is_Level_Mopping_Done()
- 12:19 - Добавим перечисление EMop_State
- 16:02 - Учитываем состояния швабры в методе анимации Act()
- 19:29 - Добавим геттер Get_Mop_State()
- 21:54 - Добавим метод Show_Level()
- 23:11 - Сведём методы Erase_Level() и Show_Level() в Activate()
- 25:51 - Добавим состояния швабры для подъёма и опускания
- 27:20 - Исправим использование состояний швабры
- 28:45 - Задаём стартовую позицию сложенной швабры
- 32:25 - Добавим метод Get_Cylinders_Height()
- 34:03 - Делаем анимацию подъёма швабры
- 39:12 - Переводим анимацию в расширение после подъёма
- 40:44 - Переводим анимацию в спуск после опускания
- 45:02 - Рефакторим машину состояний анимации швабры
- 48:30 - Вынесем код в Act_Lifting()
- 55:26 - Оптимизация машины состояний для стирания и показа уровня
- 59:52 - Финальный рефакторинг машины состояний
- 01:01:48 - Popcorn_part_89.zip: пишем код
- Popcorn_part_89.zip - https://drive.google.com/file/d/1RuYrSe2bZqy1UcMDn748oQ4Y6eAIY0uo
- 00:00 - Настройка перехода по уровням игры
- 00:20 - Обновим состояние плана разработки
- 01:13 - Исправим конструктор ALevel_Data
- 04:40 - Добавим метод Get_Available_Bricks_Count()
- 10:44 - Добавим учёт оставшихся кирпичей
- 15:26 - Отправим новое сообщение Level_Done
- 18:03 - Добавим обработку сообщения в Handle_Message()
- 20:10 - Добавим заглушку для Game_Won()
- 20:49 - Вынесем код в метод Stop_Play()
- 22:39 - Добавим метод Mop_Next_Level()
- 27:02 - Уменьшим количество учитываемых кирпичей до 3
- 28:06 - Добавим метод Is_Mopping_Done()
- 34:04 - Добавим метод Is_Cleaning_Done()
- 35:43 - Баг: множество сообщений об окончании уровня
- 38:01 - Добавим метод Disable_All_Balls()
- 42:35 - Добавим состояние игры Finish_Level
- 46:32 - Добавим метод Can_Mop_Next_Level()
- 48:13 - Добавим метод Are_All_Destroyed()
- 49:25 - Исправим удаление монстров
- 52:18 - Исправим стирание мячиков
- 54:59 - Баг: количество жизней уменьшается при успешном завершении уровня
- 57:23 - Баг: монстр всё время выходит из одного и того же гейта
- 58:38 - Баг: монстр опять застрял в гейте
- 01:06:20 - Обновим план разработки
- 01:07:30 - Popcorn_part_90.zip: пишем код
- Popcorn_part_90.zip - https://drive.google.com/file/d/1u2DCLoA7Motz0bflCI48oV72AoWAvp9J
- 00:00 - Контролы, виджеты и табличка уровня
- 00:22 - Смотрим на табличку уровня в оригинальной игре
- 02:32 - Добавим в уровень объект Level_Title
- 04:13 - Добавим класс AsLevel_Title
- 07:30 - Применим переменную Is_Visible в методах
- 08:07 - Добавим вывод надписи "УРОВЕНЬ"
- 11:24 - Добавим методы Show_Title() и Hide_Title()
- 15:25 - Про контролы и виджеты
- 21:50 - Добавим класс ALabel
- 29:05 - Применим метку для вывода имени игрока
- 33:04 - Пытаемся задать фонт для метки
- 36:29 - Добавим класс AFont
- 40:22 - Применим AFont как шрифт для метки
- 42:39 - Использование ссылки на объект при инициализации
- 45:40 - Добавим фонту метод Select()
- 48:21 - Сделаем вывод счёта через метку
- 52:42 - Добавим в метку цвет
- 54:47 - Перенесём создание лого-фонтов в конфиг
- 57:08 - Перенесём цвета Dark_Red и Dark_Blue в конструктор
- 59:59 - Выводим табличку уровня двумя метками
- 01:06:46 - Добавим прямоугольник Title_Rect
- 01:08:48 - Выведем табличку после очистки уровня
- 01:10:24 - Добавим состояния таблички ELevel_Title_State
- 01:14:45 - Добавим количество знаков для строкового представления числа
- 01:21:23 - Баг: постоянная перерисовка инфопанели
- 01:23:37 - Проверяем переходы по уровням
- 01:25:28 - Исправим условия включения моппинга уровня
- 01:27:30 - Popcorn_part_91.zip: пишем код
- Popcorn_part_91.zip - https://drive.google.com/file/d/1EfYL7B1NHpJbz40AzCoeXhKNFMi2m6mT
- 00:00 - Финальные титры
- 00:27 - Анализируем оригинальную анимацию финальных титров
- 03:55 - Добавим класс AFinal_Letter
- 11:29 - Добавим букву "К" в уровень
- 14:35 - Выберем шрифт "MV Boli"
- 19:05 - Выберем шрифт "Impact"
- 22:31 - Выберем шрифт "Comic Sans MS" с курсивом
- 24:33 - Добавим в класс AFont поддержку курсива
- 26:48 - Подберём размер символов
- 28:33 - Исправим рисование AFinal_Letter
- 33:01 - Добавим координаты для финальной буквы
- 37:37 - Добавим массив букв "КОНЕЦ ИГРЫ"
- 41:53 - Выравниваем буквы по горизонтали
- 49:50 - Вынесем функциональность титров в AsGame_Title
- 55:22 - Добавим в AsGame_Title метод Show()
- 59:11 - Добавим массив букв "ПОБЕДА!"
- 01:00:47 - Выравниваем буквы победы по горизонтали
- 01:06:10 - Смотрим оригинальную анимацию уничтожения букв
- 01:08:08 - Добавим состояния EGame_Title_State
- 01:10:36 - Добавим стирание финальных титров
- 01:16:51 - Включаем надпись при утрате мячика
- 01:19:46 - Выводим надпись под кирпичами
- 01:24:32 - Вынесем код в метод Is_Destroying_Complete()
- 01:28:59 - Делаем анимацию спуска надписи
- 01:40:56 - Баг: надпись не едет
- 01:44:01 - Popcorn_part_92.zip: пишем код
- Popcorn_part_92.zip - https://drive.google.com/file/d/1ttnI6qumNVQLvHiz47kzXth4VunAzSuz
- 00:00 - Анимация финальных титров
- 00:20 - Добавим состояние титров Game_Over_Show
- 05:47 - Добавим обработку состояния Game_Over_Destroy
- 10:06 - Вынесем логику взрывающихся шариков в класс AExplosion
- 15:23 - Переносим код начала взрывов в Start_Explosion()
- 20:33 - Перенесём метод Draw_Destroying() в Draw_Explosion()
- 22:33 - Вынесем анимацию в метод Act_On_Explosion()
- 27:34 - Popcorn_part_93_1.zip: пишем код
- 27:47 - Вынесем класс AExplosion в свою пару файлов
- 30:38 - Вынесем класс AsLevel_Title
- 31:55 - Вынесем класс ALabel
- 33:53 - Вынесем класс AFinal_Letter
- 35:17 - Вынесем класс AsGame_Title
- 39:07 - Popcorn_part_93_2.zip: пишем код
- 39:23 - Отнаследуем финальную букву от AExplosion
- 44:35 - Добавим анимацию и рисование взрывов
- 46:31 - Смотрим в отладчике, как уничтожаются буквы
- 49:19 - Исправим анимацию финальных титров
- 53:40 - Добавим код для Is_Finished()
- 55:00 - Баг: Шарики не рисуются
- 56:11 - Баг: Шарики анимируются слишком медленно
- 59:10 - Баг: Шарики не закрывают буквы полностью
- 01:00:44 - Вынесем код в метод Destroy_Letters()
- 01:05:40 - Вычислим размеры буквы
- 01:10:05 - Баг: остаются кусочки букв
- 01:21:10 - Добавим состояния финальной буквы
- 01:23:57 - Исправим отрисовку буквы по состояниям
- 01:30:20 - Вынесем код в Draw_Letter()
- 01:32:38 - Popcorn_part_93_3.zip: пишем код
- Popcorn_part_93_1.zip - https://drive.google.com/file/d/1e5kY6JwZj3GCSkVjvqirEp44UgvnB1bv
- Popcorn_part_93_2.zip - https://drive.google.com/file/d/1qdftfOYH46dGaK9sb2I5C259SGsiv5Xx
- Popcorn_part_93_3.zip - https://drive.google.com/file/d/1geRzs_gZUhNqfvnmN5Cz6uNWUqs6Mb0b
- 00:00 - Победа в игре и ввод имени игрока
- 00:19 - Отладим вывод надписи "Победа"
- 01:55 - Добавим анимацию букв "Победа"
- 04:05 - Добавим метод Animate_Game_Won()
- 07:00 - Добавим метод Set_Color()
- 10:46 - Баг: победа не едет
- 12:15 - Баг: буквы не перемигиваются
- 13:31 - Добавим состояние Color_Letter для финальной буквы
- 15:21 - Вынесем код в Setup_Letter_Rect()
- 17:24 - Включим "победу" при успешном завершении игры
- 19:36 - Добавим состояние игры Game_Won
- 23:09 - Баг: восклицательный знак закрашивается не до конца
- 24:52 - Баг: буквы "КОНЕЦ ИГРЫ" обрезаются при взрывах
- 28:29 - Баг: всё время находятся в состоянии конца анимации
- 31:55 - Popcorn_part_94_1.zip: пишем код
- 32:11 - Обновим план
- 33:30 - Добавим состояние для ввода имени игрока
- 36:37 - Смотрим в MSDN про сообщение WM_CHAR
- 39:14 - Добавим обработку WM_CHAR и метод On_Char()
- 40:50 - Добавим метод Edit_Player_Name()
- 44:43 - Добавим в строку перегруженный метод Append()
- 48:11 - Баг: буквы при вводе не отображаются
- 49:28 - Добавим в класс метки метод Append()
- 51:29 - Делаем отложенное вычисление длины строки
- 54:17 - Добавим метод Delete_Last_Symbol()
- 57:36 - Добавим удаление символов
- 01:00:05 - Смотрим символы на unicode-table.com
- 01:06:45 - Поднимаем регистр букв
- 01:12:29 - Добавим обработку Enter при вводе имени
- 01:17:00 - Добавим надпись "ВВЕДИТЕ ИМЯ"
- 01:19:44 - Сделаем мигающую надпись
- 01:24:41 - Баг: редактирование надписи "ВВЕДИТЕ ИМЯ"
- 01:27:58 - Popcorn_part_94_2.zip: пишем код
- Popcorn_part_94_1.zip - https://drive.google.com/file/d/1goQKN_VTRBn6vW0skwKrscSgEBEGcDAF
- Popcorn_part_94_2.zip - https://drive.google.com/file/d/1HZrpu87FfyJSLZNl4ysqhst7_ALEzWWo
- 00:00 - Финальная настройка и завершение проекта
- 00:19 - Обновим план
- 01:31 - Сохраним все исходные файлы в формате Юникода
- 04:31 - Уберём комментарии "//!!! Надо сделать!"
- 06:09 - Исправим наследование швабры AsMop
- 07:42 - Представим строками заголовок и класс окна
- 12:25 - Убираем закомментированный код
- 18:41 - Popcorn_part_95_1.zip: пишем код
- 19:10 - Исправим количество жизней
- 20:11 - Смотрим в оригинальной игре количество очков за кирпичи
- 26:50 - Исправим подсчёт очков в Update_Score()
- 30:26 - Исправим подсчёт очков в On_Hit()
- 32:35 - Проверим подсчёт очков
- 35:16 - Подсчитаем вероятность выпадения букв в оригинальной игре
- 39:21 - Установим вероятность выпадения буквы
- 40:00 - Установим лимит монстров
- 43:18 - Баг: чёрные кирпичи
- 45:29 - Перенесём оттенки угасающего цвета в конфиг
- 53:36 - Исправим Draw_Brick_Letter(), чтобы убрать точки на экране
- 57:32 - Баг: редактирование имени не прекратилось
- 59:13 - Поиграем в нашу игру
- 59:48 - Баг: активные кирпичи не заканчивают свою анимацию
- 01:03:21 - Играем 1-й уровень
- 01:05:03 - Баг: мячик зациклился при отражении от платформы
- 01:12:58 - Баг: гейты открываются, не выпуская монстров
- 01:19:46 - Баг: мячик на парашюте летит вверх
- 01:22:30 - Баг: мячик застрял на платформе
- 01:29:37 - Баг: 8-й уровень не закончился
- 01:35:20 - Вынесем код в метод Set_Floor_State()
- 01:37:52 - Увеличим максимальное количество активных кирпичей
- 01:39:07 - Исправим баг с отражением мячика на парашюте от пола
- 01:41:46 - Исправим баг с пикселями, остающимися от парашюта
- 01:46:02 - Воспроизведём зацикленность мячика на тестовом уровне
- 01:56:47 - Добавим метод Detect_Hits_Cycling()
- 01:59:50 - Добавим циклический буфер координат
- 02:05:06 - Сканируем массив окнами в поисках паттерна
- 02:11:13 - Добавим оператор сравнения в APoint
- 02:12:34 - Добавим метод Set_As() в APoint
- 02:13:55 - Проверяем алгоритм поиска паттерна
- 02:20:48 - Смотрим на стили окна в MSDN
- 02:23:05 - Уберём ресайз окна нашей программы
- 02:24:24 - Исправим ускорение мячика
- 02:25:12 - Popcorn_part_95_2.zip: пишем код
- 02:25:28 - Обновим план и скомпилируем игру в релизе
- 02:27:40 - Мы заканчиваем наш проект!
- Popcorn_part_95_1.zip - https://drive.google.com/file/d/1hPpTb0keb1BjiKzaGM0KKouuFzc_1mAk
- Popcorn_part_95_2.zip - https://drive.google.com/file/d/1QLKKoOv4_HTDWFeXg5o47EHpqXXs04I2