Привет, извини за долгое отсутствие, пару месяцев занят был и что-то забыл про эти уроки. Теперь пора вернутся и делать игры. Так вот, собественно, у меня возник вопрос по поводу реализации классов в этой игре.
Ты сделал класс Game для реализации всей игры, но есть ли в этом смысл, если объект этого класса будет всего один? Не проще ли разбить игру на несколько более мелких классов, чтобы уже на каждый класс было больше одного объекта. Например, класс для уровня, класс для врага и т.п.
Смысл в правильной архитектуре. :) Классов должно быть столько, сколько существует сложных отдельных модульных задач :) Ну и я приверженец древовидной архитектуры с главным корневым классом-объектом( Как Game в данном случае ). Остальные объекты должны находится внутри Game, а в них уже могут быть свои объекты, ну и так далее :)
В этом уроке происходит только ознакомление с классами, поэтому тут используется такая упрощенная архитектура из нескольких классов :)
Можно тебя совета попросить, а то у меня мелкий баг появился, а код я пишу сам, стараясь в твой не смотреть. Можешь словами описать то, как у тебя перемещаются противники вбок. Ну сам процесс по шагам. Вот у меня просто есть специальный класс для противников. Я создал массив из объектов этого класса. Так вот, чтобы каждый противник двинулся, я создал функцию, которая циклом перебирает каждый объект и двигает его (с помощью метода класса) вбок на определенное расстояние. Движение происходит так: если он двигался в своей клетке - просто меняем координату. Если он двинулся в другую клетку, то мы ставим пробел на то место где он был, меняем координату, отрисовываем его в новой координате.
В принципе, все работает, я даже сделал нормальную стрельбу и противники уничтожаются, но есть мелкий баг. Иногда при стрельбе попадаются противники, которым насрать на снаряды, которые попадают в них. Они их как будто проглатывают их. Это происходит буквально долю секунды и как только этот противник перемещается (вбок или вниз), то эта "неуязвимость" пропадает. Мелочь, но довольно досадная. И поймать ее очень сложно.
Я думаю это связано с кривым перемещением.
Во-первых отрисовка в клетки не должна влиять на позицию объектов, просто должно происходить отрезание дробной части координат для получения row и column :)
Во-вторых лучше посмотреть как это реализовано у меня, ибо какой смысл тогда в уроках? :)
Нет, уроки то я читаю. Теория нужна. Но вот как реализовать саму игру пытаюсь сам. Потому что иначе это будет просто бездумное списывание.
По поводу перемещения. Как оно происходит у меня прямо по шагам:
1. Высчитываю новую позицию противника (float).
2. Проверяю перешел ли он в новую клетку (if ((int)NewPosition_X == Position_X))
3. Если да, то просто ему прописываю новую координату.
4. Если нет, то тут идет несколько действий:
5. Отрисовываю пробел на старой позиции противника
6. В схему уровня (которая двухмерный массив) ставлю пробел в клетку старой позиции
7. Прописываю новую координату (точно также как в п.3)
8. На новой позиции отрисовываю противника.
9. В схему уровня ставлю значок противника в клетку новой позиции
Так вот у меня вопрос. Так ли я все делаю. Оно работает, но тот баг не дает мне покоя. Если они стоят, то он не возникает, но как они двигаются, то иногда проскакивает эта временная "неуязвимость".
Ну я не руками рисую. Вызываю рендерную функцию, которая рисует. Ну функция, которая принимает координаты, символ, цвет символа и цвет фона. Вот с ее помощью я ставлю пробелы и символ противника, где нужно. Это так должно делаться или я чего-то не понимаю?
Я решил проблему. Вот какая причина была. Вот представь летит снаряд, а сбоку в него приходит противник. Они же ходят вбок, поэтому и могут зацепить летящий рядом снаряд. А такая ситуация у меня не обрабатывалась и вызывала непредвиденные последствия.
Правда появилась другая беда, если долго стрелять, то все противники начинают дергаться. Но это я решу.
Все, проблему окончательно решил и у меня возник к тебе вопрос. Что должно происходить с противником, когда его убили. У меня есть метод в классе, который этим занимается. Так вот он обнуляет ХП и отрисовывает на месте противника пробел, и выставляет координаты противнику куда подальше (у меня эти координаты находятся за полем игры, куда никто не заходит). Это нормально, что я так делаю или это как-то можно более грамотно реализовать?
Все, разобрался. То есть мы в начале создаем массив указателей. Потом туда закидываем динамически выделенный указатель на объект. И дальше на протяжении программы работаем с объектом только через указатель, так?
Мотивация не та, но мысль правильная.То, что у класса лишь один экземпляр - это не плохо само по себе. Есть даже такой архитекрутный паттерн, как "Singleton". (Готов поспорить с желающими назвать его антипаттерном).
Модуляризацией приложения можно улучшить абстракцию элементов программы, что упростит поддержку (модернизацию) и позволит проводить их независимое тестирование.
Но чтобы понять, какие проблемы такой подход решает, их нужно встретить самостоятельно.
Ну и монолит пишется компактнее и лучше читается. Новичкам это важнее.
Я как Singleton использую в 99% случаев только главный корневой класс-объект :) И то, только с возвратом экземпляра без автоматического создания :) Это отличный паттерн при правильном использовании :)
А вот как бы данную прогу выполнить в стиле Model-View-Controller?
Не будет времени хоть приблизительно наметить где какие классы и методы будут располагаться при применении данного паттерна?
Вообще, надо подобие танчиков в MVC, но следующая прога слишком заморочена, так как после еще и придется разные алгоритмы и диаграммы по проге составлять.
Думаю, если уж с этой разберусь, то что-то немногим сложнее как по маслу пойдет.
Эээм... Ну это ИМХО уже слишком - наворачивать MVC для примитивного консольного приложения :) Оверинженеринг какой-то :)
Так курсовой проект задали реализовать игру именно в консоли, причем применяя MVC в обязательном порядке. Надеялся на Ваши уроки, думал, что поболее вникну в указатели и объекты - и справлюсь, но нет... Причем само описание паттерна вполне понятно, а вот на реализации встрял, не то что с нуля, а даже просто переделать мозгов не хватает.
Я совсем скатился в своих же глазах.
Не смог Вашу версию программы запустить.
https://pp.vk.me/c636626/v636626618/47075/I7zHxQ4Hl9w.jpg
В принципе, ведь модель - это исходное поле (двумерный массив) и все вычисления, вид - система рендера, а вот как это грамотно через контроллер пропустить...