Форум программистов, компьютерный форум CyberForum.ru

Создание игр в текстовом режиме - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 24, средняя оценка - 4.71
Bretbas
22 / 17 / 1
Регистрация: 05.08.2013
Сообщений: 468
Завершенные тесты: 1
17.02.2014, 00:43     Создание игр в текстовом режиме #1
Привет всем! Тут занялся написанием игрушек в текстовом режиме, типа змейки, тетриса и т.п. Суть в том, что я хочу как можно более правильно написать код, со стороны рефакторинга, со стороны выделения и освобождения памяти, и многих других аспектов. Думаю эта тема поможет многим новичкам, в написание чего-либо подобного, поэтому буду потихоньку выкладывать свои исходники и ждать ваших комментариев.Долго думал куда все-таки отнести эту тему, но решил остановиться здесь.
Итак, сейчас я хочу выложить класс интерфейса(менюшка), и данный класс будет использоваться в любой мной написанной игре.

Файл _interface.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#pragma once
#include <iostream>
#include <vector>
#include <string>
#include "msoftcon.h"
using namespace std;
 
 
/* ## Cтруктура списка интерфейса ## */
struct ListMenu 
{
    vector<wstring> item;
};
 
 
/* ## Абстрактный класс интерфейса ## */
class _interface
{
protected:
    int CurrentMenu();                              // Получение текущего списка меню
    int CurrentCursor();                            // Получение каретки текущего пункта меню
    static void NextMenu();                         // Следующий список меню
    static void BackMenu();                         // Предыдущий список меню
    void AddListMenu(wstring);                      // Добавить пункт в список меню
    void ClearListMenu();                           // Очистить список меню
    int SizeListMenu();                             // Размер списка меню
    void DrawMenu();                                // Прорисовка списка меню
 
private:
    static int current_menu;                        // Текущий список меню
    int current_cursor;                             // Каретка текущего пункта меню
    int x,y;                                        // Координаты прорисовки списка на экране
    ListMenu *menu;                                 // Структура списка меню
 
public:
    _interface(int,int);                            // Конструктор
    ~_interface();                                  // Деструктор
 
    virtual void Run() = 0;                         // Запуск статической системы меню
    virtual void Run(ListMenu*) = 0;                // Запуск динамической системы меню
};
Ну что могу сказать по поводу этого класса. Ну первое, это абстрактный класс, то есть создание экземпляров от этого класса будет невозможно.

У меня есть 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

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "_interface.h"
 
 
int _interface :: current_menu = 0;
 
 
/* ## Конструктор ## */
_interface :: _interface(int x1,int y1) : x(x1),y(y1)
{ 
    init_graphics();
    menu = new ListMenu;
}
 
 
/* ## Деструктор ## */
_interface :: ~_interface()
{ }
 
 
/* ## Следующий список меню ## */
void _interface :: NextMenu()
{
    current_menu++;
}
 
 
/* ## Предыдущий список меню ## */
void _interface :: BackMenu()
{
    current_menu--;
}
 
 
/* ## Получение текущего списка меню ## */
int _interface :: CurrentMenu()
{
    return current_menu;
}
 
 
/* ## Получение каретки текущего пункта меню ## */
int _interface :: CurrentCursor()
{
    return current_cursor;
}
 
 
/* ## Добавить пункт в список меню ## */
void _interface :: AddListMenu(wstring item)
{
    menu -> item.push_back(item);
}
 
 
/* ## Очистить список меню ## */
void _interface :: ClearListMenu()
{
    menu -> item.clear();
}
 
 
/* ## Размер списка меню ## */
int _interface :: SizeListMenu()
{
    return menu -> item.size();
}
 
 
/* ## Прорисовка списка меню ## */
void _interface :: DrawMenu()
{
    set_color(cWHITE,cBLACK);
    clear_screen();
 
    for(int i = 0; i < menu -> item.size(); i++)
    {
        set_cursor_pos(x + 4,y + i);
        wcout << menu -> item[i] << endl;
    }
 
    set_cursor_pos(x,y);
    current_cursor = 1;
    char c;
 
    do
    {
        for(int i = 0; i < SizeListMenu(); i++)
        {
            if(i == current_cursor - 1)
            { set_color(cBLACK,cYELLOW); }
            else
            { set_color(cBLACK,cBLUE); }
 
            set_cursor_pos(x,y + i);
            cout << "->";
        }
 
        c = _getch();
 
        switch(c)
        {
        case 72: if(current_cursor != 1) { current_cursor = current_cursor - 1; } break;
        case 80: if(current_cursor != SizeListMenu()) { current_cursor = current_cursor + 1; } break;
        }
    }
    while(c != 13);
}
Ну если все понятно, можно теперь создать собственно меню.) Создаем вначале класс - потомок. Файл ___interface.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma once
#include "_interface.h"
using namespace std;
 
 
/* ## Производный класс от класса интерфейса ## */
class ___interface : public _interface
{
public:
    ___interface(int,int);      // Конструктор
    ~___interface();            // Деструктор
 
    void Run();                 // Запуск статической системы меню
    void Run(ListMenu*);        // Запуск динамической системы меню
};
Здесь вроде все понятно, теперь соответственно определяем функции Run() и Run(ListMenu*). Но прежде чем их определить, нужно придумать меню).
Давайте создадим меню из списка: 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

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "___interface.h"
 
 
/* ## Конструктор ## */
___interface :: ___interface(int x,int y) : _interface(x,y)
{ }
 
 
/* ## Деструктор ## */
___interface :: ~___interface()
{ }
 
 
/* ## Запуск системы ## */
void ___interface :: Run()
{
    set_color(cWHITE,cBLACK);
 
    ClearListMenu();
 
    switch(CurrentMenu())
    {
    case 0: // Первое меню - START  OPTION  EXIT
        {
            AddListMenu(L"START");
            AddListMenu(L"OPTION");
            AddListMenu(L"EXIT");
 
            DrawMenu();
 
            switch(CurrentCursor())
            {
            case 1:
                {
                    clear_screen();
                    cout << "hello world";
                    getch();
                }
            break;
 
            case 2:
                {
                    NextMenu();
                }
            break;
 
            case 3:
                {
                    exit(0);
                }
            break;
            }
        }
    break;
 
    case 1: // Второе меню - DINAMIC CREATE MENU   MESSAGE   BACK
        {
            AddListMenu(L"DINAMIC CREATE MENU");
            AddListMenu(L"MESSAGE");
            AddListMenu(L"BACK");
 
            DrawMenu();
 
            switch(CurrentCursor())
            {
            case 1:
                {
                    clear_screen();
                    ListMenu* DinamicMenu = new ListMenu;
                    wstring item;
 
                    for(int i = 0; i < 6; i++)
                    {
                        cout << "Input item of menu";
                        wcin >> item;
                        DinamicMenu -> item.push_back(item);
                    }
 
                    Run(DinamicMenu); // Создаем новое меню динамически
                }
            break;
 
            case 2:
                {
                    clear_screen();
                    cout << "I Love CyberForum";
                    getch();
                    BackMenu();
                }
            break;
 
            case 3:
                {
                    BackMenu();
                }
            break;
            }
        }
    break;
 
    }
 
    Run(); // Рекурсивно вызываем эту же функцию
}
 
 
void ___interface::Run(ListMenu *list)
{
    set_color(cWHITE,cBLACK);
    NextMenu();
    ClearListMenu();                                // Очищаем список
 
    for(int i = 0; i < list -> item.size(); i++)
    {
        AddListMenu(list -> item[i]);               // Инициализируем список с формальным параметром
    }
 
    DrawMenu();                                     // Прорисовка списка меню
 
    switch(CurrentCursor())
    {
    case 1: BackMenu(); break;
    case 2: BackMenu(); break;
    case 3: BackMenu(); break;
    case 4: { BackMenu(); BackMenu(); } break;
    case 5: { BackMenu(); BackMenu(); } break;
    case 6: { BackMenu(); BackMenu(); } break;
    }
}
В main.cpp можно вызвать меню таким способом:

C++
1
2
3
4
5
6
7
8
9
#include "___interface.h"
 
 
void main()
{
    ___interface *inter = new ___interface(38,10);
 
    inter -> Run();
}
Постепенно я буду выкладывать и остальные части игр, и буду слушать ваше мнение по написанному. Почему я начал с меню? Потому что это главный класс, который заводит всю игру, и его нужно написать на сколько можно правильно. Поэтому жду ваших комментариев,критик по поводу написанного, может что то нужно изменить, добавить, убрать. Я прислушаюсь к любому мнению)
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
06.03.2014, 05:44     Создание игр в текстовом режиме #41
Цитата Сообщение от Bretbas Посмотреть сообщение
Значит мне нужно делать 3 класса
Как я уже говорил - не нужно слепо следовать паттерну. Каждая сущность может быть представлена несколькими классами, их композицией. Или же вообще классов может не быть - если окажется достаточно свободной функции.

Чтобы предложить какое-нибудь решение, расскажите словами что хочется получить в итоге. Что из себя представляет карта, предполагается ли скроллинг, какие элементы уровня должны быть, что вы хотите делать с этой картой (сохранение, загрузка). Чтобы я не навязывал какое-то свое видение.
Понятно, что это может показаться очевидным. "Карта - это набор клеток, каждая из которых может быть своего цвета". Но важно формализовать все детали. Возможно, характеристики объектов: проходимость, триггеры событий. Для какой вообще игры делается редактор. Или это будет семейство игр. Нужно понять что у них общего и в чем различия, чтобы либо принять решение где разделять интерфейс и реализацию, определить наиболее вероятные места изменений и т п.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Bretbas
22 / 17 / 1
Регистрация: 05.08.2013
Сообщений: 468
Завершенные тесты: 1
07.03.2014, 22:17  [ТС]     Создание игр в текстовом режиме #42
Короче по максимому изменил мой класс Меню,в лучшую сторону или нет, судить конечно не мне а Вам. А как мне кажется, он ниче так)
Во-первых, теперь он у меня не абстрактный.Потому что, я подумал что это не нужно в принципе.
Во-вторых, я написал библиотеку графики,точнее стащил пол кода с книги Р.Лафоре, и сделал на его "Упрощенном варианте консольной графики" класс. Теперь этот класс я использую везде, где хочу изменить цвет, стереть с экрана что-нибудь, или расположить курсор в нужном мне месте. Думаю это стало более удобнее, чем было раньше. Но меню не будет работать без этого класса, поэтому его нужно таскать всегда с собой.
В-третьих, избавился от функций run вовсе, они мне не нужны) Создаю меню я в главной функции main и все такое)

Итак сами файлы:

Файл Menu.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#ifndef MENU_H_
#define MENU_H_
 
#include <iostream>
#include <vector>
#include <string>
#include <conio.h>
 
#include "Grafic.h"
 
 
/* ## Класс интерфейса ## */
class Menu
{
private:
    static int number_current_menu_;                    // Номер текущего списка меню
    int current_cursor_;                                // Каретка текущего пункта меню
    int x_, y_;                                         // Координаты прорисовки списка на экране
    static std :: vector<std :: wstring> list_menu_;    // Список меню
    Grafic *grafic_;                                    // Объект графики
 
public:
    Menu(int,int);                                      // Конструктор
    ~Menu();                                            // Деструктор
 
    void add_list_menu(std :: wstring);                 // Добавить пункт в список меню
    void draw_menu();                                   // Прорисовка списка меню
    int current_menu() const;                           // Получение номера текущего списка меню
    int current_cursor() const;                         // Получение каретки текущего пункта меню
    static void next_menu();                            // Следующий список меню
    static void back_menu();                            // Предыдущий список меню
};
 
#endif  MENU_H_
Файл Menu.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "Menu.h"
 
 
int Menu :: number_current_menu_ = 1;
std :: vector<std :: wstring> Menu :: list_menu_;
 
 
/* ## Конструктор ## */
Menu :: Menu(int x,int y) : x_(x),y_(y)
{ 
    grafic_ = new Grafic;
}
 
 
/* ## Деструктор ## */
Menu :: ~Menu()
{ }
 
 
/* ## Следующий список меню ## */
void Menu :: next_menu()
{
    if(number_current_menu_ != list_menu_.size())
    { number_current_menu_++; }
}
 
 
/* ## Предыдущий список меню ## */
void Menu :: back_menu()
{
    if(number_current_menu_ != 0)
    { number_current_menu_--; }
}
 
 
/* ## Получение текущего списка меню ## */
int Menu :: current_menu() const
{
    return number_current_menu_;
}
 
 
/* ## Получение каретки текущего пункта меню ## */
int Menu :: current_cursor() const
{
    return current_cursor_;
}
 
 
/* ## Добавить пункт в список меню ## */
void Menu :: add_list_menu(std :: wstring item)
{
    list_menu_.push_back(item);
}
 
 
/* ## Прорисовка списка меню ## */
void Menu :: draw_menu()
{
    if (list_menu_.empty())
    {
        grafic_ -> clear_screen();
        std :: cout << "Check your list menu!It is empty!";
        _getch();
        exit(0);
    }
 
    grafic_ -> set_color(cWHITE,cBLACK);
    grafic_ -> clear_screen();
 
    for(unsigned int i = 0; i < list_menu_.size(); i++) 
    {
        grafic_ -> set_cursor_pos(x_ + 4,y_ + i);
        std :: wcout << list_menu_[i] << std :: endl;
    }
 
    grafic_ -> set_cursor_pos(x_,y_);
    current_cursor_ = 1;
    char c;
 
    do
    {
        for(unsigned int i = 0; i < list_menu_.size(); i++)
        {
            if(i == current_cursor_ - 1)
            { grafic_ -> set_color(cBLACK,cYELLOW); }
            else
            { grafic_ -> set_color(cBLACK,cBLUE); }
 
            grafic_ -> set_cursor_pos(x_,y_ + i);
            std :: cout << "->";
        }
 
        c = _getch();
 
        switch(c)
        {
        case 72: if(current_cursor_ != 1) { current_cursor_--; } break;
        case 80: if(current_cursor_ != list_menu_.size()) { current_cursor_++; } break;
        }
    }
    while(c != 13);
 
    list_menu_.clear();
}
Файл Grafic.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef GRAFIC_H_
#define GRAFIC_H_
 
#include <iostream>
#include <windows.h>
 
 
/* ## Список перечисления ## */
enum color
{
    cBLACK=0, cDARK_BLUE=1, cDARK_GREEN=2, DARK_CYAN=3, cDARK_RED=4, cDARK_MAGENTA=5, cBROWN=6, cLIGHT_GRAY=7,
    cDARK_GRAY=8, cBLUE=9, cGREEN=10, cCYAN=11, cRED=12, cMAGENTA=13, cYELLOW=14, cWHITE=15
};
 
 
/* ## Класс графики ## */
class Grafic
{
private:
    static HANDLE h_console_;                       // Дескриптор окна консоли
 
public:
    Grafic();                                       // Конструктор
    ~Grafic();                                      // Деструктор
 
    void set_color(color fg,color bg = cBLACK);     // Установка цвета
    void set_cursor_pos(int x,int y);               // Установка позиции курсора
    void clear_screen();                            // Стирание экрана
};
 
#endif GRAFIC_H_
Файл Grafic.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include "Grafic.h"
 
 
HANDLE Grafic :: h_console_ = NULL;
 
 
Grafic :: Grafic()
{
    COORD console_size = {80,25};
 
    h_console_ = CreateFile( L"CONOUT$",
                            GENERIC_WRITE |
                            GENERIC_READ,
                            FILE_SHARE_READ |
                            FILE_SHARE_WRITE,
                            0L,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL,
                            0L );
 
    SetConsoleScreenBufferSize(h_console_,console_size);
 
    SetConsoleTextAttribute(h_console_,(WORD)((0<<4) | 15));
 
    clear_screen();
}
 
 
Grafic :: ~Grafic()
{ }
 
 
void Grafic :: set_color(color foreground,color background)
{
    SetConsoleTextAttribute(h_console_,(WORD)((background<<4) | foreground));
}
 
 
void Grafic :: set_cursor_pos(int x,int y)
{
    COORD cursor_pos;
    cursor_pos.X = x - 1;
    cursor_pos.Y = y - 1;
 
    SetConsoleCursorPosition(h_console_,cursor_pos);
}
 
 
void Grafic :: clear_screen()
{
    set_cursor_pos(1,25);
 
    for(int j = 0;j < 25;j++)
    { std :: cout << "\n"; }
 
    set_cursor_pos(1,1);
}
И конечно же сам main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <iostream>
#include <conio.h>
 
#include "Menu.h"
#include "Grafic.h"
 
using namespace std;
 
int main()
{
    Grafic *grafic = new Grafic;
    Menu *inter = new Menu(38,10);
    
    for(;;)
    {
        switch(inter -> current_menu())
        {
        case 1: // Первое меню - START  OPTION  EXIT
            {
                inter -> add_list_menu(L"START");
                inter -> add_list_menu(L"OPTION");
                inter -> add_list_menu(L"EXIT");
 
                inter -> draw_menu();
 
                switch(inter -> current_cursor())
                {
                case 1:
                    {
                        grafic -> clear_screen();
                        cout << "hello world";
                        _getch();
                    }
                break;
 
                case 2:
                    {
                        inter -> next_menu();
                    }
                break;
 
                case 3:
                    {
                        exit(0);
                    }
                break;
                }
            }
        break;
 
        case 2: // Второе меню - DINAMIC CREATE MENU   MESSAGE   BACK
            {
                inter -> add_list_menu(L"DINAMIC CREATE MENU");
                inter -> add_list_menu(L"MESSAGE");
                inter -> add_list_menu(L"BACK");
 
                inter -> draw_menu();
 
                switch(inter -> current_cursor())
                {
                case 1:
                    {
                        grafic -> clear_screen();
                        wstring item;
                        vector<wstring> dimanic_menu;
 
                        for(int i = 0; i < 6; i++)
                        {
                            cout << "Input item of menu";
                            wcin >> item;
                            inter -> add_list_menu(item);
                        }
 
                        inter -> draw_menu();
 
                        switch(inter -> current_cursor())
                        {
                        case 1: inter -> back_menu(); break;
                        case 2: inter -> back_menu(); break;
                        case 3: { inter -> back_menu(); } break;
                        }
                    }
                break;
 
                case 2:
                    {
                        grafic -> clear_screen();
                        cout << "I Love CyberForum";
                        _getch();
                        inter -> back_menu();
                    }
                break;
 
                case 3:
                    {
                        inter -> back_menu();
                    }
                break;
                }
            }
        break;
        }
    }
 
    return 0;
}
Жду снова ваших комментариев по поводу написанного. Надеюсь хоть на этот раз более-менее грамотно написано, и можно продолжать дальше)
XRuZzz
Антикодер
577 / 478 / 23
Регистрация: 15.09.2012
Сообщений: 2,429
07.03.2014, 23:05     Создание игр в текстовом режиме #43
Цитата Сообщение от Bretbas Посмотреть сообщение
grafic_ = new Grafic;
че то deletе-a не вижу.
Цитата Сообщение от Bretbas Посмотреть сообщение
Надеюсь хоть на этот раз более-менее грамотно написано
можно до бесконечности стремиться к идеалу в коде, но намного разумнее почитать что нить новое, или придумать что то новое в архитектуре кода самому.
Я например недавно добавил в свою прогу JSON парсер на основе boost property tree[ поддерживает также XML и INI]. Это позволяет хранить конфигурационный файл проги в удобном виде.
Решение в booste казалось бы красивое, но когда начинаешь рассуждать, оказывается, что можно сделать более универсальный и изящный код. Доходит до того, что хочется переделать весь C++. Раньше я считал, что языков программирования слишком много, терь я считаю, что недостаточно, так как нет подходящего.
Bretbas
22 / 17 / 1
Регистрация: 05.08.2013
Сообщений: 468
Завершенные тесты: 1
07.03.2014, 23:06  [ТС]     Создание игр в текстовом режиме #44
XRuZzz, кроме delete еще есть замечания?)
XRuZzz
Антикодер
577 / 478 / 23
Регистрация: 15.09.2012
Сообщений: 2,429
08.03.2014, 00:59     Создание игр в текстовом режиме #45
Цитата Сообщение от Bretbas Посмотреть сообщение
XRuZzz, кроме delete еще есть замечания?)
к любой строчке можно придраться, тока смысла не вижу. Но если говорить в позитивном ключе, то хотелось бы увидеть в коде паттерны проектирования[это вы можете легко оспорить, если вы их изучили], полиморфизм, наследование, обобщенное программирование[шаблоны], стиль C++11, перегрузку операторов. Возможно перегрузка вам вовсе не нужна, однако я ожидаю более широкого использования возможностей языка, в тех местах где это действительно необходимо.

Не смотря на то, что помогать разработчикам игр не очень хорошее занятие, дам вам ссылку на пример, который помог мне понять один из паттернов МVC[так как паттерны МVC бывают разные]:
MVC в примере на С++ (консольное приложение)
То что я рекомендую этот паттерн, означает только то, что я мало разбирался[экспериментировал] с другими.
По проекту в целом, меня бы порадовали[многие не признают некоторые пункты]:
-более высокий уровень описания требований к проекту
-сценарии вариантов использования
-UML диаграммы[они используются как дополнение к тексту. Немного порадовала диаграмма классов 0x10]
-система контроля версий[я не сторонник смотреть код проекта в форуме]
и т п
Конечно вы просили оценить только код, но иногда полезно выйти за рамки темы.

Давайте откроем любой участок кода boost [или другой библиотеки C++]:
C++
1
2
3
4
5
6
7
8
9
10
11
12
        /** Insert a copy of the given tree with its key just before the given
         * position in this node. This operation invalidates no iterators.
         * @return An iterator to the newly created child.
         */
        iterator insert(iterator where, const value_type &value);
 
        /** Range insert. Equivalent to:
         * @code
         * for(; first != last; ++first) insert(where, *first);
         * @endcode
         */
        template<class It> void insert(iterator where, It first, It last);
Не будем рассматривать код, посмотрим на комментарии в коде. Они имеют особый формат для автоматической генерации документации.
Это формат doxygen.
Этим я хотел сказать то, что даже в ваших комментариях есть что улучшать.

Всё вышеперечисленное не является фундаментальными знаниями[такими как математика], на которые я вам советую опираться в первую очередь[уделять им больше времени].
Bretbas
22 / 17 / 1
Регистрация: 05.08.2013
Сообщений: 468
Завершенные тесты: 1
08.03.2014, 02:51  [ТС]     Создание игр в текстовом режиме #46
Полиморфизм и перегрузку я даже не знаю где здесь использовать,может она вовсе не нужна?
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
08.03.2014, 08:46     Создание игр в текстовом режиме #47
Bretbas, сразу же в глаза бросается: в меню остались статические методы и поля, при этом все действия производятся через объект. Вывод? static не нужен.

Пробегусь по отдельным моментам.

Цитата Сообщение от Bretbas Посмотреть сообщение
Grafic *grafic = new Grafic;
Уже сказали, что нет delete, но у меня сразу же вопрос: а зачем тут new? Создавайте объект в стеке, ничто не мешает. С меню аналогично.

Далее идет огромный switch, у которого есть еще и несколько вложенных. Это сложно для чтения и поддержки. Нужно побить на функции.

Вынесение работы с графикой в отдельный класс - ок.
Цитата Сообщение от Bretbas Посмотреть сообщение
Но меню не будет работать без этого класса, поэтому его нужно таскать всегда с собой.
Как вариант, можно сделать отдельную сущность типа MenuVisualizer (MenuView), которая будет знать о меню и графике. В этом случае как раз меню хранит только данные, а визуализатор является представлением.

Ну и хочется по некоторым пунктам дополнить XRuZzz.
Цитата Сообщение от XRuZzz Посмотреть сообщение
можно до бесконечности стремиться к идеалу в коде, но намного разумнее почитать что нить новое, или придумать что то новое в архитектуре кода самому.
Да, переписывать можно до бесконечности. Разве что я бы тут предложил не архитектуру терзать, а все-таки довести хотя бы одну программу до конца. Ну и потом уже улучшать. Возможно, не ее же, а очередную.

Цитата Сообщение от XRuZzz Посмотреть сообщение
хотелось бы увидеть в коде паттерны проектирования[это вы можете легко оспорить, если вы их изучили], полиморфизм, наследование, обобщенное программирование[шаблоны], стиль C++11, перегрузку операторов. Возможно перегрузка вам вовсе не нужна, однако я ожидаю более широкого использования возможностей языка, в тех местах где это действительно необходимо.
Просто хотел выделить важную фразу, дабы автор не кидался максимизировать количество используемых возможностей языка на строчку кода.

Цитата Сообщение от XRuZzz Посмотреть сообщение
-сценарии вариантов использования
Снова плюсану. От этого зависит что вообще проектируем. Заспойлерю чуть: мне вот кажется, что иерархичное вложенное меню - это сильно круто. И хочется ввести понятие "экран", у которого будет уже одноуровневое меню, некоторые пункты которого будут менять текущий активный экран на другой, у которого снова есть простое одноуровневое меню. Но это только на уровне идеи, не призываю кидаться писать.
Bretbas
22 / 17 / 1
Регистрация: 05.08.2013
Сообщений: 468
Завершенные тесты: 1
09.03.2014, 01:34  [ТС]     Создание игр в текстовом режиме #48
1.Вы сказали лучше сделать класс MenuVisualizer, который будет знать о меню и графики,так?Значит нужно создавать именно объект этого класса в main?И работать с меню через этот объект?
2.Я не пойму что такое сценарии вариантов
использования?Это то,для чего эта система меню нужна?Ну к примеру для создание меню в консольных играх.И это все что нужно описать?
3.А как сделать систему одноуровневого меню?К примеру я хочу по определенному пункту меню объекта menu1, перейти на другой список меню,для этого мне нужно создавать нужный новый объект menu2, и выполнять тоже самое?)Так чтоли?

XRuZzz, ту статью про MVC которую вы мне дали,в первый раз я все понял)Все идеально и грамотно разжжевано,специально для новичков)Есть что то типо этого?)
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
09.03.2014, 06:45     Создание игр в текстовом режиме #49
Цитата Сообщение от Bretbas Посмотреть сообщение
1.Вы сказали лучше сделать класс MenuVisualizer, который будет знать о меню и графики,так?Значит нужно создавать именно объект этого класса в main?И работать с меню через этот объект?
Через него только отрисовка.

Цитата Сообщение от Bretbas Посмотреть сообщение
Ну к примеру для создание меню в консольных играх.И это все что нужно описать?
Нужно подробное описание всех требований. Как пользователь взаимодействует с программой, какие типы пунктов бывают и т д. http://ru.wikipedia.org/wiki/%D0%A1%...BD%D0%B8%D1%8F
Цитата Сообщение от Bretbas Посмотреть сообщение
А как сделать систему одноуровневого меню?
Это я только высказал на уровне идеи, не продумывая полностью. Не факт, что оно нужно.

Вообще мне кажется, что вопросы архитектуры надо постепенно закрывать - иначе скатимся в чтение курса лекций. Надо уже довести до конца хотя бы одну программу. Пусть она будет где-нибудь кривая и косая, но завершенная.
XRuZzz
Антикодер
577 / 478 / 23
Регистрация: 15.09.2012
Сообщений: 2,429
09.03.2014, 10:55     Создание игр в текстовом режиме #50
Цитата Сообщение от Bretbas Посмотреть сообщение
2.Я не пойму что такое сценарии вариантов использования?
На самом деле я говорил про сценарии вариантов использования по книге Alistair Cockburn - WRITING EFFECTIVE USE CASES[есть на русском]
Не прочитав этой книги, невозможно научиться работать с вариантами использования.
Bretbas
22 / 17 / 1
Регистрация: 05.08.2013
Сообщений: 468
Завершенные тесты: 1
13.03.2014, 00:54  [ТС]     Создание игр в текстовом режиме #51
0x10, е-мое,опять не понял про MenuVisualizer...какая отрисовка?То есть метод draw_menu() будет принадлежать классу MenuVisualizer?А все остальные функции,такие как current_menu(),current_cursor() и тд,будут относиться к классу Menu.Так?И нужно создавать два объекта в main,соответственно обоих классов?
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
13.03.2014, 06:01     Создание игр в текстовом режиме #52
Цитата Сообщение от Bretbas Посмотреть сообщение
То есть метод draw_menu() будет принадлежать классу MenuVisualizer?А все остальные функции,такие как current_menu(),current_cursor() и тд,будут относиться к классу Menu.Так?И нужно создавать два объекта в main,соответственно обоих классов?
Да, все так.
Профит - можно будет по необходимости подменять способ отрисовки.
Миниатюры
Создание игр в текстовом режиме  
XRuZzz
Антикодер
577 / 478 / 23
Регистрация: 15.09.2012
Сообщений: 2,429
13.03.2014, 10:34     Создание игр в текстовом режиме #53
Скорее всего вам нужен всего один вариант использования (ВИ), назовём его "Пройти игру". Желательно иметь ещё глоссарий для проекта, но я сделаю первый набросок сценария ВИ (СВИ) пользовательского уровня:

ВИ "Пройти игру"

Основной сценарий:
1. Пользователь посылает запрос для получения доступных действий.
2. Система подтверждает запрос и предоставляет пользователю список доступных действий(меню).
3. Пользователь посылает запрос для начала игры.
4. Система загружает игровой процесс и сообщает о начале игры.
5. Пользователь посылает запросы для выполнения необходимых действий в игре.
6. Система подтверждает выполнение действий в игре и сообщает об успешном завершении игры.

Расширения(если что то пошло не так):
1a. Пользователю нужна справочная информация по игровому процессу.
1a1. Пользователь посылает запрос для получения справочной информации о игровом процессе.
1a2. Система предоставляет справочную информацию о игровом процессе.

1b. Пользователю нужно изменить настройки игрового процесса.
1b1. Пользователь посылает запрос на получение списка доступных настроек игрового процесса.
1b2. Система подтверждает запрос и предоставляет список доступных настроек пользователю.
1b3. Пользователь выбирает уровень сложности, карту игрового поля и посылает запрос на изменение настроек игрового процесса.
1b4. Система подтверждает настройки

3a. Пользователь совершил действия, которые привели к поражению в игре.
3a1. Система сообщает о проигрыше.
___________
Так как всё написано текстом, скорее всего вы поняли, что я хотел этим сказать(это преимущество написания СВИ в текстовом виде).
Этим ВИ мы показываем основные способы достижения цели пользователя - пройти игру. Реализовать этот ВИ можно даже в консоли(так как я не упоминал детали интерфейса).
Изменения в любом предложении этого сценария могут привести к тому, что весь код придётся переписывать заново. Например, ВИ сообщает нам, что у пользователя всего одна жизнь для прохождения всей игры.
Нам необходимо дополнить этот ВИ такими требованиями:
-Количество пользователей системы не должно превышать 1.
-Игра должна запускаться на любых операционных системах, поддерживающих OpenGL.
-Игра должна запускаться консольном и графическом режиме.
-Игра должна иметь возможность расширять количество поддерживаемых языков.
-Настройки игры должны храниться в формате JSON(может кто предложит формат лучше?)
и т д

Очевидно, что этот простой текст сильно изменит ваш код(в лучшую сторону)
Bretbas
22 / 17 / 1
Регистрация: 05.08.2013
Сообщений: 468
Завершенные тесты: 1
14.03.2014, 01:18  [ТС]     Создание игр в текстовом режиме #54
0x10, завтра скину измененный код с добавлением нового класса)

XRuZzz, так,в принципе я понял,что такое варианты использования.Конечно,с ними код весьма быстрее читается и развивается правильно соответственно.Но вот у меня один вопросик назрел...Это случаем не частный случай блок схем?

XRuZzz, 0x10, вам не кажется,что мы одни остались в этой теме?(
XRuZzz
Антикодер
577 / 478 / 23
Регистрация: 15.09.2012
Сообщений: 2,429
14.03.2014, 14:05     Создание игр в текстовом режиме #55
Цитата Сообщение от Bretbas Посмотреть сообщение
Это случаем не частный случай блок схем?
разница в том, что ВИ показывает цель пользователя, сценарий показывает реакцию системы на действия пользователя.
Блок схемы описывают работу функций и алгоритмов(в нотации UML вместо блок схем используются диаграммы активности)
Лично я исключаю из СВИ возврат к предыдущим шагам, а на блок схеме это возможно.
Мы можем представлять ВИ в виде блок-схем и диаграмм активности, но многие рекомендуют текстовую форму, так как она понятна даже не подготовленному человеку.
Bretbas
22 / 17 / 1
Регистрация: 05.08.2013
Сообщений: 468
Завершенные тесты: 1
14.03.2014, 23:53  [ТС]     Создание игр в текстовом режиме #56
Короче разделил я на 2 сущности мой класс меню.В итоге вот что получил:

Файл Menu.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#ifndef MENU_H_
#define MENU_H_
 
#include <iostream>
#include <vector>
#include <string>
#include <conio.h>
#include <windows.h>
 
 
class MenuView;
 
 
/* ## Класс меню - МОДЕЛЬ ## */
class MenuModel
{
private:
    int number_current_menu_;                           // Номер текущего списка меню
    int current_cursor_;                                // Каретка текущего пункта меню
    int x_, y_;                                         // Координаты прорисовки списка на экране
    static std :: vector<std :: wstring> list_menu_;    // Список меню
 
public:
    MenuModel(int,int);                                 // Конструктор
    ~MenuModel();                                       // Деструктор
 
    void add_list_menu(std :: wstring);                 // Добавить пункт в список меню
    int current_menu() const;                           // Получение номера текущего списка меню
    int current_cursor() const;                         // Получение каретки текущего пункта меню
    void next_menu();                                   // Следующий список меню
    void back_menu();                                   // Предыдущий список меню
 
    friend MenuView;
};
 
 
 
/* ## Класс меню - ПРЕДСТАВЛЕНИЕ ## */
class MenuView
{
private:
    MenuModel *menu_model_;                         // Модель меню
    static HANDLE h_console_;                       // Дескриптор окна консоли
 
    void set_cursor_pos_(int x,int y);              // Установка позиции курсора
    void clear_screen_();                           // Стирание экрана
 
public:
    MenuView(MenuModel*);                           // Конструктор                      
    ~MenuView();                                    // Деструктор
 
    void draw_menu();                               // Прорисовка списка меню
};
 
#endif  MENU_H_
Файл Menu.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include "Menu.h"
 
 
std :: vector<std :: wstring> MenuModel :: list_menu_;
 
 
/* ## Конструктор ## */
MenuModel :: MenuModel(int x,int y) : x_(x),y_(y)
{
    number_current_menu_ = 1;
}
 
 
/* ## Деструктор ## */
MenuModel :: ~MenuModel()
{ }
 
 
/* ## Следующий список меню ## */
void MenuModel :: next_menu()
{
    if(number_current_menu_ != list_menu_.size())
    { number_current_menu_++; }
}
 
 
/* ## Предыдущий список меню ## */
void MenuModel :: back_menu()
{
    if(number_current_menu_ != 0)
    { number_current_menu_--; }
}
 
 
/* ## Получение текущего списка меню ## */
int MenuModel :: current_menu() const
{
    return number_current_menu_;
}
 
 
/* ## Получение каретки текущего пункта меню ## */
int MenuModel :: current_cursor() const
{
    return current_cursor_;
}
 
 
/* ## Добавить пункт в список меню ## */
void MenuModel :: add_list_menu(std :: wstring item)
{
    list_menu_.push_back(item);
}
 
 
HANDLE MenuView :: h_console_ = NULL;
 
 
/* ## Конструктор ## */
MenuView :: MenuView(MenuModel *menu_model)
{
    menu_model_ = menu_model;
 
    COORD console_size = {80,25};
 
    h_console_ = CreateFile( L"CONOUT$",
                            GENERIC_WRITE |
                            GENERIC_READ,
                            FILE_SHARE_READ |
                            FILE_SHARE_WRITE,
                            0L,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL,
                            0L );
 
    SetConsoleScreenBufferSize(h_console_,console_size);
 
    SetConsoleTextAttribute(h_console_,(WORD)((0<<4) | 15));
 
    clear_screen_();
}
 
 
/* ## Деструктор ## */
MenuView :: ~MenuView()
{ }
 
 
/* ## Стирание экрана ## */
void MenuView :: clear_screen_()
{
    set_cursor_pos_(1,25);
 
    for(int j = 0;j < 25;j++)
    { std :: cout << "\n"; }
 
    set_cursor_pos_(1,1);
}
 
 
/* ## Установка позиции курсора ## */
void MenuView :: set_cursor_pos_(int x,int y)
{
    COORD cursor_pos;
    cursor_pos.X = x - 1;
    cursor_pos.Y = y - 1;
 
    SetConsoleCursorPosition(h_console_,cursor_pos);
}
 
 
/* ## Прорисовка списка меню ## */
void MenuView :: draw_menu()
{
    if (menu_model_ -> list_menu_.empty())
    {
        clear_screen_();
        std :: cout << "Check your list menu!It is empty!";
        _getch();
        exit(0);
    }
 
    SetConsoleTextAttribute(h_console_,(WORD)((15<<4) | 0));
    clear_screen_();
 
    for(unsigned int i = 0; i < menu_model_ -> list_menu_.size(); i++) 
    {
        set_cursor_pos_(menu_model_ -> x_ + 4,menu_model_ -> y_ + i);
        std :: wcout << menu_model_ -> list_menu_[i] << std :: endl;
    }
 
    set_cursor_pos_(menu_model_ -> x_,menu_model_ -> y_);
    menu_model_ -> current_cursor_ = 1;
    char c;
 
    do
    {
        for(unsigned int i = 0; i < menu_model_ -> list_menu_.size(); i++)
        {
            if(i == menu_model_ -> current_cursor_ - 1)
            { SetConsoleTextAttribute(h_console_,(WORD)((14<<4) | 0)); }
            else
            { SetConsoleTextAttribute(h_console_,(WORD)((9<<4) | 0)); }
 
            set_cursor_pos_(menu_model_ -> x_,menu_model_ -> y_ + i);
            std :: cout << "->";
        }
 
        c = _getch();
 
        switch(c)
        {
        case 72: if (menu_model_ -> current_cursor_ != 1)
                 { menu_model_ -> current_cursor_--; }
        break;
        case 80: if (menu_model_ -> current_cursor_ != menu_model_ -> list_menu_.size())
                 { menu_model_ -> current_cursor_++; } 
        break;
        }
    }
    while(c != 13);
 
    menu_model_ -> list_menu_.clear();
}
Файл Grafic.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef GRAFIC_H_
#define GRAFIC_H_
 
#include <iostream>
#include <windows.h>
 
 
/* ## Список перечисления ## */
enum color
{
    cBLACK=0, cDARK_BLUE=1, cDARK_GREEN=2, DARK_CYAN=3, cDARK_RED=4, cDARK_MAGENTA=5, cBROWN=6, cLIGHT_GRAY=7,
    cDARK_GRAY=8, cBLUE=9, cGREEN=10, cCYAN=11, cRED=12, cMAGENTA=13, cYELLOW=14, cWHITE=15
};
 
 
/* ## Класс графики ## */
class Grafic
{
private:
    static HANDLE h_console_;                       // Дескриптор окна консоли
 
public:
    Grafic();                                       // Конструктор
    ~Grafic();                                      // Деструктор
 
    void set_color(color fg,color bg = cBLACK);     // Установка цвета
    void set_cursor_pos(int x,int y);               // Установка позиции курсора
    void clear_screen();                            // Стирание экрана
};
 
#endif GRAFIC_H_
Файл Grafic.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include "Grafic.h"
 
 
HANDLE Grafic :: h_console_ = NULL;
 
 
Grafic :: Grafic()
{
    COORD console_size = {80,25};
 
    h_console_ = CreateFile( L"CONOUT$",
                            GENERIC_WRITE |
                            GENERIC_READ,
                            FILE_SHARE_READ |
                            FILE_SHARE_WRITE,
                            0L,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL,
                            0L );
 
    SetConsoleScreenBufferSize(h_console_,console_size);
 
    SetConsoleTextAttribute(h_console_,(WORD)((0<<4) | 15));
 
    clear_screen();
}
 
 
Grafic :: ~Grafic()
{ }
 
 
void Grafic :: set_color(color foreground,color background)
{
    SetConsoleTextAttribute(h_console_,(WORD)((background<<4) | foreground));
}
 
 
void Grafic :: set_cursor_pos(int x,int y)
{
    COORD cursor_pos;
    cursor_pos.X = x - 1;
    cursor_pos.Y = y - 1;
 
    SetConsoleCursorPosition(h_console_,cursor_pos);
}
 
 
void Grafic :: clear_screen()
{
    set_cursor_pos(1,25);
 
    for(int j = 0;j < 25;j++)
    { std :: cout << "\n"; }
 
    set_cursor_pos(1,1);
}
Ну и файл main.h:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <iostream>
#include <conio.h>
 
#include "Menu.h"
#include "Grafic.h"
 
using namespace std;
 
int main()
{
    Grafic grafic;
    MenuModel menu_model(38,12);
    MenuView menu_view(&menu_model);
    
    for(;;)
    {
        switch(menu_model.current_menu())
        {
        case 1: // Первое меню - START  OPTION  EXIT
            {
                menu_model.add_list_menu(L"START");
                menu_model.add_list_menu(L"OPTION");
                menu_model.add_list_menu(L"EXIT");
 
                menu_view.draw_menu();
 
                switch(menu_model.current_cursor())
                {
                case 1:
                    {
                        grafic.clear_screen();
                        cout << "hello world";
                        _getch();
                    }
                break;
 
                case 2:
                    {
                        menu_model.next_menu();
                    }
                break;
 
                case 3:
                    {
                        exit(0);
                    }
                break;
                }
            }
        break;
 
        case 2: // Второе меню - DINAMIC CREATE MENU   MESSAGE   BACK
            {
                menu_model.add_list_menu(L"DINAMIC CREATE MENU");
                menu_model.add_list_menu(L"MESSAGE");
                menu_model.add_list_menu(L"BACK");
 
                menu_view.draw_menu();
 
                switch(menu_model.current_cursor())
                {
                case 1:
                    {
                        grafic.clear_screen();
                        wstring item;
                        vector<wstring> dimanic_menu;
 
                        for(int i = 0; i < 6; i++)
                        {
                            cout << "Input item of menu";
                            wcin >> item;
                            menu_model.add_list_menu(item);
                        }
 
                        menu_view.draw_menu();
 
                        switch(menu_model.current_cursor())
                        {
                        case 1: menu_model.back_menu(); break;
                        case 2: menu_model.back_menu(); break;
                        case 3: menu_model.back_menu(); break;
                        }
                    }
                break;
 
                case 2:
                    {
                        grafic.clear_screen();
                        cout << "I Love CyberForum";
                        _getch();
                        menu_model.back_menu();
                    }
                break;
 
                case 3:
                    {
                        menu_model.back_menu();
                    }
                break;
                }
            }
        break;
        }
    }
 
    return 0;
}
Вроде вот так)
XRuZzz
Антикодер
577 / 478 / 23
Регистрация: 15.09.2012
Сообщений: 2,429
15.03.2014, 00:36     Создание игр в текстовом режиме #57
теперь смотрим расширение сценария:
Цитата Сообщение от XRuZzz Посмотреть сообщение
1a. Пользователю нужна справочная информация по игровому процессу.
отсюда вопрос - а как пользователь поймёт, что нужно делать в игре?

Добавлено через 5 минут
Меня всегда удивляет, когда люди описывают поведение живого существа в программе и не концентрируют внимание на сущности этого существа.
Я бы выделил следующие сущности:
Змейка
Яблоки

Иными словами, неужели вам не интересно создать классы с уникальным поведением типа Snakes, Apples? В которых бы отсутствовали операторы вывода графики, а присутствовала бы только сама логика сущностей.
Bretbas
22 / 17 / 1
Регистрация: 05.08.2013
Сообщений: 468
Завершенные тесты: 1
15.03.2014, 00:40  [ТС]     Создание игр в текстовом режиме #58
XRuZzz, я не понял вас...я еще не выкладывал ни одну игру...выложил только класс меню...и сделал пример использования,не по теме игры вообще
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
15.03.2014, 07:16     Создание игр в текстовом режиме #59
На самом деле, на этом предлагаю закругляться.
Вылизывать дальше пока смысла не вижу, иначе тут можно застрять надолго. Лучше просто двигаться дальше и довести хотя бы одну идею до конца.
Из замечаний пока оставлю одно: слишком сложно. Использование класса меню занимает много места, присутствуют вложенные свитчи. Чтобы понять структуру меню и переходов приходится читать весь код. Хочется иметь отдельно более-менее декларативное описание структуры и отдельно логику обработки действий пользователя. Т.е. разделить данные и поведение.

Пока кидаться делать это не надо, я уже говорил почему. Просто на будущее.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.03.2014, 09:11     Создание игр в текстовом режиме
Еще ссылки по теме:

C++ Нарисовать мышью прямоугольник в текстовом режиме экрана
C++ Работа с экраном в текстовом режиме (вывод всех цветов фона, разделяя цвета паузой)
Создание конструкторов игр C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
XRuZzz
Антикодер
577 / 478 / 23
Регистрация: 15.09.2012
Сообщений: 2,429
15.03.2014, 09:11     Создание игр в текстовом режиме #60
Цитата Сообщение от Bretbas Посмотреть сообщение
XRuZzz, я не понял вас...я еще не выкладывал ни одну игру...выложил только класс меню...и сделал пример использования,не по теме игры вообще
так код вряд ли может существовать без проекта. именно требования к реализации определяют содержание кода.
Потом всё меню будете переделывать для добавления справки? или во время игры будете подсвечивать клавиши, которые можно нажать в данный момент? Или будете добавлять обучающий уровень?
Yandex
Объявления
15.03.2014, 09:11     Создание игр в текстовом режиме
Ответ Создать тему
Опции темы

Текущее время: 21:03. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru