# | Название видеоурока | Видео / Тесты | Решило | Рейтинг | Доступ |
---|---|---|---|---|---|
1 | Инкапсуляция мечты |
2 теста |
|||
Курс по теории Объектно-ориентированного программирования. С нуля создаётся проект по рисованию различных геометрических фигур, которые потом объединяются в спрайты, взаимодействуют друг с другом. Во время создания проекта постоянно применяется рефакторинг кода, при этом демонстрируются приёмы Объектно-ориентированного программирования. Во второй части курса мы проработаем понятие Интерфейса. Выдержка из отчёта Ларисы по завершению курса. 1) Получила представление о методах ООП - инкапсуляции, полиморфизме и наследовании. Эти три "кита" позволяют изменять и усложнять программы, добавляя в них новые возможности; 2) Научилась рисовать простые геометрические фигуры; 3) Создавать базовые и производные классы; 4) Создавать структуры и работать с пикселями; 5) Создавать фигуры из массива простых фигур в том числе и в цвете; 6) Передвигать простую фигуру; 7) Создавать класс объектов Sprite, являющийся производным от базового абстрактого класса Shape, а в нем список List, который содержит произвольное число фигур и функцию, которая добавляет фигуру, а также метод Move, который двигает её; 8) Освоила BreakPoint, который дает возможность проследить переходы в классе и связи между классами; 9) Познакомилась с абстрактыми и виртуальными методами в абстрактном базовом классе и методами override в производных классах. Совокупность этмх методов позволяет передвигать сложные фигуры как целое. Отчёт отправил: 7276. Ильшат Выполнено за 35 мин. [Показать отчёт] Научился: Выражать свои мысли про интерфейс) Сложности: Подобрать пример для описания различий между интерфейсом/реализацией. Комментарии: Инкапсуляция - это разделение структуры некоторого процесса, явления на две части: интерфейс и реализацию. Необходимость интерфейса обуславливается тем, что для пользователя не имеет значения то, как реализован некий процесс. Например, я как пользователь мобильного телефона не заинтересован в том, каким образом реализуется функция набора номера. Более того, в разных моделях эта функция реализована по разному. Мне эти детали не нужны. Мне нужно лишь знать общую последовательность действий, чтобы позвонить необходимому человеку. Т.е., я ожидаю получить удобный интерфейс, который позволит мне быстро и удобно набрать номер друга, а не изучать схемотехнику и замыкать нужные провода на схеме телефона. В итоге, интерфейс необходим для того, чтобы оградить пользователя от деталей реализации, от сложных процессов в начинке, от ошибочных действий с системой. Кроме того, интерфейс подбирается с учетом требований пользователя; возможно создание нескольких интерфейсов. Например, интерфейс для новичков, с ограниченными возможностями для управления процессом, где большинство параметров устанавливается по умолчанию. Интерфейс для опытных пользователей, для более тонкой "настройки под себя". Инкапсуляция в программировании выражается в правильной модульности исходного кода, разделении интерфейса и реализации. Например, в языке C++ для создания интерфейса используются заголовочные файлы, например MyLib.h, где пользователю доступны интерфейсы, а детали реализации расположены в файлах .cpp. На более низком структурном уровне инкапсуляция выражается в виде namespace, и далее в виде классов, где для разделения интерфейса и реализации используются секции кода public:, private:. На скриншоте показана кабина самолета Ил-96 (интерфейс) и общий вид самолета (его реализация) |
|||||
2 | Урок рисования |
2 теста |
|||
На этом уроке мы нарисуем домик из двух линий и прямоугольника.
Отчёт отправил: 7276. Ильшат Выполнено за 9 мин. [Показать отчёт] Научился: Свойство Dock у объектов на форме. Сложности: Сложностей не было. Комментарии: Все отлично) |
|||||
3 | Первый класс |
2 теста |
|||
На этом уроке мы создадим первый класс - Line. И перепишем программу, чтобы она работала точно так же. Отчёт отправил: 7276. Ильшат Выполнено за 12 мин. [Показать отчёт] Научился: Описывать класс и его конструктор, создавать объект. Сложности: Сложностей не было. Комментарии: Все отлично) |
|||||
4 | Второй класс |
|
|||
На этом уроке мы создадим второй вспомогательный класс - Box. Порассуждаем на тему "наследования" и переделаем программу. Отчёт отправил: 7276. Ильшат Выполнено за 14 мин. [Показать отчёт] Научился: Для объекта класса Box рассчитывать значение ширины и высоты внутри класса. Сложности: Прикрепить к левой части экрана дерево классов во время исполнения программы. Комментарии: "Линия это не прямоугольник", "Любой студент это человек" - понравились примеры) |
|||||
5 | Круглый класс |
|
|||
Создадим класс для задания окружности - Circle. Дополним окружность в центре домика. Отчёт отправил: 7276. Ильшат Выполнено за 12 мин. [Показать отчёт] Научился: Узнал, что для рисования эллипса необходимо задать координаты верхнего левого угла и ширину/высоту воображаемого прямоугольника вокруг эллипса. Сложности: Сложностей не было. Комментарии: Интересное название урока "Круглый класс") |
|||||
6 | Структура пикселя |
|
|||
Создадим структуру для задания координат пикселя и перепишем классы и программу с её использованием. Почитать об отличии класса от структуры: http://www.cyberforum.ru/csharp-beginners/thread442631.html Отчёт отправил: 7276. Ильшат Выполнено за 15 мин. [Показать отчёт] Научился: Познакомился с понятием "структура" в языке C#. Сложности: Сложностей не было. Комментарии: Все понятно объясняется, идем дальше) |
|||||
7 | Структура vs Класс |
1 тест |
|||
На этом дополнительном уроке наглядно демонстрируются главные отличия между struct и class в языке C#.
Отчёт отправил: 7276. Ильшат Выполнено за 40 мин. [Показать отчёт] Научился: 1) Более подробно изучил понятие "структура" в языке C#; 2) Понял отличие структуры от класса в C#; 3) Передача параметров в функцию с помощью квалификаторов ref, out. Сложности: Сложностей не было. Комментарии: Все понятно, спасибо за урок) |
|||||
8 | Пиксели для классов |
2 теста |
|||
На этом уроке мы продолжим внедрение структуры Pixel в наши классы. Будем её использовать для хранения координат внутри класса. Также избавимся от повторяемого кода внутри конструкторов. Отчёт отправил: 7276. Ильшат Выполнено за 20 мин. [Показать отчёт] Научился: Вызывать один конструктор через другой в C#. Сложности: Сложностей не было. Комментарии: Полезная фича, делегирующие конструкторы, спасибо) |
|||||
9 | Расстояние между пикселями |
2 теста |
|||
Как вычислить расстояние между двумя пикселями? Есть специальная формула, которую можно разместить в структуру Pixel. Теперь мы сможем создать ещё один конструктор окружности по центру и любой точке на окружности. Отчёт отправил: 7276. Ильшат Выполнено за 15 мин. [Показать отчёт] Научился: Более сложной инициализации аргументов для делегирующего конструктора (в данном случае, с помощью функции distance()) Сложности: Сложностей не было. Комментарии: Красота, идем дальше) |
|||||
10 | Цветные карандаши |
1 тест |
|||
Возьмём цветные карандаши и будем раскрашивать наш домик. Создаём новые классы для цветны линий, окружностей и прямоугольников. Отчёт отправил: 7276. Ильшат Выполнено за 25 мин. [Показать отчёт] Научился: Осознал неудобство ручного (copy/paste) создания новых классов со схожими свойствами на базе уже существующих . Сложности: Все понятно, сложностей нет. Комментарии: Хороший подход, постепенное улучшение структуры программы как было сказано в начале видео) |
|||||
11 | Рисуем Снеговика |
|
|||
На этом уроке мы создадим ... Снеговика (спрайт) — более сложную фигуру, которая состоит из других фигур. В дальнейшем мы будем работать с такими спрайтами, перемещать их, поворачивать, масштабировать, а пока ... мы просто нарисуем Снеговика. Отчёт отправил: 7276. Ильшат Выполнено за 44 мин. [Показать отчёт] Научился: Рисовать снеговика в paint:D Сложности: Определить координаты центров окружностей, углов прямоугольников и концов отрезков. Комментарии: Абстракция прекрасна: используя заранее определенные необходимые типы данных (Line, Circle, Box) удобно создавать интересные фигуры, не задумываясь о деталях) |
|||||
12 | Второй Снеговик |
1 тест |
|||
На этом уроке мы создадим второй спрайт - ещё одного снеговика, но разноцветного. Вопрос для перехода к следующему уроку: Что нужно изменить в этой программе, чтобы мы могли а) перемещать снеговика; б) поворачивать снеговика; в) изменять размер снеговика. Отчёт отправил: 7276. Ильшат Выполнено за 15 мин. [Показать отчёт] Научился: Добавил второго снеговика, путем смещения координат 'x' базовых точек первого снеговика. Сложности: Сложностей не было. Комментарии: Для начала, для удобства, можно создать класс SnowMan, где, в качестве полей определены: x, y - координаты верхнего-левого угла снеговика; angle_x, angle_y - текущие углы поворота снеговика относительно осей x, y; scale_x, scale_y - коэффициенты масштабирования относительно осей x, y. 1) для перемещения можно добавить функцию move(int dx, int dy) {x += dx; y += dy;} 2) для поворота можно добавить функцию rotate(int rx, int ry) { angle_x += rx; angle_y += ry; } 3) для изменения размеров можно добавить функцию scale(int sx, int sy) {scale_x *= sx; scale_y *= sy;} Кроме того, можно добавить функции set_position(int x, int y), set_rotation(int rx, int ry), set_scale(int sx, int sy), которые устанавливают абсолютные значения необходимых полей. |
|||||
13 | Богатое наследство |
2 теста |
|||
Наконец-таки мы возьмёмся за наследование. Убираем повторяющийся код из цветных классов. Осмысливаем значение термина «наследование». Отчёт отправил: 7276. Ильшат Выполнено за 20 мин. [Показать отчёт] Научился: 1) Познакомился с наследованием в C#. 2) Вызов конструктора базового класса в конструкторе производного класса с помощью ключевого слова base в С#. Сложности: Сложностей не было, все по аналогии с C++, правда до сих пор слегка неловко, когда вижу в коде голые 'new', явные 'this'. Комментарии: На этот раз кратко опишу, как это отражается в коде. Наследование - это способ создания новых типов на базе существующих, путем повторного использования их интерфейса (и реализации), и с добавлением каких-либо новых свойств, поведений, которые явно отличают производный тип от базового. |
|||||
14 | Фигуральный базовый класс |
|
|||
Очень хочется все элементы снеговика поместить в один массив. Сейчас это сделать нельзя - придётся делать три массива - для кругов, для линий, для боксиков... Решение гениальное - создаём базовый класс фигуры - Shape, создаём массив фигур, и все фигуры помещаем в этот массив! После размещения фигур в массив можно видеть, что каждая фигура в нём хранится не как фигура, а под своим типом. А все под одной крышей они могут находится потому что все они - фигуры, так как унаследованы от Shape. Отчёт отправил: 7276. Ильшат Выполнено за 30 мин. [Показать отчёт] Научился: 1) Создавать массив объектов и использовать цикл для итерации в указанном диапазоне. 2) Свойство или поле Length у массива. 3) Динамическая идентификация типа в C#. Сложности: Реализовать функцию Draw(Shape). Комментарии: Общая идея такова, что среда выполнения C# как бы должна знать динамический тип объекта. Как раз на видео было показано, что хоть у массива статический тип это Shape, но динамический тип может быть другим(Circle, Box и т.д.). Для реализации Draw(Shape) обратился к гуглу, почитал в википедии про динамическую идентификацию типа в C#, обнаружил, что для этого есть несколько способов реализации (GetType, typeof, is, as), подробнее почитал в msdn, поигрался с is, GetType(), выбрал GetType. Получился эдакий брутальный способ вызова соответствующей перегруженной функции Draw). |
|||||
15 | Приведение с мотором |
1 тест |
|||
На этом уроке мы реализуем метод Draw (Shape shape) через серию условных операторов. А также создадим функцию для рисования целевого спрайта (снеговика) - Draw (Shape [] shapes). Результат работы программы не изменяется, а вот содержимое кода всё более и более облагораживается. Отчёт отправил: 7276. Ильшат Выполнено за 15 мин. [Показать отчёт] Научился: Закрепил знания, полученные на предыдущем уроке (функция GetType()) Сложности: Сложностей не было. Комментарии: Переменная Shape.position необходима для удобства, простоты расчетов, "независимости от контекста", то есть, это единственная переменная, которая хранит в себе абсолютные координаты снеговика в целом, как фигуры. Остальные координаты зависят от Shape.position, что удобно для расчетов поворота, масштабирования и прочее. |
|||||
16 | Переезд метода Draw |
|
|||
На этом уроке мы начнём переносить функции для рисования фигур из основной программы в классы.
Отчёт отправил: 7276. Ильшат Выполнено за 15 мин. [Показать отчёт] Научился: 1) Приведению типа Shape к типу Circle. 2) Новому способу прохода через breakpoint, на видео(10:58). Отличие этого способа, от двух других (F10, F11) в том, что после нажатия на F5 программа продолжает свое обычное выполнение (пока не встретит новый breakpoint). Это удобно в определенных случаях, когда нет необходимости пошагово проходить через выражения; экономит время. Сложности: Сложностей не было. Комментарии: Все понятно, идем дальше) |
|||||
17 | Переезд graph в базовый класс |
1 тест |
|||
На этом уроке мы напишем функции для рисования фигур во всех остальных классах.
Отчёт отправил: 7276. Ильшат Выполнено за 20 мин. [Показать отчёт] Научился: Использовать функционал базовых классов. Сложности: Сложностей не было. Комментарии: Наша программа постепенно становится более удобной: там закинули в массив, тут прошлись в цикле, дальше унифицировали обращение к функции Draw - красота) |
|||||
18 | Мощь полиморфизма |
2 теста |
|||
На этом уроке мы создадим в базовом классе функцию Draw(), и при её вызове через механизм полиморфизма будет запускаться созвучный метод нужного класса. Отчёт отправил: 7276. Ильшат Выполнено за 15 мин. [Показать отчёт] Научился: 1) Ключевые слова abstract, virtual, override их смысл и применение. 2) Реализация полиморфизма в C#. Сложности: Сложностей не было, все по аналогии с C++, правда с другим синтаксисом. Комментарии: Да, дождались, полиморфизм, ура!) |
|||||
19 | Спрайт для Снеговика |
1 тест |
|||
На этом уроке мы создадим новый класс - Sprite, в котором будет хранится список всех фигур, из которых строится графический объект, чтобы в основной программе мы могли оперировать сразу спрайтами, а не их составными элементами.
Отчёт отправил: 7276. Ильшат Выполнено за 20 мин. [Показать отчёт] Научился: Познакомился с коллекцией List в C#; удобно, мощно. Сложности: Сложностей не было. Комментарии: Спасибо за урок, приятно познакомиться с коллекциями в C#) |
|||||
20 | Перемещение круга |
1 тест |
|||
На этом уроке мы начнём реализовывать идею перемещения спрайтов. Начнём, как обычно, с простого. Научимся перемещать один кружок. Отчёт отправил: 7276. Ильшат Выполнено за 15 мин. [Показать отчёт] Научился: Отличать координаты position от координат расположения круга. Сложности: Сложностей не было. Комментарии: На мой взгляд, Move(int offset_x, int offset_y) это функция, которая принимает смещения относительно текущих координат; для абсолютного размещения лучше подойдет функция MoveTo(int x, int y) или SetPosition(int x, int y). |
|||||
21 | Перемещение других фигур |
2 теста |
|||
На этом уроке мы переделаем метод Draw() для остальных фигур - Line и Box(). Наша программа теперь по нажатию кнопочки будет перемещать сразу три фигурки. Отчёт отправил: 7276. Ильшат Выполнено за 20 мин. [Показать отчёт] Научился: Закрепил материал с прошлого урока, координаты position и внутренние координаты для Circle, Box, Line. Сложности: Придумать фигуру из трех фигур) Комментарии: Если использовать данную структуру классов, то для реализации перемещения спрайта необходимо объявить функцию Move с ключевым словом virtual в классе Shape, затем перегрузить функцию Move для класса Sprite, которая пробежится по коллекции shapes и для каждого объекта вызовет функцию Move: public override void Move(Pixel position) { base.Move(position); foreach(Shape shape in shapes) shapes.Move(position); } |
|||||
22 | Перемещение Снеговиков |
1 тест |
|||
На этом уроке мы научим перемещаться целых снеговиков. Для этого нам не нужно будет менять метод Draw(), мы воспользуемся полиморфизмом! Отчёт отправил: 7276. Ильшат Выполнено за 15 мин. [Показать отчёт] Научился: Перемещать снеговиков, закрепил навыки предыдущих уроков. Сложности: Сложностей не было, все ок. Комментарии: Перемещать спрайты научились, теперь необходимо их поворачивать и масштабировать) |
|||||
23 | ПОЛУФИНАЛЬНЫЙ УРОК. |
без видео |
|||
На этом первая часть видеокурса "Теория ООП" закончилась. Пожалуйста, напиши отзыв об этом курсе, что тебе понравилось, что узнал нового, что можно было бы сделать лучше, оправдал ли курс твои ожидания. Приложи своё фото и напиши своё имя-фамилию. (видео в этом уроке нет) |
|||||
24 | Интерфейс. Зачем он нужен. |
1 тест |
|||
На этом уроке я объясню своими словами, что такое интерфейс. Мы поговорим об игре "Голя" или "Сифа" или "Вода", о том, кто в неё может играть, и что делать тем, кто не знает правила игры. В конце урока мы создадим наш интерфейс. Правила игры, для тех, кто не знает: Выбирается ведущий. Его цель - догнать и дотронуться до кого-либо из участников. Цель остальных - не допустить этого. Когда ведущий дотронется до кого-либо (заголит) - ведущим становится новый участник. Отчёт отправил: 7276. Ильшат Выполнено за 20 мин. [Показать отчёт] Научился: Познакомился с интерфейсами в C#. Сложности: Понять, связать действия в интерфейсе Player (Игрок) с правилами в игре "Голя", выразить вкратце мысли про интерфейс. Комментарии: На мой взгляд, интерфейс это некий контракт, правила, которые должны выполнены (реализованы в коде), прежде чем мы можем создавать различные реализации конкретных классов. Эти классы будут представляться от имени интерфейса, как допущенные к использованию (подчиняющиеся правилам контракта) и могут быть вызываться любой функцией, которая работает с данным интерфейсом. На примере данной игры "Голя", интерфейс это требования к человеку, которые должны быть соблюдены, прежде чем он сможет принимать участие в игре. То есть, надо уметь бегать, становиться Голей, становиться не Голей и ловить других игроков. В коде это означает, что любой класс, который хочет принимать участие в игре, должен реализовать все 4 функции интерфейса Игрок. Если он это сделал, система довольна и разрешает доступ к тем классам, функциям, которые работают с интерфейсом Игрок. |
|||||
25 | Интерфейс. Правила игры. |
1 тест |
|||
На этом уроке мы поговорим о правилах игры в догоняшки. На прошлом уроке мы выясняли, что должны уметь делать игроки. На этом уроке мы начнём писать класс, в котором опишем конкретные правила нашей игры. Отчёт отправил: 7276. Ильшат Выполнено за 17 мин. [Показать отчёт] Научился: Автоматическая генерация заглушки stub для методов. Сложности: Продумать словесный алгоритм. Комментарии: Алгоритм FindNewLeader(): Начало Игрок := Первый игрок в списке игроков Цикл: Пока Игрок != Последний игрок в списке Если Лидер Поймал Игрока ТО Блок Лидер := Игрок Выход из цикла Конец Блока Конец Цикла Конец //--------------------------------- Алгоритм SetNewLeader(Игрок игрок): Начало Лидер установить Не Голя Лидер := игрок Лидер установить Голя Конец |
|||||
26 | Интерфейс. Алгоритм игры. |
|
|||
На этом уроке мы допишем класс GameCatch. Напишем реализацию методов FindNewLeader() и SetNewLeader(). Ваша задача - подумать и написать, что нужно ещё сделать, чтобы можно было начать играть в эту игру. Отчёт отправил: 7276. Ильшат Выполнено за 15 мин. [Показать отчёт] Научился: Узнал, что если в списке не будет элементов, то foreach корректно обработает эту ситуацию. Сложности: Сложностей не было. Комментарии: Чтобы начать играть, нам необходимо продумать "интерфейс" игры, как и что рисовать на форме, панели или pictureBox, реализовать интерфейс Игрок в виде конкретного класса, добавить несколько объектов этого класса в список gamers в классе GameCatch и как-нибудь по-хитрому все это запустить) |
|||||
27 | Интерфейс. Создаём кружок. |
|
|||
На этом уроке мы создадим объект для нашей игры - Кружок! У кружочка есть координаты центра, радиус и цвет. Цель урока - создать класс Circle.cs Отчёт отправил: 7276. Ильшат Выполнено за 15 мин. [Показать отчёт] Научился: Закрепил полученные знания из предыдущих уроков. Сложности: Сложностей не было. Комментарии: Дальше необходимо каким-нибудь образом связать Circle с интерфейсом Игрок. Как было сказано в конце урока, что если Circle стал Голей, то меняет цвет на красный, если не Голя, то обратно синий. |
|||||
28 | Интерфейс. Площадка для игры. |
1 тест |
|||
На этом уроке мы начнём создавать класс Arena, который создаст поле для игры и реализует методы для отображения объектов на экране. Отчёт отправил: 7276. Ильшат Выполнено за 20 мин. [Показать отчёт] Научился: Кириллу респект, хорошо подметил, что в конструкторе переменная picture ссылается на аргумент, а не на член класса Arena. Код и так и сяк будет работать, согласен с Евгением Витольдовичем, но менять косвенно состояние this.picture через аргумент на мой взгляд это словно зайти в дом через черный вход, мало ли, что тебя там ожидает. Возможно в C# есть какой-нибудь механизм, защищающий от этого, аналогичный const ссылкам и указателям C++ на аргументы функций. Сложности: Нарисовать окольными путями кружок на форме, для этого добавил pictuteBox на форму, добавил Arena.Show(), создал объект Arena в коде инициализации формы. Комментарии: Класс Арена нужен для того, чтобы инкапсулировать отображение наших игроков Circle на форме, чтобы, например, не вручную в коде форме вызывать функции DrawEllipse, а создать какой-нибудь удобный интерфейс Arena.Show(object). Вообще говоря, класс Арена малек перегружен по смыслу, он кроме того, умеет создавать новые Circle и статический Range меня немного смущает, но соглашусь с Евгением Витольдовичем, не стоит усложнять код) |
|||||
29 | Интерфейс. Кружок на площадке. |
1 тест |
|||
На этом уроке мы допишем класс Arena, реализуем методы Show(Circle), Refresh(), static NewCircle(). Всё готово к созданию кода для отображения кружка из класса Form1.cs! Отчёт отправил: 7276. Ильшат Выполнено за 14 мин. [Показать отчёт] Научился: PictureBox.Refresh() удобная штука) Сложности: Сложностей не было. Комментарии: Свое творчество с прошлого урока удалил) Идем дальше) |
|||||
30 | Интерфейс. Запускаем кружки на площадку! |
3 теста |
|||
На этом уроке мы настроим нашу форму, напишем несколько волшебных строчек, и ... программа заработает!!! У нас будет много-много кружков на экране 8-о Отчёт отправил: 7276. Ильшат Выполнено за 20 мин. [Показать отчёт] Научился: Рисовать круги на форме в рандомных местах, с рандомным радиусом, это красиво) Сложности: Три функции Refresh(), Clear(), Arena.NewCircle(). Они взаимосвязаны и их нужно вызывать в правильном порядке. Сначала не понимал, как так получается, что мы создали объект в куче, вызвали для него Show(), потом потеряли ссылку, значит объект уничтожился, а на форме он все так же рисуется. Вся магия в том, что на pictureBox остается не сам объект, а его бледная тень, словно рисуешь карандашом на бумаге. И если случайно вызвать Clear(), то все тени исчезнут, словно стирающей резинкой все очистил) И конечно нужно вовремя вызывать Refresh(), чтобы показать результат изменения после итерации. Комментарии: Это был долгий путь в несколько уроков, прежде чем мы нарисовали заветные круги, причем в рандомных местах, с рандомным радиусом) Результат понравился, спасибо!) |
|||||
31 | Интерфейс. Кружок хочет играть. |
2 теста |
|||
На этом уроке мы унаследуем кружок от интерфейса Игрок. Теперь для запуска программы нам придётся реализовать методы из его интерфейса. В этом уроке мы реализуем методы Голя() и НеГоля(). Отчёт отправил: 7276. Ильшат Выполнено за 20 мин. [Показать отчёт] Научился: Закрепил навыки. Сложности: Описать словами содержимое методов Беги(), Поймал(). Комментарии: Метод Беги(). Наш круг описывается координатами центра center (Point) и радиусом(int). В конце урока была дана подсказка, две целочисленные переменные sx, sy. Эти переменные могут означать смещение координат центра. Могут означать изменение радиуса. Но мы должны реализовать не метод Расширься(), а метод Беги(), то есть изменение координат самого круга, а это определяется координатами центра. Так что, думаю что надо в методе Беги() изменить координаты центра: center = new Point(center.x + sx, center.y + sy); В методе Поймал(object obj) нам надо проверить поймал ли текущий кружок this того, что мы получили в аргументах. Физическая реализация этого представляется проверкой на столкновение или, точнее, пересечение двух окружностей (Так как у нас объекты круги). Пересечение двух окружностей это не rocket science, решение известно - это определение дистанции между центрами окружностей и сравнение этого значения с суммой радиусов. Если дистанция меньше суммы, то ... кружок поймал другой кружок. public bool Catch(object obj) { Circle second_circle = (Circle)obj; int distance = Convert.ToInt16(Math.Sqrt( (center.X - second_circle.center.X) * (center.X - second_circle.center.X) + (center.Y - second_circle.center.Y) * (center.Y - second_circle.center.Y))); return distance < radius + second_circle.radius; } |
|||||
32 | Интерфейс. Кружок готов к игре! |
1 тест |
|||
На этом уроке мы допишем методы Игрока в классе Circle. Реализуем метод Беги() и Поймал(), и даже исправим недочёты в описании интерфейса (!!). В конце урока я ответил на многочисленные вопросы участников. Отчёт отправил: 7276. Ильшат Выполнено за 45 мин. [Показать отчёт] Научился: Поэкспериментировал с выводом класса Circle на экран. Попробовал FillEllipse, различные Brush. Оставил вывод через DrawEllipse, мне показались более симпатичными. От себя добавил, что если Circle Голя, то у него толщина окружности в три раза больше, чем у остальных, это помогло в наглядности тестирования. Сложности: В 4 пункте было указано, что нужно описать словами что нужно сделать. Я малость не удержался, и реализовал в коде, правда достаточно долгое время, около 10 минут не понимал, почему у меня круги двигаются, но не Голятся. Оказалось, что в функции SetNewLeader() мы выходили из функции, если Лидер был НЕ null. Исправил как надо - заработало) Ошибка была глупой:D Надо быть внимательнее. Комментарии: Решил записать видео демонстрацию, без звука. В конце видео выделил мышкой добавленный код, а в самом конце - проблемный участок, надо которым сидел 10 минут) Видеообзор: https://youtu.be/0tObhwEck74 |
|||||
33 | Интерфейс. Кружочки гоняются друг за другом. |
1 тест |
|||
На этом уроке мы добавим в форму класс GameCatch, Разместим таймер и наконец-таки запустим нашу игру - Шарики начнут гоняться друг за другом! Отчёт отправил: 7276. Ильшат Выполнено за 25 мин. [Показать отчёт] Научился: Метод Equals() у объекта. Сложности: Продумать как исправить недочеты с переголением. Комментарии: Как исправить недочет с переголением? 1) Можно определить время в течение которого новый Голя не может Голить игроков. 2) Как и в первом случае, указать время, но в течение этого времени новый Голя не может двигаться. 3) Сделать какую-нибудь форму иммунитета игроков на действия нового Голи. Из всех способов, думаю первый самый простой и подходящий. |
|||||
34 | Интерфейс. Изменяем правила игры. |
1 тест |
|||
На этом уроке мы добавим в правила игры задержку после получения Голи. Ведущий будет считать до 10, и только потом сможет голить других. Твоя задача - придумать новую игру, в которую смогут играть Игроки, то есть объекты, которые умеют делать то, что описано в интерфейсе Игрок. Отчёт отправил: 7276. Ильшат Выполнено за 45 мин. [Показать отчёт] Научился: Понял значимость класса GameCatch, благодаря которому легко меняются правила игры. Увидел реализацию задержки нового Голи, понравилось то, что код обработки этой ситуации локален внутри GameCatch, хотя и зависит от внешнего таймера. Сложности: Сложностей не было, интересный урок, попробовал версию игры, где новый Голя стоит на месте в течение 10 итераций. Получается менее динамично, но есть ощущение уже несколько другой игры. Комментарии: Суть новой игры. В начале игры все игроки имеют статус Голя, им дается команда Беги. Когда Голя ловит другого Голю, то оба становятся Не Голями и замирают на месте (Не получают команду Беги). Если после этого какой-нибудь другой Голя поймает Не Голю, то Не Голя оживает, становиться Голей и снова начинает двигаться. Если в игре не останется Голь, то игра сбрасывается и все становятся Голями и так по кругу. Записал видео, для этой версии игры. Видеообзор: https://youtu.be/14YzZfzjnQY |
|||||
35 | Интерфейс. Создаём новую игру. |
|
|||
На этом уроке мы начнём делать новую игру - Вирус. Смысл игры подробно рассказан на видео. Цель урока - создать класс GameVirus и реализовать методы GameViurs(), AddGamer(), Step(), RunAll(). Также придумать и написать словами алгоритм методов SetNewVirus(Игрок) и FindNewVirus(). Отчёт отправил: 7276. Ильшат Выполнено за 20 мин. [Показать отчёт] Научился: Закрепил навыки из прошлых уроков, добавил новый класс GameVirused для реализации новой игры. Сложности: Сложностей не было. Комментарии: У нас имеется два массива, gamers и virused. gamers хранит всех текущих игроков, virused - тех игроков, которые заражены. В SetNewVirus(Игрок) нам необходимо добавить игрока в список virused и сказать ему - Ты Голя. В FindNewVirus несколько сложнее, у нас два массива данных, как такового отдельного лидера уже нет, лидер растворен среди зараженных игроков, поэтому необходимо пройтись в двух циклах по gamers и virused и проверить Поймал ли тот, кто заражен того, кто не заражен. Если поймал, то вызвать функцию SetNewVirus. Если остался всего один не зараженный игрок, то сделать его зараженным, остальных в цикле не зараженными. |
|||||
36 | Интерфейс. ФИНАЛЬНЫЙ УРОК. |
|
|||
На этом уроке мы допишем последние две функции и надолго залипнем в экран, наблюдая за новой игрой для наших кружков, как вирусная эстафета может быстро передаваться, особенно, когда игроков очень много. В комментариях написать свой отзыв об этой серии уроков. Следующие уроки не обязательны для выполнения. Я предупредил. Какой курс ты будешь проходить следующим? Отчёт отправил: 7276. Ильшат Выполнено за 45 мин. [Показать отчёт] Научился: Метод Contains у класса List<>, удобная штука. Сложности: Не было, все понятно, хорошо показано, как изменить правила в игре. Комментарии: Перед началом второй части курса теории ООП я ожидал, что мы продолжим работать со снеговиками, научим их каким-нибудь действиями (помню Оля писала мне в комментариях, что "они у нас еще потанцуют, а мы отлично потренируемся"). Кроме того, в шапке курса было указано, "При создании программы мы будем использовать некоторые шаблоны проектирования, такие как "Одиночка", "Фабрика", "Строитель", "Наблюдатель" и другие. Когда я это увидел, еще до того, как пройти первую часть курса, то загорелся желанием пройти курс ООП. В первой части курса паттернов не было, поэтому ожидал их увидеть во второй части. Но и во второй части их не было. Да, были моменты с методами Arena.NewCircle(), но упор в курсе был сделан не на паттерны, а на интерфейсы. Однако это ни в коей мере не говорит о том, что курс мне не подошел. Я присутствовал на вебинаре, на котором производилась запись курса, это восхитительная атмосфера, всем советую ходить на вебинары!) Тематика второй части курса меня сразу захватила, Евгений Витольдович придумал интересный пример для объяснения этой важной концепции в объектно-ориентированном программировании. При этом, в первых уроках упор был сделан на абстракцию, логику программу, а отображением результатов на форме мы занимались во второй половине курса, и, что примечательно, программа сразу со старта заработала корректно, это достойно уважения!) Кроме того, практически после каждого урока были дополнительные вопросы на проработку материала. Нам было необходимо написать словесные алгоритмы или попробовать самим реализовать действия из следующих уроков. Это сильно мотивирует и проверяет на сколько качественно усваивается материал. В целом, я считаю, что неплохо прокачался за эти два курса ООП. Кому стоит рекомендовать данный курс? В своем полуфинальном отчете я писал, что курс теория ООП хорошо подойдет для программистов, которые достаточно уверенно знают C#, но не уверенно понимают понятия ООП. Мои коллеги по проекту не разделяют этого мнения (я читал их отзывы с полуфинального урока) и считают, что курс мастхев для новичков. На вкус и цвет конечно, но я своего мнения не меняю. Лучше сначала хорошо проработать задачи из консоли, бесплатные курсы, понять, что ты не боишься языка программирования и можешь написать программу любой разумной сложности, и потом понять для себя, чего не хватает и к чему лежит интерес) Получился достаточно длинный отчет, спасибо тем, кто прочитал его до конца) Спасибо Евгений Витольдович, мне было приятно пройти курс теория ООП, появились новые идеи, открылись пробелы по некоторым вопросам, будем изучать дальше!) |
|||||
37 | Интерфейс. VIP. Квадратики тоже хотят играть. |
|
|||
На этом уроке мы создадим новый класс Box. Квадратики тоже хотят играть в эту игру, и просят их научить. Пока они ещё не умеют ловить, но уже смогут отображаться и передвигаться. Полезные ссылки для написания функции Поймал: http://xdan.ru/how-to-check-intersect-two-rectangles.html http://stackoverflow.com/questions/306316/determine-if-two-rectangles-overlap-each-other Отчёт отправил: 7276. Ильшат Выполнено за 4 час. 10 мин. [Показать отчёт] Научился: Повторил применение интерфейсов. Сложности: Реализовать функцию пересечения прямоугольников. Комментарии: Данный урок выполнил в Linux Mint с использованием Qt. Я давно интересовался Linux, неделю назад установил себе на компьютер и теперь осваиваю работу в этой ОС. Вчера получил письмо от Евгения Витольдовича с предложением закончить курс ООП, Согласился, продлил курс, но решил выполнить задание с использованием C++ Qt. Программу писал с нуля, по памяти и это большой плюс для меня, так как в завершении совершенно другими глазами смотрел на код Евгения Витольдовича и оценивал как он решал те или иные архитектурные задачи. В целом, функционально код во многом совпал, но структурно были отличия, позже корректировал с учетом решения в видеоуроке. В конце урока было предложено реализовать функцию пересечения прямоугольников, это было сделано, на скриншотах результаты игры GameVirused с "боксиками". P.S. Евгений Витольдович, я хочу продолжить обучение с использованием своих инструментов разработки, Вы это одобряете? То есть, функционально я буду выполнять требования из видеоуроков, получать навыки программирования, но с помощью C++. |
|||||
38 | Интерфейс. VIP. Пересечение прямоугольников. |
|
|||
На этом уроке мы допишем метод Box.Поймал() и запустим игру с квадратиками. Потом попробуем подружить квадратики с кружками, увидим, что это не так просто, да собственно и не нужно. Но возможно. Отчёт отправил: 7276. Ильшат Выполнено за 1 час. 20 мин. [Показать отчёт] Научился: Условие пересечения прямоугольников. Сложности: Сложностей не было. Комментарии: Поначалу решил, что предложенная в уроке функция проверки пересечения двух прямоугольников рассматривает только один частный случай, слишком уж "простая" она на вид. Однако проверил на практике - работает. Здесь я предположил, что боксики двигаются слишком быстро, поэтому в какой-то момент срабатывает "то самое" частное условие и боксик голится. Я не верил, что это решение корректное. Для полной проверки нужно было замедлять боксики и проверять на глаз пересечения, но мне не хотелось этим заниматься. Я уже хотел было отправить отчет, но тут вспомнил совет Евгения Витольдовича, что следует довести дело до конца. Тут осенило, думаю, дай-ка создам unit-тесты на функцию isIntersect и проверю все возможные варианты пересечений и не пересечений. В итоге, нарисовал на бумаге разные варианты расположения прямоугольников, получалась 31 комбинация, создал для каждой из них свой тест, каждый тест запускал по мере написания и меня каждый раз шокировало, что функция-то работает:D На втором скриншоте показаны результаты выполнения 31 теста, все проходят. Подумал, может в Qt какая-нибудь бага, регрессировал код тестируемой функции, добавил в нее ошибку и тесты посыпались как надо, чудо. В общем, функция Евгения Витольдовича работает как надо. Позже я еще раз логически проанализировал функцию проверки и да, тут уже понял, что код корректен. Первое впечатление оказалось обманчивым, следует внимательно читать код. Хороший урок для меня. |
|||||
39 | Интерфейс. VIP. Тяжёлая дружба кругов и квадратов. |
|
|||
На этом уроке мы создалим "универсальный" класс Crosser, который сможет проверять на столкновение "любых" двух Игроков. Конечно не любых, а только двух наших Box и Circle. Это яркий способ, чего стоит избегать в программах. Потому что тут не добавляется универсальности, т.к. при добавлении новых объектов придётся дописывать кучу новых функций на сравнение. Самостоятельное задание - записать видеообзор своего проекта и рассказать, что такое Interface. Отчёт отправил: 7276. Ильшат Выполнено за 3 час. 00 мин. [Показать отчёт] Научился: Поэкспериментировал с интерфейсами, повторил создание видео обзоров. Сложности: Выбрать какое-то одно решение проблемы на проверку пересечения объектов. Комментарии: Проблему проверки пересечения объектов решил немного другим путем, с помощью интерфейса Boundable, который требует, чтобы реализующие его объекты определили ограничивающие круги и прямоугольники вокруг фигуры. Это позволяет сравнивать не сами объекты со сложной конфигурацией, а упрощенные элементы, например, такие как круги. Для того, чтобы добавить нового игрока в игру, достаточно описать список этих ограничивающих поверхностей, а другие функции более высокого уровня уже работают не с самими объектами, а их границами, таким образом нет тесной связи между типами. Да, проверка получается грубее и менее точная. Здесь можно было бы изменить начальный интерфейс, но я пошел другим путем, оставил все как есть и искал куда бы добавить свой интерфейс Boundable. Мое решение так себе, пока не знаю как сделать лучше, но это позволяет создавать новых игроков и не беспокоиться об их сравнении с другими игроками. Для верности, добавил двух новых игроков с более сложной конфигурацией. Курс понравился, стоит пересмотреть еще раз, так как многие "очевидные" моменты открываются с новой стороны. Спасибо, Евгений Витольдович! Видеообзор: https://youtu.be/lemoIWg72Ps |
|||||
Итого: 39 видеоуроков |
7 час. 40 мин. 36 тестов |
83 чел. | |||
Финалисты: lomik, Роман, Максим Базуев, Neverwinter 2, Владимир, Никита, Олюшка, Валера Луцевич, Anton Sozykin, Permitin Alexey, Артём, Максим Лапшинов, Frank, Archi, Александр Львович, Олег Михайлович, Дмитрий, Новопашин Владимир, Евгений, Сергей Соколов, Александр Б., Максим Саратов, Алексей В., Александр, Rita, Станислав, Алексей Хонин, Ludmila, Yefim, Сергей Зулкарнаев, Сергей Аникин, Константин, Tekashnik, Артем Посунько, Андрей Козлов, kalobyte, Sergio, Алексей Малышев, Александр, Сергей Стефаненко, Николай Денисов, Анатолий, Денис, Алексей|BrisK|Кривицкий, Скозложоп, chokayes, Иван Воронин, Андрей Шевченко, Chip, Rise, Слава, Саша Авербух, Александр, ser2018, Дмитрий, Виктор, Денис, Oleksandr, superGrover, Александр Балбашов, vip, Слава, Sergey Potapov, Den Andreevich, Dmitry Sinitsin, Никита, Айдар, Кирилл, Max, AlliZzeN, no name, Дмитрий, Владимир, ES35, Anatoli, Виталий, Татьяна, Vdonsk, MaxB, Булат, Tim, Tom, Антон . |