Как стать автором
Обновить

Игра на WinForms + C# в 16 лет (2 часть)

Время на прочтение4 мин
Количество просмотров17K

Предыстория


Прошло довольно много времени с момента написания предыдущей статьи. Как и обещал я написал вторую часть. Хотелось бы сказать спасибо всем тем, кто давал советы в комментариях, из всех их я смог узнать что-то новое. Ну а для тех кому хочется сразу посмотреть проект вот ссылка на GitHub проекта.

Сразу хочется отметить, что всё, что было добавлено и изменено в этой версии делалось с очень
большим трудом, большим количеством ошибок. мой гугл наполнился большим количеством запросов начиная от особенностей реализации MVP, до асинхронных методов.

image


Обновления


  1. Добавлен свой собственный редактор карт(как в оригинале игры).
  2. Реализован эхолот.
  3. Добавлена возможность ловить на донку и на спиннинг.
  4. Добавлено много видов рыбы.
  5. Сильно улучшена производительность проекта.
  6. Исправлено большое количество багов.
  7. Так же значительное улучшение архитектуры приложения(точнее её появление).
  8. Добавлено сохранение профиля игрока.
  9. Реализованы трофеи.
  10. Добавлена смена дня и ночи.
  11. Добавлены путешествия.
  12. Реализован продуктовый магазин.
  13. Реализован патерн MVP.
  14. Реализована система событий в игре
  15. Реализована прикормка, с возможностью миксования ингредиентов
  16. Добавлена озвучка
  17. Добавлены анимации
  18. Реализован износ удилищ, в зависимости от размера рыбы и времени вываживания

Больше изменений добавлю в README файл проекта Git.

Как чужой код ввёл в заблуждение.


image

Мы видим на скриншоте редактор карт для рыбалки, а именно сетку глубины для каждой локации (Это элементы Label с FormBorderStyle = 0, для того, чтобы показать рамку). Кстати скриншот сделан с использованием моих собственных ножниц. В чём заключалась проблема?

Исходный код
for (int x = 0; x < 51; x++){
    for (int y = 0; y < 18; y++){
    Point between = new Point(Game.CastPoint.X - LVL.Deeparr[x, y].Location.X, 
                           Game.CastPoint.Y - LVL.Deeparr[x, y].Location.Y);
    float distance = (float)Math.Sqrt(between.X * between.X + between.Y * between.Y);
        if (distance < 20){
            if (Player.getPlayer().lure != null){
                Game.gui.DeepLabel.Text = LVL.Deeparr[x, y].Tag.ToString();
                Sounder.setY(x);
                Sounder.setX(y);
            }
        }
        Game.Deep = Convert.ToInt32(Game.gui.DeepLabel.Text);
    }
        
}



Здесь мы видим простой проход по двумерному массиву(причём не правильный). Потом мы вычисляем по теореме Пифагора гипотенузу, и если она < 20, мы определяем нужную клетку. Но этот метод очень плохо работает даже с квадратом. А тут прямоугольники. Поэтому часто клетка определяется неправильно. В своё оправдание могу сказать, что этот код я взял с YouTube.

Итак, нам нужно определить в какой клетке находится курсор. Для этого можно применить данный исходный код:

Код
for (var y = 0; y < CurLvl.Height; y++) {
      for (var x = 0; x < CurLvl.Widgth; x++) {
             var r = new Rectangle(CurLvl.DeepArray[x, y].Location, new 
                    System.Drawing.Size(LabelInfo.Width, LabelInfo.Height));
      if (r.IntersectsWith(new Rectangle(point, new System.Drawing.Size(1, 1)))) {
                        //SomeCode
      }
     }
}


Здесь мы берем координаты курсора, кастим их в PointToClient, и передаём в конструктор Rectangle, размеры указываем 1 и 1. Потом мы используем стандартный метод IntersectsWith проверяем, пересечение курсора, и label. Также, мы не можем просто обработать клик по label, так как форма с ними не показывается.
Также, это позволило реализовать поддержку 3-х удилищ для ловли.

Генерация рыбы


Итак, основная часть игры это генерация рыбы. Она происходит в несколько этапов:
1.При заходе на локацию мы из строки типа:
Карась Золотой:25 250-400 [Сыр, Червь, Опарыш, Кукуруза] Где содержится размер рыбы в процентах от максимального, глубина минимальная, глубина максимальная, и список наживок получаем объект рыбы(Не забыв предварительно проверив строку через регулярные выражения). Для красоты кода я определил оператор который кастит строку к рыбе.

public static explicit operator Fish(FishString fs) {
      return fs.GetFishByStr();
}


В итоге такой подход позволяет нам написать:

Fish fish = (Fish)new FishString("Карась Золотой: 25 250 - 400
[
Сыр,
 Червь,
 Опарыш,
 Кукуруза
]");

Код приведен для примера и не встречается в проекте в подобном виде.

2.Теперь нам надо дождаться, когда удочки будут закинуты, после этого мы запускаем таймер (свой для каждой удочки) со случайным временем поклёвки, дальше по тику таймера из нашего списка рыб размеров 1000 единиц, выбираем рыб, глубина обитания которых включает в себя глубину удочки.

3. Из этого списка случайно выбираем рыбу. Проверяем может ли съесть установленную наживку, и также проверяем, чтобы время суток активности рыбы соответствовало текущему времени в игре.

4. Если рыба может съесть наживку, производим атаку на приманку. Вычисляем, будет ли сход и через какое время, основываясь на шансе схода установленного крючка. Если рыба не может съесть наживку, то циклом проходимся по текущей прикормке(если она есть). Проверяем, нет ли рядом рыбы, которая может клюнуть на наживку, и повторяем всё тоже самое.

Благодаря процессу генерации, я стал уверенным пользователем LINQ.

Сама игра



FoodS

Скриншот продуктового магазина.

Его исходник можно посмотреть в репозитории. Там довольно интересно выполнены обработчики MouseEnter и MouseLeft для изменения изображений еды.

image

Скриншот формы для путешествий. (Все водоёмы являются тестовыми и их названия не являются подлинными.)

image

Скриншот игрового мира

Планы


  1. Сделать клиент-сервер для игры
  2. Junior FPGA(ПЛИС) Developer
  3. Распознавание лиц через Веб камеру(Ищу литературу, которая может быть полезна)
  4. Замена обычных ListView на ObjectListView

В конце предыдущей статьи, я писал, что хочу устроиться на работу. Ну что ж, в сентябре я закрыл своё первое ТЗ по SNMP, правда на языке C.

Вывод


Проект стал довольно большим, с хоть не идеальной, но очень достойной кодовой базой, удобной в сопровождении.Где-то могут нарушаться принципы SOLID, но это из-за того, что проект очень сильно затянулся. Также, если вы начинающий разработчик, и ищите проект, в котором можно поучаствовать, можете делать коммиты в данный репозиторий. Список ожидаемый изменений можно посмотреть в README файле проекта.

Также хочется отметить, что я не вижу перспектив в карьере C# разработчика, вернее мне бы хотелось чего-то более близкого к железу, поэтому пробую изучение более низкоуровневых языков.

Всем спасибо, кто прочитал до конца, любая критика исходного кода приветствуется и будет сразу рассмотрена.
Теги:
Хабы:
+4
Комментарии17

Публикации

Истории

Работа

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн