sunmeat / snake.cpp
Clone via HTTPS Clone with Git or checkout with SVN using the repository’s web address.
Learn more about clone URLs
snake game cpp console application code example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| # include |
| # include |
| # include |
| # include |
| using namespace std ; |
| int main () |
| srand ( time ( 0 )); // запуск генератора случайных чисел |
| rand (); // холостой ход генератора случаный чисел |
| system ( » mode con cols=51 lines=31 » ); // установка размеров окна консоли |
| MoveWindow ( GetConsoleWindow (), 50 , 50 , 2000 , 2000 , true ); // установка стартовой позиции окна консоли (50 и 50 — это пиксели |
| // относительно верхнего левого угла монитора |
| const int width = 50 , height = 30 ; // размеры поля, по которому бегает змейка |
| const int max_length = 50 ; // установка максимальной длины «змейки» |
| int array_X[max_length]; // массив,хранящий абсциссы звеньев «змейки» |
| int array_Y[max_length]; // массив, хранящий ординаты звеньев «змейки» |
| int length = 1 ; // переменная длины «змейки» |
| array_X[ 0 ] = width / 2 ; // установка стартовой абсциссы «змейки» |
| array_Y[ 0 ] = height / 2 ; // установка стартовой ординаты «змейки» |
| int dx = 1 , dy = 0 ; // создание смещений по осям для движения «змейки» |
| int X_apple; // абсцисса «яблока» |
| int Y_apple; // ордината «яблока» |
| do // цикл ставит координаты яблока случанйм образом — но чтобы они не совпадали со «змейкой» |
| X_apple = rand () % (width — 2 ) + 1 ; |
| Y_apple = rand () % (height — 2 ) + 1 ; |
| > while (X_apple != array_X[length — 1 ] && Y_apple != array_Y[length — 1 ]); |
| int sleep_time = 100 ; // переменная частоты кадров |
| char snake = ‘ * ‘ ; // символ для отображения тела «змейки» |
| char apple = ‘ o ‘ ; // символ для отображения «яблока» |
| char head = 1 ; // символ для отображения головы «змейки» |
| COORD c; // объект для хранения координат |
| HANDLE h = GetStdHandle (STD_OUTPUT_HANDLE); // создание хендла потока вывода |
| CONSOLE_CURSOR_INFO cci = < sizeof (cci), false >; // создание параметров на отображение курсора |
| SetConsoleCursorInfo (h, &cci); // связывание параметров и хендла |
| SetConsoleTextAttribute (h, 4 ); // установка цвета, которым рисуется рамка поля |
| for ( int y = 0 ; y < height; y++) // стандартный двойной цикл на отрисовку рамки |
| for ( int x = 0 ; x < width; x++) |
| char s; |
| if (x == 0 && y == 0 ) // в верхнем левом углу поля — символ соответствующего угла |
| s = 218 ; |
| else if (x == 0 && y == height — 1 ) // нижний левый угол |
| s = 192 ; |
| else if (y == 0 && x == width — 1 ) // верхний правый угол |
| s = 191 ; |
| else if (y == height — 1 && x == width — 1 ) // нижний правый угол |
| s = 217 ; |
| else if (y == 0 || y == height — 1 ) // верхняя и нижняя граница поля |
| s = 196 ; |
| else if (x == 0 || x == width — 1 ) // левая и правая граница поля |
| s = 179 ; |
| else s = ‘ ‘ ; // во всех остальных случаях должен быть просто пробел (означает пустую область поля) |
| putchar (s); // выводим символ |
| > |
| cout |
| > |
| c. X = X_apple; // связываем объект координат с позициями «яблока» |
| c. Y = Y_apple; |
| SetConsoleCursorPosition (h, c); // отправляем курсор на позицию «яблока» |
| SetConsoleTextAttribute (h, 12 ); // устанавливаем красный цвет для отрисовки «яблока» |
| putchar (apple); // отображаем символ «яблока» |
| c. X = array_X[ 0 ]; // связываем объект координат со стартовой позицией «змейки» |
| c. Y = array_Y[ 0 ]; |
| SetConsoleCursorPosition (h, c); // отправляем курсор на позицию головы «змейки» |
| SetConsoleTextAttribute (h, 10 ); // устанавливаем зеленый цвет для отрисовки «змейки» |
| putchar (head); // отображаем символ головы «змейки» |
| bool flag = true ; // переменная для управления ходом цикла |
| do // собственно цикл игры |
| Sleep (sleep_time); // задержка потока программы на заданный ранее интервал |
| if ( _kbhit ()) // проверяем, была ли нажата какая-либо клавиша и запускаем её обработку в случае ИСТИНЫ |
| int k = _getch (); // считываем код клавиши из буфера |
| if (k == 0 || k == 224 ) // если первый код — вспомогательный, считываем второй код |
| k = _getch (); |
| switch (k) // пропускаем код нажатой клавиши внутрь оператора выбора |
| case 80 : // если была нажата клавиша вниз |
| dy = 1 ; // то приращение по оси ординат будет положительным |
| dx = 0 ; // по оси абсцисс приращение нулевое |
| break ; |
| case 72 : // если вверх |
| dy = — 1 ; // аналогично согласно геометрической логике |
| dx = 0 ; |
| break ; |
| case 75 : // если влево |
| dy = 0 ; |
| dx = — 1 ; |
| break ; |
| case 77 : // если вправо |
| dy = 0 ; |
| dx = 1 ; |
| break ; |
| case 27 : // если была нажата клавиша ESC |
| flag = false ; // устанавливаем флажок на ЛОЖЬ, чтоб закончить показ движения |
| break ; |
| > |
| > |
| int X = array_X[length — 1 ] + dx; // определяем значение абсциссы головы «змейки» после смещения |
| int Y = array_Y[length — 1 ] + dy; // то же самое для ординаты |
| if (X == 0 || X == width — 1 || Y == 0 || Y == height — 1 ) // проверка на достижение границ поля |
| flag = false ; // пока что — просто установка управляющей переменной цикла |
| > |
| else if (X == X_apple && Y == Y_apple) // проверка на достижение «яблока» |
| c. X = array_X[length — 1 ]; // установка в объект координат позиции головы «змейки» |
| c. Y = array_Y[length — 1 ]; |
| SetConsoleCursorPosition (h, c); // установка курсора в эту позицию |
| putchar (snake); // отображение символа тела «змейки» |
| length++; // увеличение длины «змейки» (яблоко проглочено) |
| c. X = array_X[length — 1 ] = X; // установка в массивы позиции нового звена «змейки» |
| c. Y = array_Y[length — 1 ] = Y; |
| SetConsoleCursorPosition (h, c); // установка туда курсора |
| putchar (head); // и отображение там символа головы «змейки» |
| if (length == max_length) // проверка, достигла ли длина «змейки» своего максимального значения |
| break ; // пока что — просто прерываем цикл |
| > |
| int i; // переменная для подсчета количества звеньев «змейки», не совпадающих с позицией «яблока» |
| do |
| X_apple = rand () % (width — 2 ) + 1 ; // установка новых координат «яблока» |
| Y_apple = rand () % (height — 2 ) + 1 ; |
| i = 0 ; // обнуление числа несовпадающих координат |
| for (; i < length; i++) // запуск цикла на сверку совпадений |
| if (X_apple == array_X[i] && Y_apple == array_Y[i]) // если совпадение найдено |
| break ; // то прерываем цикл for |
| > while (i < length); // поиск новых координат продолжается, пока число несовпадающих координат меньше длины "змейки" |
| c. X = X_apple; // установка в объект координат новой корректной позиции «яблока» |
| c. Y = Y_apple; |
| SetConsoleCursorPosition (h, c); // отправка туда курсора |
| SetConsoleTextAttribute (h, 12 ); // установка цвета в красный |
| putchar (apple); // отображение символа «яблока» |
| SetConsoleTextAttribute (h, 10 ); // обратная установка цвета в зеленый — для дальнейшего отображения «змейки» |
| > |
| else // случай, когда голова «змейки» оказалась на новой пустой позиции |
| int i = 1 ; // переменная на количество звеньев, не совпадающих с новой позицией — кроме хвоста «змейки» |
| for (; i < length; i++) |
| if (X == array_X[i] && Y == array_Y[i]) // если совпадение найдено в цикле — прерываемся |
| break ; |
| if (i < length) // если число несовпадающих звеньев меньше длины "змейки" - то прерываем основной цикл игры |
| break ; |
| > |
| else // а иначе запускаем обработку сдвига «змейки» |
| c. X = array_X[ 0 ]; // устанавливаем в объект координат позицию хвоста «змейки» |
| c. Y = array_Y[ 0 ]; |
| SetConsoleCursorPosition (h, c); // двигаем туда курсор |
| putchar ( ‘ ‘ ); // и отображаем пробел (затирка хвоста) |
| if (length > 1 ) // если длина змейки больше |
| c. X = array_X[length — 1 ]; // устанавливаем в объект координат предыдущую позицию головы «змейки» |
| c. Y = array_Y[length — 1 ]; |
| SetConsoleCursorPosition (h, c); // двигаем туда курсор |
| putchar (snake); // выводим символ тела «змейки» |
| > |
| for ( int i = 0 ; i < length - 1 ; i++) // запускаем цикл свдига координат звеньев "змейки" |
| array_X[i] = array_X[i + 1 ]; // обрабатываем все звенья — кроме последнего |
| array_Y[i] = array_Y[i + 1 ]; |
| > |
| c. X = array_X[length — 1 ] = X; // устанавливаем новую позицию головы «змейки» |
| c. Y = array_Y[length — 1 ] = Y; |
| SetConsoleCursorPosition (h, c); // двигаем туда курсора |
| putchar (head); // отображаем символ головы «змейки» |
| > |
| > |
| > while (flag); // выходим из цикла, если сброшена управляющая переменная |
| system ( » cls » ); // очищаем экран |
| cout |
| system ( » pause » ); |
| > |
Как написать змейку на c
Интересно, как совместить хочу опробовать себя и готовый код? Та нет ни какого опробования тогда, есть копипаста без осмысливания кода. Аналогично — хочу опробовать себя, помогите. Помогать то не в чем, не видно того, что не получается. Не, есть вариант, что вообще ни чего не получается, ну тогда и ни какого опробования — азы изучать
Дело в том, что я знаю как это сделать и много работал с Паскалем и Бейсиком. Но я не знаю как написать код красиво. Можно конечно сделать всё как обычно, чтобы была непонятная куча всего и объём превышал всякие мыслимые пределы, а можно посмотреть на чужую, но уже более красивую работу и вынести для себя основные моменты.
| Swallow1962 |
| Посмотреть профиль |
| Найти ещё сообщения от Swallow1962 |
Регистрация: 02.01.2011
Сообщений: 3,322
| а можно посмотреть на чужую, но уже более красивую работу и вынести для себя основные моменты. |
Вы создали тему с какой целью? Чтобы вам накидали исходников? Если кому-то требуются исходники чего-либо, то он гуглит. Вот более красивая работа на чистом Си, гуглится за 5 секунд: http://demin.ws/blog/russian/2012/12/10/snake-game/
Я считаю это хорошо — изучить исходники более опытного человека, извлечь основые идеи. Вы могли бы нагуглить несколько вариантов, изучить их хорошенько, сравнить между собой и написать свою версию змейки. Многие писали змейку, но не многие — консольную. Кто-то рисовал квадратики змейки на WinAPI, кто-то на OpenGL или DirectX. Я, например, сначала изучил змейку на C++ и GLUT и переписал её на Qt OpenGL. Позже я нашёл туториал змейки на C# и на игровом движке Unty5: http://noobtuts.com/unity/2d-snake-game
В общем, просто начните гуглить, изучайте чужой более профессиональный код и потихоньку развивайте свой.
| 8Observer8 |
| Посмотреть профиль |
| Найти ещё сообщения от 8Observer8 |
| Похожие темы | ||||
| Тема | Автор | Раздел | Ответов | Последнее сообщение |
| Змейка | Alex33RU | Помощь студентам | 0 | 20.05.2012 17:28 |
| змейка | spydark91 | Общие вопросы Delphi | 4 | 16.07.2011 15:12 |
| Змейка | zamaevac | Gamedev — cоздание игр: Unity, OpenGL, DirectX | 20 | 01.07.2010 19:19 |
| змейка =) | romiccccc | Помощь студентам | 0 | 12.05.2010 11:08 |
| ЗМЕЙКА(((( | mizantrop32 | Общие вопросы C/C++ | 2 | 07.04.2010 17:10 |
консольная змейка на с++
Решил по приколу написать некое подобие змейки на с++, но столкнулся с проблемой. Когда score доходит до 4, игра прекращается, подскажите пожалуйста, почему ?
#include #include #include using namespace std; int w = 20; int h = 20; bool gameOver; int x, y, fructX, fructY, score; enum eDir < STOP, LEFT, RIGHT, DOWN, UP >; eDir dir; void Setup() < gameOver = false; x = w / 2; y = h / 2; fructX = rand() % w; fructY = rand() % h; dir = STOP; >void Draw() < system("cls"); for (int i = 0; i < w + 1; i++) < cout cout << "\n"; for (int i = 0; i < h; i++) < for (int j = 0; j < w ; j++) < if (j == 0 || j == w - 1) < cout if (i == y && j == x ) < cout else if (j == fructX && i == fructY) < cout else < cout > cout for (int i = 0; i < w + 1; i++) < cout cout void Input() < if (_kbhit()) < switch (_getch()) < case 'a': dir = LEFT; break; case 'd': dir = RIGHT; break; case 'w': dir = UP; break; case 's': dir = DOWN; break; case 'x': gameOver = true; break; >> > void Logic() < switch (dir) < case LEFT: x--; break; case RIGHT: x++; break; case UP: y--; break; case DOWN: y++; break; >if (x == fructX && y == fructY ) < score += 1; fructX = rand() % w; fructY = rand() % y; >> int main() < Setup(); while(!gameOver) < Draw(); Sleep(100); Input(); Logic(); >>
Отслеживать
задан 21 июл 2023 в 23:40
15 2 2 бронзовых знака
программа прекращается с какой-то ошибкой или просто закрывается? (посмотрите в консоль, может там что нибудь пишется)
22 июл 2023 в 3:41
Блин, еще и сидеть играть, чтоб дойти до 4? «Сама, сама, сама!» (с)
Урок №14. Создание игры «Змейка» на C++/Qt5
Сегодня мы создадим аналог популярной игры «Змейка» на С++/Qt5.
Оглавление:
- Игра «Змейка»
- Разработка игры «Змейка»
- Заключение
Игра «Змейка»
Игра «Змейка» — это старая классическая видеоигра. Впервые она была создана в конце 70-х годов для использования на игровых автоматах, а затем в 1979 году её перенесли и на ПК. В этой игре игрок управляет тонким существом, похожим на змею, которое перемещается по игровому полю без остановки. Цель состоит в том, чтобы съесть как можно больше яблок, появляющихся в процессе игры. Каждый раз, когда змея съедает яблоко, она становится длиннее, что усложняет дальнейший процесс игры. Змея при этом должна избегать столкновений со стенами и собственным телом.
Разработка игры «Змейка»
Размер каждой отдельной «части» тела змеи составляет 10 пикселей. Управляется она с клавиатуры при помощи стрелочек: ← , → , ↑ , ↓ . Изначально тело змеи состоит из трех «частей». Если игра завершилась, то в центре игрового поля отображается сообщение «Game Over» .
Заголовочный файл — Snake.h: