|
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
|
||||||||||||||||||||||||||
Создание игр в текстовом режиме17.02.2014, 00:43. Показов 8175. Ответов 67
Метки нет (Все метки)
Привет всем! Тут занялся написанием игрушек в текстовом режиме, типа змейки, тетриса и т.п. Суть в том, что я хочу как можно более правильно написать код, со стороны рефакторинга, со стороны выделения и освобождения памяти, и многих других аспектов. Думаю эта тема поможет многим новичкам, в написание чего-либо подобного, поэтому буду потихоньку выкладывать свои исходники и ждать ваших комментариев.Долго думал куда все-таки отнести эту тему, но решил остановиться здесь.
Итак, сейчас я хочу выложить класс интерфейса(менюшка), и данный класс будет использоваться в любой мной написанной игре. Файл _interface.h
У меня есть 8 методов в области видимости protected, которые будут доступны соответственно классу - потомку. Сейчас распишу примерно, что каждый метод делает: Кликните здесь для просмотра всего текста
int CurrentMenu() - Соответственно получает номер текущего меню. При создании первого экземпляра класса - потомка номер текущего меню равен 0.
static void NextMenu() - Изменяет номер текущего меню на следущее +1. static void BackMenu(); - Изменяет номер текущего меню на предыдущее -1. int CurrentCursor() - Получаем номер текущего пункта меню, где в данное время находится каретка указателя. void AddListMenu(wstring) - Так мы можем добавить пункт меню в список меню. void ClearListMenu() - Соответсвенно, что видно из название - очищаем список меню. int SizeListMenu() - Размер текущего списка меню(Количество пунктов меню данного списка). void DrawMenu() - Метод прорисовки списка меню и выбора определенного пункта меню. Теперь расскажу про область видимости private. Там находятся поля класса. Про них особо нечего рассказывать, практически все методы, которые были описаны выше, просто манипулируют этими полями и все: Кликните здесь для просмотра всего текста
static int current_menu - Номер текущего меню. Причем сколько бы экземпляров класса - потомка не было, это значение для всех общее.
int current_cursor - Номер текущего пункта меню, где в данное время находится каретка указателя. int x,y - Координаты вывода списка меню на экране. ListMenu *menu - Ну и конечно структура самого списка меню, состоящая из одного всего поля - вектора библиотеки STL, где хранятся все пункты меню. Ну и public: Кликните здесь для просмотра всего текста
_interface(int,int) - Конструктор как вы поняли.
~_interface() - Деструктор соответственно. virtual void Run() = 0 - Вот это самое интересное.Это чисто виртуальная функция, которая будет заводить всю систему меню. Она должна обязательно быть перегружена в классе - потомке, и все меню и события по нажатию на определенные пункты меню должны создаваться в ней. То есть все что связано с меню, должно выполняться именно в этой функции. virtual void Run(ListMenu*) = 0 - Метод Run(), это статическое управление списками меню, то есть я не могу создавать, изменять, удалять меню программно. Для этого я создал функцию Run(ListMenu*), которая делает все тоже самое что и Run(), только принимает в качестве формального параметра список меню, что следовательно,что я могу создать меню программно, что иногда очень бывает нужно. Выкладываю определение всех методов данного класса. Файл _interface.cpp
Давайте создадим меню из списка: START, OPTION, EXIT. По нажатию на START - Выводится сообщение "hello world" По нажатию на OPTION - Создается второе меню - DINAMIC CREATE MENU, MESSAGE, BACK По нажатию на EXIT - Выходим из программы Теперь распишем что будет делать второе меню,созданное по нажатию на OPTION. По нажатию на DINAMIC CREATE MENU - Создается динамическое меню, из 6 пунктов, если нажмем на один из первых трех - вернемся назад на второе меню, если нажмем на один из трех следующих - вернемся на START, ... По нажатию на MESSAGE - Выводится сообщение "I Love CyberForum" и возвращаемся на меню START, ... По нажатию на BACK - Возвращаемся назад на первое меню Ну вот более менее подходящее меню, чтобы задействовать всю мощь моего написанного класса) Реализовываем. Файл ___interface.cpp
1
|
||||||||||||||||||||||||||
| 17.02.2014, 00:43 | |
|
Ответы с готовыми решениями:
67
Создание интерфейса пользователя в текстовом режиме
Работа с экраном в текстовом режиме |
| 22.02.2014, 00:49 | |
|
0
|
|
|
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
|
||||||||||||||||||||||||||
| 23.02.2014, 00:42 [ТС] | ||||||||||||||||||||||||||
|
Так, наконец нашел время все поправить в лучшую сторону. По вашим комментарием собрал вот это:
Файл Interface.h
Файл Inteface.cpp
Файл InterfaceChild.h
Файл InterfaceChild.cpp
Ну и конечно же сам main.cpp
Вроде все, ничего не забыл) Ну теперь жду ваших новых комментариев по новому "улучшенному коду". Что скажете? Так оставлять или можно что-то еще изменить?)
0
|
||||||||||||||||||||||||||
|
Антикодер
1889 / 871 / 48
Регистрация: 15.09.2012
Сообщений: 3,092
|
|
| 23.02.2014, 01:11 | |
|
Название класса Interface не несёт в себе никакой сущности, вы также не определяете пространств имен для класса.
В больших проектах это грозит тем, что на использование класса Interface будут претендовать совершенно разные по назначению классы, и в конечном счете заставит разделить вас класс Interface на несколько. Этой ситуации можно избежать, определив на ранних этапах сущности предметной области, что я и пытался объяснить в статье на которую давал ссылку. Думаю Страуструп также относит ваш подход к "overabstract" Поэтому дальше названия класса проверять не интересно.
0
|
|
|
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
|
|
| 23.02.2014, 01:29 [ТС] | |
|
XRuZzz, я не понял, какой сущности нет в названии моего класса?Если я переименую его в AbstractInterface то будет у него сущность?или я вас не правильно понял?объясните пожалуйста.
а про какие пространства имен идет речь?у меня в классе используется только одно пространство имен std и больше ничего.
0
|
|
|
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
|
||||||
| 23.02.2014, 08:24 | ||||||
|
Для такой простой задачи написать такой сложный класс - это, конечно, надо было постараться.
Не будем зарываться в реализацию, а посмотрим на класс с точки зрения пользователя. По идее, должно быть достаточно посмотреть на интерфейс класса, чтобы стало ясно как его использовать. А что у нас в интерфейсе?
Ок, второй метод я еще могу понять - передаем список пунктов, которые следует отобразить. А первый? Откуда он возьмет этот список? Интерфейс не дает ответов на эти вопросы. А теперь главный фейл - метод run чисто виртуальный. Т.е. я, как пользователь, обязан каждый раз для каждого меню писать свой дочерний класс и каждый раз реализовывать логику выбора пункта и отрисовки меню? Вот уж чего мне точно хочется меньше всего. Скорее всего в большинстве случаев логика будет одна: выбрали пункт - вызвали его обработчик - отрисовали меню. В данном случае эта логика уже реализована в дочернем классе, и тут возникает вопрос - это пример использования или этот класс является частью библиотеки? Если это пример использования, то он отлично показывает насколько плох базовый класс - 120+ строк кода, да еще и с не пойми зачем появившейся рекурсией. В моей маленькой голове не укладывается зачем методу run() может потребоваться вызывать себя. Если же этот класс предоставляется библиотекой, то не ясно на каких правах в нем захардкожены какие-то пункты меню. Мне могут понадобиться совсем другие. Дальше смотреть смысла нет, ибо даже если я и решусь реализовывать метод run в своем классе меню, то мне придется смотреть в секцию protected и разбираться какой порядок вызова предполагают предоставляемые методы. Еще класс навязывает свой способ отрисовки. У меня, например, нет заголовочного файла msoftcon.h (я так понимаю, функции для работы с псевдографикой объявлены в нем). В общем, напишите для начала простое текстовое меню... Тут еще есть какие-то списки менюшек - не надо. Пусть будет один уровень.
0
|
||||||
|
Антикодер
1889 / 871 / 48
Регистрация: 15.09.2012
Сообщений: 3,092
|
||
| 23.02.2014, 09:40 | ||
|
Класс относится к сущности представления главного окна программы. в MVC паттерне я бы назвал его как то вроде MainFormViews. Я к тому что по названию класса Interface нельзя догадаться относится ли он к главному окну, либо у вас он нужен для какого нить протокола, либо ещё какой-нить интерфейс для работы с реализациями абстрактных классов, который никак не относится к выводу в консоль. Впрочем еслu вам не нравumcя мой подход, вы можеmе проuгнорuроваmь моё сообщенuе. Во многом согласен c 0x10.
0
|
||
|
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
|
|
| 23.02.2014, 22:39 [ТС] | |
|
XRuZzz, я не хочу игнорировать никакое сообщение, ибо дальше я буду выкладывать уже сами игрушки с использованием этого класса меню.Я хочу преслушиваться к каждому мнению, чтобы добиться как можно идеальной техники кода.
Итак,снова я вас не понимаю, мне нужно мой класс переименовать в MainFormViews для лучшего представления того,что данный класс делает?) А с пространством имен снова не понял( Вы можете,если вам не сложно, изменить мой код и выложить мне?
0
|
|
|
Антикодер
1889 / 871 / 48
Регистрация: 15.09.2012
Сообщений: 3,092
|
|||
| 24.02.2014, 09:40 | |||
|
К вашему коду естественно такое название мало подходит. Техника зависит от опыта, опыта вряд ли вам в форуме за пару дней сильно улучшить технику программирования. Чтоб углубится в мои подходы к программированию. Нужно потратить значительное время на изучение сайта www.uml2.ru. вот что пишет Страуструп:
0
|
|||
|
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
|
|
| 25.02.2014, 00:30 [ТС] | |
|
XRuZzz,вы можете сказать,кроме как названия класса,что нибудь нужно менять еще?может в самом классе нужно изменить что нибудь?или все как надо там?
0
|
|
|
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
|
|
| 26.02.2014, 02:47 [ТС] | |
|
ммммм?)
0
|
|
|
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
|
|
| 27.02.2014, 22:06 [ТС] | |
|
Надеюсь вы не отписались от моей темы,потому что я продолжаю!)
В этот раз я выкладываю прикладное приложение для создания карт моих будущих игр)Класс интерфейса(меню) использован тот же,что я и выкладывал) Итак жду снова ваших мнений и предложений!
0
|
|
|
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
|
|
| 01.03.2014, 00:25 [ТС] | |
|
неужели все отписались от темы?)
0
|
|
|
Каратель
|
|
| 01.03.2014, 01:58 | |
|
0
|
|
|
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
|
|
| 01.03.2014, 02:30 [ТС] | |
|
0x10, хм...странно,я ваш комментарий почему-то пропустил.Вот что значит сидеть с мобильного в интернете(
Мой класс Interface является библиотекой,пользователь должен будет создать дочерний класс,чтобы начать использовать и создавать меню.Его нужно создавать только в функции run(),если пользователь хочет создать меню еще до компиляции,тоесть статически,ну или использовать run(ListMenu*),для того,чтобы создать меню уже динамически.Только за этим я разделил эти две функции. Рекурсия использована,для перехода между списками иерархии меню и не больше. 120 строк...я согласен,но что убрать тогда,чтобы сделать базовый класс меньше? объясните плизз Добавлено через 2 минуты Jupiter,а что вы скажете по поводу "создания карт"?)
0
|
|
|
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
|
||
| 01.03.2014, 06:43 | ||
|
1
|
||
|
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
|
|
| 02.03.2014, 01:51 [ТС] | |
|
0x10,я вас понял...все переделаю нафиг)завтра выложу)а что скажете про создание карт?)
0
|
|
|
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
|
|
| 02.03.2014, 08:20 | |
Сообщение было отмечено Bretbas как решение
Решение
Было бы желание, а разнести можно за каждую строчку... Я не уверен, имеет ли смысл расписывать или пусть автор дойдет своим умом.
Пробежимся раз по интерфейсам и местами по реализации. Дисклеймер: все сказанное - не прямое руководство к действию. Посмотрим на интерфейс класса Matrix. В паблике у нас два конструктора: с параметрами и без. Внимание, вопрос: какой смысл автор вкладывает в конструктор матрицы без параметров? Что должно произойти? Создаться матрица размера 0х0? Как потом с ней работать? По факту выясняется, что этот конструктор не делает ничего. видимо, его и быть не должно. Смысл конструктора с двумя параметрами интуитивно понятен - создание матрицы размера rows*cols. Забегая вперед, реализация конструктора не соответствует ожиданиям. В публичном доступе также есть данные: собственно, сама матрица и ее размерности. Причем ни о какой инкапсуляции и речи нет - пользователю навязывается тот факт, что матрица реализована как двумерный массив, что, кстати, может быть и иначе. Более того, массив этот всегда фиксированного размера. Размерности матрицы также ничем не защищены и могут быть изменены независимо. Т.е. где-то в коде я могу поменять, например, высоту, а в другом месте - вылететь за пределы массива при обходе матрицы. В общем, интерфейс неудобен, не является универсальным и вообще потенциально опасен в использовании. Еще интересности в приватной части: некая функция Mod_. Комментарий сообщает, что это проверка четности. Тут надо вспомнить, что есть оператор %, которым можно проверить четность. И вообще: какое отношение обычная операция с двумя целыми числами имеет к матрице? Посмотрим теперь на реализацию. Реализация конструктора, как я уже заметил выше, дикая. Внезапно конструктор устанавливает цвета в терминале, выводит сообщения в случае ошибок и, что еще круче, в случае ошибки вызывает exit(). Разделите данные и представление. Матрица - это всего лишь контейнер объектов, никакого отношения к представлению он не имеет. Более того, в нем не должны фигурировать никакие ограничения по размеру матрицы относительно размера окна. В общем, тут две сущности слились в одну: сама матрица и ее представление в окне. Метод Mod_ делает странное и не соответствующее комментарию. Проверяет он делимость первого аргумента на второй. Как я уже говорил, тут не нужны циклы, а есть оператор %. Еще у класса есть производный - MatrixChild, который не расширяет функционал базового ничем. Следовательно, и быть его не должно. Класс Cursor. Аналогичная проблема с инкапсуляцией - координаты открыты, доступны для изменения. Главная неожиданность - курсор ссылается на матрицу. Все ради того, чтобы нельзя было сместить его за пределы матрицы. Опять же странная логика. Матрица - контейнер, не важно как она отображается. Курсор - пассивная структура со своей позицией. Мне видится, что явно не ему принимать решение куда двигаться можно, а куда нельзя. Ну а класс Map - это просто свалка. Тут и редактирование, и доступ к файловой системе, все вперемешку.
0
|
|
|
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
|
|
| 03.03.2014, 02:19 [ТС] | |
|
0x10, слушайте,по вашим комментарием хочется все взять и удалить нафиг,и не делать ничего больше...но надо,надо учиться)на счет сущностей,что каждому классу делать,а что не делать,это вы про MVC наверное?)Если да,то есть какая нибудь хорошая книга по MVC с примерами на C++?Не подскажете?
0
|
|
|
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
|
||||
| 03.03.2014, 05:54 | ||||
|
Например, из моего поста не ясно почему курсор не может ссылаться на карту. Ведь и так все работает. Да и я сходу не придумаю пример когда все будет плохо. Если только не допустить, что в других местах программы (в менюшках или еще где) возникнут курсоры с теми же данными (координатами), но с другим поведением (или с другими допустимыми границами). При разработке маленького монолитного приложения, в котором переиспользовать особо нечего (или кажется, что нечего) действительно может показаться, что все это не нужно. Но после написания нескольких таких приложений станет очевидно, что какие-то части кода дублируются во всех практически без изменений. И тогда захочется общие части вынести в библиотеку - и тут уже ее нужно сделать универсальной. Было бы дико, если бы контейнеры стандартной библиотеки в Вашей программе что-то сами писали в stdout, так? Мне, например, видится, что логику обработки навигации по меню можно обобщить и не заставлять клиента каждый раз собирать по кирпичикам метод run. Это как пример. http://ru.wikiversity.org/wiki... 0%BA%D0%B8 http://rsdn.ru/article/patterns/generic-mvc.xml Только без фанатизма. Не обязательно всегда слепо следовать паттерну в том виде, в котором он реализован в примере. Подвижки допустимы. Почитать можно Макконнелла - "Совершенный код". Там в основном капитанство, но некоторые эвристические принципы описаны, лишним не будет. "Паттерны проектирования" GoF - хорошая, но опять же надо без фанатизма.
0
|
||||
|
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
|
|
| 06.03.2014, 00:04 [ТС] | |
|
0x10, слушайте...я читаю данные вами статьи про MVC,но не могу понять как разделить данные...мне до сих пор кажется,что они разделены( Я на счет "создания карт"
Вы можете мне словами рассказать,что именно нужно разделить,и к примеру каким образом выводить сообщение об ошибки,если я введу слишком большие размеры матрицы...Ведь манипуляции с матрицей это и есть МОДЕЛЬ,так?Передача размеров матрицы происходит в ПРЕДСТАВЛЕНИИ,которое в свою очередь передает эти размеры КОНТРОЛЛЕРУ на проверку,так?И взависимости прааильные ли они или нет,идем дальше к МОДЕЛИ или ПРЕДСТАВЛЕНИЮ для отображения соответствующего сообщения.Значит мне нужно делать 3 класса - МОДЕЛЬ,ПРЕДСТАВЛЕНИЕ,КОНТРОЛЛЕР для осуществления работы с матрицей?И так нужно и для класса Map и остальных классов?так чтоли?
0
|
|
| 06.03.2014, 00:04 | |
|
ООП иерархия классов с выводом в текстовом режиме Нарисовать мышью прямоугольник в текстовом режиме экрана Как сделать прокрутку (в текстовом режиме) и менюшку в turbo c Работа с экраном в текстовом режиме (вывод всех цветов фона, разделяя цвета паузой) Создание приложения в визуальном режиме Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version
Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
|
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер
На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
|
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/
TL DR
Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
|
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык.
Возвращает он вот это:
https:/ / i. **********/ vqBWLe2. png
Нужную строчку в 3й колонке просто выдумал. .
Это. . .
|
|
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor.
Это. . .
|
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js.
В помощники взял Яндекс-Алису.
Было создано три зала на разные интересы.
исторические и ретро
сериал Хичкок. . .
|
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
|
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#.
Название изменил на ColorStep.
Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
|