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

Очистка экрана - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.74
JlightenDev_C++
 Аватар для JlightenDev_C++
61 / 61 / 7
Регистрация: 12.08.2012
Сообщений: 150
12.08.2012, 14:44     Очистка экрана #1
Пытаюсь сделать игрушку, но при очищении экрана через cls, чтобы отпечатать уже измененный массив экар постоянно мигает... Я пробовал сделать через отступы строк, но получается тоже самое. Есть ли способ очистить экран, чтобы не мигало?
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#include <iostream>
#include <conio.h>
using namespace std;
   
   void menuPrint(char menuP[][1], int y, int x);
   
   void printUnit(char unitT[][11], int n, int m, int lvl);
 
   void clearUnit(char unitC[][11], int n, int m);
//===
int main()
{
setlocale( LC_ALL,"" );
    char g = 1; 
    int move = 0, lvl = 1, k = 0, l = 0;
    const int w = 15, h = 11;
    char menu[4][1];
        for (int x = 0; x < 4; x++)
    {
        for (int y = 0; y < 1; y++)
        {
            menu[x][y] = ' ';
            }
        }
    char unit[w][h];
    for (int y = 0; y < (w + 1); y++)
    {
        for (int x = 0; x < h; x++)
        {
            unit[y][x] = '*';
            if(y > 0 && y < w && x > 0 && x < h)
            {
                 for(int Space = 1; Space < (h - 1); Space++)
                 {
                         unit[y][Space] = ' ';
                         }
                 }
            }
        }
        
                menu[k][l] = g;
        menuPrint(menu, 4, 1);
        while(true){
                getch();
                move = getch();
        switch (move)
        {
        case 72: 
              menu[k][l] = ' ';
              k = k - 1;
                 if(menu[k][l] != ' ')
                 {
              menu[k][l] = '*';
              k = k+1;
                 }
                 system("CLS");
                 menu[k][l] = g;
                 menuPrint(menu, 4, 1);
                 break;
        case 80:
              menu[k][l]=' ';
              k = k + 1;
                 if(menu[k][l] != ' ')
                 {
              menu[k][l] = '*';
              k = k - 1;
                 }
                 system("CLS");
                 menu[k][l] = g;
                 menuPrint(menu, 4, 1);
                 break;
              }
              if (menu[0][0] == g && move == 77){lvl = 1; break;}
              if (menu[1][0] == g && move == 77){lvl = 1; break;}
              if (menu[2][0] == g && move == 77){lvl = 1; break;}
              if (menu[3][0] == g && move == 77){exit(0);}  
              }
               //=== Старт
        start:
              clearUnit(unit, w, h);
        int s = (h / 2);
        int Y = (w - 1), X = s;
                unit[Y][s] = '@';
        while(move != 27){
        system("CLS");
        //lvl first
        if(lvl == 1)
        {
                unit[1][1] = g; unit[1][2] = g; unit[1][3] = g; unit[1][7] = g; unit[1][8] = g; unit[1][9] = g;
                unit[2][3] = g; unit[2][7] = g;
                unit[3][3] = g; unit[3][7] = g;
                unit[5][3] = g; unit[5][7] = g;
                unit[6][4] = g; unit[6][6] = g;
                unit[8][1] = g; unit[8][2] = g; unit[8][3] = g; unit[8][4] = g; unit[8][6] = g; unit[8][7] = g; unit[8][8] = g; unit[8][9] = g;
                unit[10][4] = g; unit[10][6] = g;
                unit[11][3] = g; unit[11][7] = g;
                unit[13][2] = g; unit[13][3] = g; unit[13][4] = g; unit[13][5] = g; unit[13][6] = g; unit[13][7] = g; unit[13][8] = g;
                }
        else if(lvl == 2)
        {
        //lvl second
                unit[1][2] = g; unit[1][4] = g; unit[1][6] = g; unit[1][8] = g;
                unit[2][1] = g; unit[2][4] = g; unit[2][9] = g;
                unit[3][3] = g; unit[3][6] = g;
                unit[4][2] = g; unit[4][5] = g; unit[4][8] = g;
                unit[5][2] = g; unit[5][4] = g; unit[5][8] = g;
                unit[6][2] = g; unit[6][6] = g; unit[6][8] = g;
                unit[7][4] = g;
                unit[8][1] = g; unit[8][2] = g; unit[8][3] = g; unit[8][6] = g; unit[8][7] = g; unit[8][8] = g; unit[8][9] = g;
                unit[9][6] = g;
                unit[10][2] = g; unit[10][4] = g; unit[10][8] = g;
                unit[11][2] = g; unit[11][6] = g; unit[11][8] = g;
                unit[12][2] = g; unit[12][4] = g; unit[12][8] = g;
                unit[13][2] = g; unit[13][6] = g; unit[13][8] = g;            
             }
                printUnit(unit, w, h, lvl); 
 
        getch();
        move = getch();
        switch (move)
        {
        case 75:
              cout << "left";
              unit[Y][X] = ' ';
              X = X-1;
         system("CLS");
                 if(unit[Y][X] != ' ')
                 {
              unit[Y][X] = '*';
              X = X+1;
                 }
                 system("CLS");
                 unit[Y][X] = '@';
                 printUnit(unit, w, h, lvl);
                 break;
        case 72: 
              cout << "up";
              unit[Y][X] = ' ';
              Y = Y - 1;
                 if(unit[Y][X] != ' ')
                 {
              unit[Y][X] = '*';
              Y = Y+1;
                 }
                 system("CLS");
                 unit[Y][X] = '@';
                 printUnit(unit, w, h, lvl);
                 break;
        case 80:
              cout << "down";
              unit[Y][X]=' ';
              Y = Y + 1;
                 if(unit[Y][X] != ' ')
                 {
              unit[Y][X] = '*';
              Y = Y - 1;
                 }
                 system("CLS");
                 unit[Y][X] = '@';
                 printUnit(unit, w, h, lvl);
                 break;
         case 77:
              cout << "right";
              unit[Y][X] = ' ';
              X = X + 1;
                 if(unit[Y][X] != ' ')
                 {
              unit[Y][X] = '*';
              X = X - 1;
                 }
                 system("CLS");
                 unit[Y][X] = '@';
                 printUnit(unit, w, h, lvl);
                 break;
              }
              //цикл проверки конца уровня
    for (int i = 1; i < 2; i++)
    {
        for (int j = 1; j < h - 1; j++)
        {
                         if(unit[i][j] == '@'){
                                       unit[i][j] = ' ';
                                       lvl = lvl + 1;
                                       system("CLS");       
                              goto start;
                                       }
            }
        }
         //конец проверки уровня
         }
         //================ конец тела
        getch();
        return 0;
    }
// Функции
    void printUnit(char unitT[][11], int n, int m, int lvl)
{
    for (int i = 0; i < (n + 1); i++)
    {
        for (int j = 0; j < m; j++)
        {
                 cout << unitT[i][j];
                 if(i == 0 && j == 10){
                      cout << "  Уровень: " << lvl;
                      }
            }
            cout << endl;
        }
}
//===
void clearUnit(char unitC[][11], int n, int m)
{
    for (int i = 1; i < n; i++)
    {
        for (int j = 1; j < (m - 1); j++)
        {
                         unitC[i][j] = ' ';
            }
        }
}
//===
 void menuPrint(char menuP[][1], int y, int x)
   {
     for(int i = 0; i < y; i++)
     {
             for(int j = 0; j < x; j++)
             {
        cout << menuP[i][j];
        if(i == 0 && j == 0){ cout << " Начать игру (сделано только 2 уровня)";}
        if(i == 1 && j == 0){ cout << " Выбор уровня (пока не сделано)";}
        if(i == 2 && j == 0){ cout << " Как играть (пока не сделано)";}
        if(i == 3 && j == 0){ cout << " Выход" << endl << endl << "Для выбора используйте клавишу вправо.";}
              }
              cout << endl;
      }
        }
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.08.2012, 14:44     Очистка экрана
Посмотрите здесь:

C++ Очистка экрана
C++ очистка экрана в C
C++ очистка экрана на DevC++
Очистка экрана в консоли C++
очистка экрана недоконца C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DaskOFF
 Аватар для DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 521
Записей в блоге: 1
12.08.2012, 14:47     Очистка экрана #2
у вас очищается экран и отрисовывается все по новой поэтому и мерцает
JlightenDev_C++
 Аватар для JlightenDev_C++
61 / 61 / 7
Регистрация: 12.08.2012
Сообщений: 150
12.08.2012, 14:50  [ТС]     Очистка экрана #3
Это понятно, но можно это как нибудь исправить?
returnless
25 / 25 / 3
Регистрация: 05.08.2012
Сообщений: 83
12.08.2012, 14:59     Очистка экрана #4
может не очищать все? а перерисовывать то что нужно, нее?
двойная буферизация слышал есь может если заюзать поможет.
Игорь с++
 Аватар для Игорь с++
429 / 452 / 15
Регистрация: 26.01.2011
Сообщений: 2,029
12.08.2012, 15:21     Очистка экрана #5
Цитата Сообщение от returnless Посмотреть сообщение
двойная буферизация слышал есь может если заюзать поможет.
поможет то конечно оно поможет , но это уже WinApi а ТС делает консольное приложение , нет конечно можно использовать и консольное окно и выводить на него рисунок , но это уже извращенство , и как я понял не совсем то , что нужно ТС ! Как самый примитивный вариант поставить Sleep хотя если маленький , то всё равно будет моргать , но если особая скорость не нужна в игре , то можно поставить вот так - Sleep ( 1000 ) ; может и будет моргать но либо мало либо вообще не будет ИМХО конечно !

Добавлено через 13 минут
как вариант конечно же в консольном окне можно вообе рисовать картинками .bmp Изображение в консольном приложении.
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
12.08.2012, 15:32     Очистка экрана #6
ну врятли есть смысл мутить не аски графику в консольном окошке. уж лучше использовать для этого что-нибудь более подходящее.
Если же консольное приложение и аски графика - то могу предложить такой вариант буферизации. хз прокатит или нет. просто предложение:
Допустим мы знаем параметры консольного окна. Ширину и высоту в символах. Допустим так же, что у нас есть возможность ставить курсор в позицию (0, 0).
Тогда все, что выводится на экран можно выводить в строку которая бы при напечатании выглядела как текст с шириной и высотой консольного окна. И вот каждое обновление экрана делать не очисткой экрана, а переводом курсора в начало окна и печатанием этой строки. А она уже сама затрет собой старое содержимое, на экране будет новое. Но вот будет ли это работать без морганий или нет - хз.
Игорь с++
 Аватар для Игорь с++
429 / 452 / 15
Регистрация: 26.01.2011
Сообщений: 2,029
12.08.2012, 15:50     Очистка экрана #7
Цитата Сообщение от DU Посмотреть сообщение
Но вот будет ли это работать без морганий или нет - хз
работать будет без моргание , но есть одно НО !!! Если символ который стоит уже больше чем который будет есть вероятность он не сможет его затереть до конца т.е. часть может остаться это во первых , а во вторых даже если всё осуществить то будет не много геморно , но хз , ТС пускай сам выбирает , что ему удобней .

Добавлено через 5 минут
кстати ещё как вариант,но тоже опять winapi -
1)находим hwnd нашего консольного онка
2)делаем координаты где надо обнавить при помощи структуры RECT rect ;
3)обнавляем данную область , а не всё окно и вуаля моргания нет
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
12.08.2012, 16:09     Очистка экрана #8
не. символы перезатрираться должны. скажем если раньше была звездочка, а я поверх нее рисую пробел, то пробел затрет звездочку, потому что в этом месте должен рисоваться целиком новый символ.
На счет винапи и gdi - это лучше сразу не консольное приложение делать, а по нормальному. даже эмулировать консольный вид будет проще, чем заставить настоящее консольное окошко работать как надо.

кстати попробовал свою идейку. мерцает не тас сильно, но какие-то черные точки все таки проскакивают. Вот код прохода пробела по полю из символов '@'



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
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <string>
 
HANDLE GetConsoleHandle()
{
  return GetStdHandle(STD_OUTPUT_HANDLE);
}
 
void GoToXY(unsigned x, unsigned y)
{
  COORD coord = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
  SetConsoleCursorPosition(GetConsoleHandle(), coord);
}
 
class ScreenBuffer
{
  unsigned m_width;
  unsigned m_height;
  std::string m_buffer;
 
public:
  ScreenBuffer(unsigned width, unsigned height)
    : m_width(width)
    , m_height(height)
  {
    const unsigned size = (m_width + 1) * m_height;
    m_buffer.resize(size);
    Clear();
  }
 
  unsigned GetWidth()
  {
    return m_width;
  }
 
  unsigned GetHeight()
  {
    return m_height;
  }
 
  void Fill(char ch)
  {
    for (size_t i = 0, end = m_buffer.size(); i != end; ++i)
      m_buffer[i] = ch;
 
    for (size_t i = 1, end = m_height; i <= end; ++i)
    {
      m_buffer[(i * (m_width + 1)) - 1] = '\n';
    }
  }
 
  void Clear()
  {
    Fill(' ');
  }
 
  void Draw(unsigned x, unsigned y, char ch)
  {
    m_buffer[y * (m_width + 1) + x] = ch;
  }
 
  void DrawToScreen() const
  {
    GoToXY(0, 0);
    std::cout << m_buffer;
  }
};
 
int main()
{
  ScreenBuffer screenBuffer(40, 20);
 
  for (unsigned y = 0; y < screenBuffer.GetHeight(); ++y)
  {
    for (unsigned x = 0; x < screenBuffer.GetWidth(); ++x)
    {
      screenBuffer.Fill('@');
      screenBuffer.Draw(x, y, ' ');
      screenBuffer.DrawToScreen();
      Sleep(10);
    }
  }
 
  return 0;
}
JlightenDev_C++
 Аватар для JlightenDev_C++
61 / 61 / 7
Регистрация: 12.08.2012
Сообщений: 150
12.08.2012, 16:26  [ТС]     Очистка экрана #9
Как перевести курсор в самое начало?
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
12.08.2012, 16:29     Очистка экрана #10
смотри в код. если винда, то проканает вызов GoToXY(0, 0) из приведенного кода.
JlightenDev_C++
 Аватар для JlightenDev_C++
61 / 61 / 7
Регистрация: 12.08.2012
Сообщений: 150
12.08.2012, 17:38  [ТС]     Очистка экрана #11
DU, благодарю, все получилось
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.08.2012, 23:16     Очистка экрана
Еще ссылки по теме:

C++ Очистка экрана в консоли
C++ Очистка экрана
Частичная очистка экрана C++

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

Или воспользуйтесь поиском по форуму:
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
12.08.2012, 23:16     Очистка экрана #12
вот если кому интересно пример с динамикой из другой похожей темы:
Закон отражения в ограниченой зоне на консольном приложении
Yandex
Объявления
12.08.2012, 23:16     Очистка экрана
Ответ Создать тему
Опции темы

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