Создание игры на C++ / Змейка - Урок #3 (Логика игры)

แชร์
ฝัง
  • เผยแพร่เมื่อ 25 พ.ย. 2024

ความคิดเห็น • 385

  • @tallwi
    @tallwi 4 ปีที่แล้ว +32

    Бомба!! Спасибо большое за урок, практика которую мы заслуживаем.
    Можно и что то добавить, и что то переделать, и понять структуру, и комментарии на каждом знаке, и всё на базовых знаниях...
    Ещё раз, ОГРОМНЕЙШЕЕ СПАСИБО!!!!!

  • @zaeu
    @zaeu 6 ปีที่แล้ว +472

    Я так понял GTA 6 я так не напишу

    • @ФондзащитыСВ-98
      @ФондзащитыСВ-98 5 ปีที่แล้ว +9

      C++-это самый сложный язык (он сам это сказал)

    • @DarknesS-sy6to
      @DarknesS-sy6to 4 ปีที่แล้ว

      @@ФондзащитыСВ-98 Ещё C# и PHP

    • @constvntine5453
      @constvntine5453 4 ปีที่แล้ว +11

      @@DarknesS-sy6to Что? с-шарп? ПХП?
      С-шарп - легкая версия Си, он не такой уж и трудный если смотреть на С.
      С пхп начинают новички, о нем говорить вообще смысла нет, легче легкого.

    • @DarknesS-sy6to
      @DarknesS-sy6to 4 ปีที่แล้ว +1

      @@constvntine5453 C# - Трудный, но не сложный? Так он трудный или нет?!
      К тому же я с тобой не соглашусь так, как испытывал тупые оплошности во время учёбы Python после учёбы PHP!

    • @constvntine5453
      @constvntine5453 4 ปีที่แล้ว +7

      @@DarknesS-sy6to Я так понял ты не знаешь разницу между "трудным" и "сложным". Питон мне показался легче чем php, у всех по разному. Там синтаксис проще, и книги есть достойные, по которым можно освоить не зная клиентскую часть, и многое другое.

  • @artempetrenko2518
    @artempetrenko2518 7 ปีที่แล้ว +78

    Буквально недавно начал писать свою змейку на С# в окне. Несколько дней гемороился с алгоритмом для хвоста змейки и тут это видео! Применил этот алгоритм, все работает! Большое спасибо! Жирный лайк)

    • @AlexandroLavichez
      @AlexandroLavichez 7 ปีที่แล้ว

      А там мерцание тоже есть?

    • @maximplyashchenko5610
      @maximplyashchenko5610 6 ปีที่แล้ว +2

      Мерцание будет, если делать, как автор видео. Используй SetConsoleCursorPosition. Лагов намного меньше.

    • @maximplyashchenko5610
      @maximplyashchenko5610 6 ปีที่แล้ว +25

      Функция SetConsoleCursorPosition (библиотека windows.h) устанавливает положение текстового курсора в консольном окне. Например:
      COORD cursorPos;
      cursorPos.X = 5;
      cursorPos.Y = 2;
      SetConsoleCursorPosition(hStdOut, cursorPos);
      Первым аргументом она принимает дескриптор консольного окна, а вторым - переменную типа COORD (это структура с двумя полями X и Y), в котройдолжны находиться координаты текстового курсора. Т.е. изменяет только выделеный символ. В этой игре, в сетапе, можно было один раз прорисовать карту, а потом, циклично прорисовывать каждый сегмент! И лагов было бы на столько мало, что они были бы просто не заметны! Но автору похуй! И правильно, легче спиздить чужой алгоритм, выложить под видом своего и не париться

    • @ДмитрийКулявец-в5у
      @ДмитрийКулявец-в5у 4 ปีที่แล้ว +3

      #include //Для работы с консолью и т.д. (библиотека много что может)
      void ConsolePenCoordinates(int& x, int& y)//Устанавливает курсор консоли по заданным координатам
      {
      COORD Position;//Объявление необходимой структуры
      HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);//Получение дескриптора устройства стандартного вывода
      Position.X = x;//Установка координаты X
      Position.Y = y;//Установка координаты Y
      SetConsoleCursorPosition(hStdOut, Position);//Перемещение каретки по заданным координатам
      }

    • @КириллЗахаров-ы4б
      @КириллЗахаров-ы4б 3 ปีที่แล้ว

      @@maximplyashchenko5610 как раз думал, чем можно это реализовать, спасибо

  • @alexivanov4068
    @alexivanov4068 2 ปีที่แล้ว +2

    Спасибо большое за уроки. Очень подробно, ясно и не очень усложненно. В комментах некоторые товарищи пишут, что можно лучше. Это понятно, что можно все красивее сделать. Но для начинающих то что нужно - без всяких нагромождений и общая логика понятно. Еще раз спасибо.

  • @nickilanto3308
    @nickilanto3308 7 ปีที่แล้ว +179

    Такое ощущение что он каждое видео меняет микрофон __--__--__

    • @kerikkent
      @kerikkent 5 ปีที่แล้ว +1

      Да, уж )

    • @David-xd8pu
      @David-xd8pu 5 ปีที่แล้ว

      //////////////////////////////////////////////////////////
      //ПОДСКАЖИТЕ почему не работает//
      //ОШИБОК НЕТ //
      //////////////////////////////////////////////////////////
      #include
      #include
      using namespace std;
      bool gameOver;
      const int width = 20;
      const int height = 20;
      int x, y;
      int fruitX, fruitY;
      int score;
      int tailX[100], tailY[100];
      int nTail;
      enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN };
      eDirection dir;
      void Setup()
      {
      gameOver = false;
      dir = STOP;
      x = width / 2 - 1;
      y = height / 2 - 1;
      fruitX = rand() % width;
      fruitY = rand() % height;
      score = 0;
      }
      void Draw()
      {
      system("cls");
      for (int i = 0; i < width + 1; i++)
      cout

    • @КрымБелорусский
      @КрымБелорусский 5 ปีที่แล้ว +2

      @@David-xd8pu у тебя ошибка значит

    • @Jaroshevskii
      @Jaroshevskii 3 ปีที่แล้ว

      Это магия мудацкого монтажа

    • @мастернедовещей
      @мастернедовещей 2 ปีที่แล้ว

      @@kerikkent вспомни старого maddy murk'a

  • @HillSkor
    @HillSkor 6 ปีที่แล้ว +74

    // Самый готовый код
    #include
    #include
    #include
    #include
    using namespace std;
    bool gameOver;
    const int width = 20;
    const int height = 20;
    int x, y, fruitX, fruitY;
    int score;
    int speed = 500;
    char corm;
    int tailX[100], tailY[100];
    int nTail = 0;
    enum eDirection {STOP = 0, LEFT, RIGHT, UP, DOWN};
    eDirection dir;
    void Setup();
    void Draw();
    void Input();
    void Logic();
    int main() {
    system("color 07");
    char menu;
    cout > menu;
    if (menu == 'Y' || menu == 'y') {
    system("color 70");
    Setup();
    while (!gameOver) {
    Draw();
    Input();
    Logic();
    if (gameOver)
    main();
    }
    }
    else if (menu == 'N' || menu == 'n') {
    system("cls");
    cout

  • @vadimsf5976
    @vadimsf5976 5 ปีที่แล้ว +98

    Играть в нее мы, конечно же, не будем.

  • @psychozoa
    @psychozoa 7 ปีที่แล้ว +8

    Спасибо! Очень понравилось! Нужно больше видео о консольных игрушках на С++ !

  • @maxazarov3504
    @maxazarov3504 5 ปีที่แล้ว +22

    #include
    #include //для считывания состояния клавиш клавиатуры
    #include // для floor
    #include //перемещения курсора в консоли, Sleep
    #include //для srand(), rand()
    #include //время для srand
    const int width = 22;
    const int height = 14;
    char pixel [width][height];
    int snake [width][height]{0};
    bool gameOver(false);
    bool gameStart(false);
    enum mover {STOP,LEFT,RIGHT,UP,DOWN};
    void displayGraphics(int score){
    //установка курсора в 0,0
    COORD position; // Объявление необходимой структуры
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);//Получение дескриптора устройства стандартного вывода
    position.X = 0; // Установка координаты X
    position.Y = 0; // Установка координаты Y
    SetConsoleCursorPosition(hConsole, position); // Перемещение каретки по заданным координатам
    //system("cls");
    for(int j=0;j

    • @vladatsman5464
      @vladatsman5464 5 ปีที่แล้ว +2

      а можешь создать репозиторий на гит хабе, а то твой код не работает

    • @viktorperov3104
      @viktorperov3104 4 ปีที่แล้ว

      Ошибка C4996 стр 99-100

    • @viktorperov3104
      @viktorperov3104 4 ปีที่แล้ว

      if (kbhit())
      fromTheKeyboard = getch();

    • @GENZEKIRILL
      @GENZEKIRILL 4 ปีที่แล้ว +1

      @@viktorperov3104 if (_kbhit())
      fromTheKeyboard = _getch();

    • @ІА-11ДанилоБерковський
      @ІА-11ДанилоБерковський 4 ปีที่แล้ว

      нихрена не пашет

  • @alexlivingstone3419
    @alexlivingstone3419 9 หลายเดือนก่อน

    от души за туториал, у меня все вышло, спасибо !

  • @dimagomid6641
    @dimagomid6641 6 ปีที่แล้ว +56

    тут вроде есть баг, если змейка едет вниз и нажать вверх, то голова начнет движение вверх, а там хвост и гейм овер. нужно еще пару условий (где то в инпут функции) типа: если последняя нажатая кнопка была вниз, то вверх нажать нельзя, только влево или вправо. если было нажато D, то доступно только W или S ну и т.д.

    • @deniskaliuzhnui2385
      @deniskaliuzhnui2385 6 ปีที่แล้ว +7

      switch (_getch())
      {
      case 'a':
      if (dir != RIGHT || nTail == 0)dir = LEFT; break;
      case 'd':
      if (dir != LEFT || nTail == 0) dir = RIGHT; break;
      case 'w':
      if (dir != DOWN || nTail == 0) dir = UP; break;
      case 's':
      if (dir != UP || nTail == 0) dir = DOWN; break;
      case 'q':
      dir = STOP; break;
      case 'x':
      gameOver = true ; break;

    • @Alexander0803
      @Alexander0803 6 ปีที่แล้ว +11

      void Input() {
      if (_kbhit()){
      switch(_getch())
      {
      case 'a':
      if (dir != RIGHT)
      dir = LEFT;
      break;
      case 's':
      if (dir != UP)
      dir = DOWN;
      break;
      case 'd':
      if (dir != LEFT)
      dir = RIGHT;
      break;
      case 'w':
      if (dir != DOWN)
      dir = UP;
      break;
      case 'x':
      gameOver = true;
      break;
      }
      }
      }

    • @mmmmhmmm6517
      @mmmmhmmm6517 5 ปีที่แล้ว +1

      @@deniskaliuzhnui2385 зачем q?

    • @lon5393
      @lon5393 5 ปีที่แล้ว +1

      @@Alexander0803 а нельзя ли написать типо если было нажато D то A будет false если я неправильно сказал поправьте я только начинаю изучать язык.

    • @pashakey4611
      @pashakey4611 5 ปีที่แล้ว +1

      @@lon5393 Нет,элементы свича не имеют проверки,её надо создавать отдельно,здесь же проверка уже встроена в кейсы,так просто удобнее(занимает меньше места).Кстати,небольшой вопросик,как учишь(какая-нибудь литература,или чей-то канал)?

  • @Funkbass1986
    @Funkbass1986 7 ปีที่แล้ว +5

    можно было чтоб сберечь ресурсы компа все числовые переменные, значение которых в принципе не может превысить 255, объявить как char. char - один байт, а int - 4 байта как правило. Программирование микроконтроллеров приучает так делать)) на ассемблере, конечно проще: байт - это все что ты сам захочешь. Хочешь - целое, хочешь - с точкой, хочешь - отрицательное. хочешь - символ)))

  • @EliseyKarpov
    @EliseyKarpov 7 ปีที่แล้ว

    В процессе тестирования нашел 2 бага:
    1) не работают кнопки, если включен Caps Lock, это мелочь конечно и исправимо.
    2) Последний цикл прохождения через стену нормально работает с -1, иначе когда фрукт около самой стенки, то его никак не взять. поэтому получается так:
    if (x >= width - 1)
    x = 0;
    else if (x < 0)
    x = width - 1;
    if (y >= height - 1)
    y = 0;
    else if (y < 0)
    y = height - 1;
    Спасибо большое за увлекательные видео!

  • @alexandersechin7261
    @alexandersechin7261 4 ปีที่แล้ว +1

    Большое спасибо! Очень хорошо и доступно!

  • @odiltilloev2079
    @odiltilloev2079 ปีที่แล้ว

    Огромное спасибо за видео

  • @abursuk
    @abursuk 7 ปีที่แล้ว +5

    11:52 после gameOver = true неплохо бы и выход из цикла дописать.
    Ну и избыточным считаю проверять выход змейки за пределы по x, если она движется по y)
    И советую структурировать код и использовать ООП (из-за которого с++ и был придумал собсно :) )

    • @alexmaltsev7835
      @alexmaltsev7835 7 ปีที่แล้ว

      Ami00 чего? Ооп в змейке в консоли? Для чего? Класс с одним методом для вывода в консоль?

    • @abursuk
      @abursuk 7 ปีที่แล้ว +4

      количество классов и методов будет зависеть от твоей архитектуры. и более того тут можно использовать и FSM. Вывод\ввод (в том числе в консоль) лучше выносить за пределы логики, можно даже в отдельную подключаемую длл. Это называется нормальным стилем программирования. и это приветствуется, особенно в учебных видео. а стиль аля "пишу все в одной функции@называю это с++" врядли кого-то чему-то научит (хорошему).

    • @alexmaltsev7835
      @alexmaltsev7835 7 ปีที่แล้ว

      "нормальный стиль" используют в "нормальных" проектах, а не темповой змейке в консоли на 100 строк. ООП тут использовать бесполезно.

    • @abursuk
      @abursuk 7 ปีที่แล้ว +5

      смотря в чем польза. если это урок, то он должен чему-то научить. с такой точки зрения использовать правильные подходы в создании архитектуры приложения, использовать пару патернов - это полезно. это способствует в обучении программированию. Та и не будет там 1-го класса с одним методом. Золотое правило звучит так: 1 метод выполняет одно логическое действие, длина метода не должна быть больше одного экрана в 90% случаев. если у человека есть знания\опыт в проектировании архитектуры приложений, то ему не составит труда сделать все нормально не зависимо от размера проекта (за исключением очень крупных), поэтому я не вижу, почему бы в учебных целяг не показать наглядно как это делается. во-вторых, пользы с точки зрения экономии в размере сорцов не будет, но будет более наглядный\понятный\структурированный код как результат перекладывания сущностей из реальности на юзер-дефайнед типы(классы). Обычно программисты оставляют место для маневра, допустим, мы захотим сделать, чтолы был не 1 тип фруктов, а несколько. в том виде кода, что представлен в видео - это будет треш, если же будет использоваться ооп парадигма, фактори патерн, то это может быть сделано в течении 5-10 минут без особых усилий и превращения кода в еще большее говно. если вынести взаимодействие юзера с программой в отдельно подключаемый модуль (как частенько и делают), то это позволит нам полностью в коде игровой логики абстрагироваться от I/O, что в дальнейшем облегчит возможность перехода на альтернативный методы I/O - имя один интерфейс общения, может подключить вместо консольного ввода\вывода любую графическую либу. Можем даженаписать несколько реализаций I/O и по типу аддынов подключать в зависимости от выбора пользователя. проще говоря, это называется - расширяемость. если до сих пор непонятно, то я сдаюсь.

    • @unittest3649
      @unittest3649 6 ปีที่แล้ว

      А как называется тема по разделению программы на отдельные файлы, подскажите, пожалуйста

  • @fedorkonuxov7076
    @fedorkonuxov7076 5 ปีที่แล้ว +2

    Удивительно!
    Это одновременно и абсолютное сумасшествие (в болезненной форме) :)))),
    и необузданная гениальность!!! :)))
    Змейка, блин, мать её, на консоли!!!!! :)))))))))
    Потрясающе!!! :)
    Достойно лайка! :)
    З.Ы. Чем-то напоминает шоу "Чудаки"... Круто и весело, но "не делайте так дома"!!! :)))

    • @dimker4130
      @dimker4130 4 ปีที่แล้ว

      Он сплагиатил с запада код

    • @sidorstrelok6843
      @sidorstrelok6843 3 ปีที่แล้ว

      @@dimker4130 можешь скинуть код? у меня с хвостом проблемы, просто хочу сравнить и найти ошибку. У меня когда 3 фрукт собираю, то 4-10 части тела не следуют идеально, а только горизонтально. тоесть первые 2 части змейки идут за головой, остальные горизонтальной полосой

  • @andreym2567
    @andreym2567 5 ปีที่แล้ว +20

    #include
    #include
    #include
    #include
    using namespace std;
    bool gameOver;
    const int width = 20;
    const int height = 20;
    int x, y, fruitX, fruitY, score;
    int tailX[100], tailY[100];
    int nTail;
    enum eDirection {STOP = 0, LEFT, RIGHT, UP, DOWN};
    eDirection dir;
    void Setup() {
    gameOver = false;
    dir = STOP;
    x = width / 2 - 1;
    y = height / 2 - 1;
    fruitX = rand() % width;
    fruitY = rand() % height;
    score = 0;
    }
    void Draw() {
    Sleep(300);
    system("cls"); //SYSTEM CLEAR
    for (int i = 0; i < width+1; i++)
    cout

  • @nyvyme
    @nyvyme 6 ปีที่แล้ว +7

    Хорошо было бы сделать видео как изменить framerate в console играх!

  • @1234qub
    @1234qub ปีที่แล้ว

    Спасибо за урок!!!!!

  • @МаксимОанча
    @МаксимОанча 7 ปีที่แล้ว +1

    Спасибо за турориал, очень понравилось. Столкнулся с проблемой что слишком быстро обновляется консоль и просто не успеваю управлять змеей. Сначала просто увеличил поля высоты и ширины а потом решил что лучше приостанавливать главный поток(_sleep(time_sleep)).Поставил 100 мс и норм. Думаю можно тип усложнять єтим параметром, по типу больше очей набрал, уменьшил немного time_sleep......все, я спать

    • @usovmisha
      @usovmisha 7 ปีที่แล้ว +1

      Привет, я еще новичок , но не могу понять , где ты прописал команду (_sleep(time_sleep) , помоги пожалуйста .

  • @Funkbass1986
    @Funkbass1986 ปีที่แล้ว

    С точки зрения разбития основноц задачи на подзадачи и объяснения логики - очень классное видео. Но читабельность кода... Я так писал когда пересел с QBasic на C++. Если бы я писал эту игру сейчас, я бы создал класс Segment, который хранил бы свойства сегментов хвоста и создал бы например вектор указателей на такие сегменты. Когда съдаешь фрукт, то в конец вектора добавляется еще один экземпляр класса Segment. И сделал бы наследный класс Head : public Segment. С тем, чтобы if(Head.Coord == Segment. Coord) gameOver = true. Ну примерно так, читабельность кода будет на порядок веселее

  • @Ілько-р2т
    @Ілько-р2т ปีที่แล้ว

    Конечно с прорисовкой заново всего поля игры будет брать много ресурсов, думаю лучше сделать массив игрового поля, и торомозить не будет, и проверку делать если край , змея или фрукт, сравнивая координату головы с ячейкой масива, моргать так не будет, когда то давно еще в начале 90х на турбо паскале (похож на С, в универе потом С проще было понять) написал тетрис, и комп у меня был "Искра" так там проц был 4МГерца, и игра не торозила)

  • @gugglegum
    @gugglegum 4 ปีที่แล้ว +4

    Кстати, а я правильно понимаю, что в данной реализации нет защиты от того, что яблоко может появиться прямо на змейке? Это же тоже надо отслеживать. Причём, я считаю, не совсем правильным просто проверять это и брать новые случайные координаты, потому что может оказаться так, что игровое поле почти полностью заполнено змейкой и нам придётся очень много раз вызывать функцию rand(), чтобы найти пустую клетку. В своей реализации змейки я делал иначе. Я считал кол-во пустых клеток на карте, а потом брал rand() из диапазона до этого числа, а потом отсчитывал на карте, идя слева направо, сверху вниз пустые клетки. Таким образом, я находил свободную клетку за 1 вызов rand(). Но правда ценой обхода в среднем половины карты. Плюс в моей реализации есть возможность обработать ситуацию, когда клетки заполнены на 100% и яблоко просто некуда поставить. Я считаю эту ситуацию победой игрока.

  • @yegormakarenko5045
    @yegormakarenko5045 7 ปีที่แล้ว

    Отлично!

  • @alex_10405
    @alex_10405 5 ปีที่แล้ว +1

    Спасибо, пойду на основе змейки сокобан делать :D

  • @flexer5611
    @flexer5611 5 ปีที่แล้ว +11

    на половине 3 видео все сбилось и я понял что буду заниматься фигней

  • @ohmycfg
    @ohmycfg 6 ปีที่แล้ว +47

    #include
    #include
    #include
    using namespace std;
    bool gameOver;
    const int width = 20;
    const int height = 20;
    int x, y, fruitX, fruitY, score;
    int tailX[100], tailY[100];
    int nTail;
    enum eDirecton { STOP = 0, LEFT, RIGHT, UP, DOWN};
    eDirecton dir;
    void Setup()
    {
    gameOver = false;
    dir = STOP;
    x = width / 2;
    y = height / 2;
    fruitX = rand() % width;
    fruitY = rand() % height;
    score = 0;
    }
    void Draw()
    {
    system("cls"); //system("clear");
    for (int i = 0; i < width+2; i++)
    cout

  • @krenciak
    @krenciak 7 ปีที่แล้ว +15

    Спасибо за видео! Уроки полезные! Хотелось бы курс по 3D игре на с++ (слышал, что на c++ игра Minecraft более производительная, чем Minecraft на Java).

    • @AlexandroLavichez
      @AlexandroLavichez 7 ปีที่แล้ว +4

      Еще 2D не было, а тебе уже 3D подавай!

    • @4AneR
      @4AneR 7 ปีที่แล้ว +6

      Эти школьники недоразработчики и понятия не имеют, насколько это сложно.

    • @krenciak
      @krenciak 7 ปีที่แล้ว

      Да я уже понял... Нужно изучить типы рендеринга, OpenGL, наложения текстур, добавление 3D объектов и т. д.

    • @alexmaltsev7835
      @alexmaltsev7835 7 ปีที่แล้ว +1

      OpenGl тебе в помощь... а на чистом C++ без знания высшей математики, а в частности матриц и матричных умножений, делать 3d игры, непонимая как это работает будет нереально сложно. ИМХО
      ОТВЕТИТЬ

    • @krenciak
      @krenciak 7 ปีที่แล้ว

      Уже почти выучил! Благодаря этому курсу - th-cam.com/video/aMHUfGLmv1E/w-d-xo.html

  • @Красный-ц9ч
    @Красный-ц9ч 5 ปีที่แล้ว

    Круто

  • @ИсламКаримов-в8б
    @ИсламКаримов-в8б 3 หลายเดือนก่อน +1

    почему в 9:30 tailX[0] = x и аналогично и с у? и почему не завершается игра когда мы проверяем не попали ли мы головой по хвосту: for(int i = 0; ..){ if(tailX[i] == x ...) то gameover}

  • @rlv8472
    @rlv8472 7 ปีที่แล้ว +3

    я посмотрел конечный результат и увидел мерцание, как я понял вы аросто перерисовывали все элементы, но лучше использовать виндовс апи, там можно менять конкретные символы, т.е. нам не надо все перерисовывать, а лишь 3: конец хвоста закрасить, перенести голову, и закрасить старую голову как тело

    • @AlexandroLavichez
      @AlexandroLavichez 7 ปีที่แล้ว +1

      Расскажи поподробнее пожалуйста

  • @niksaen9152
    @niksaen9152 5 ปีที่แล้ว

    Прикольно

  • @myriaxont
    @myriaxont 4 ปีที่แล้ว

    Я на js делал змейку по книжке, использовав ООП и там я для каждого блока создавал объект (с координатами x, y) и добавлял в массив такие объекты, если игрок нажимал влево я добавлял объект влево если в перед то в перед ну и в право добавлял в право, только если игрок не съел яблоко я отнимал последний элемент, итого: змейка с многоцветной полноценной графикой, 200 строк кода, разделенных на легко читаемые блоки кода, без каких либо багов типа нажатия вперед и сразу назад (я сделал короткую проверку этого). Замечу что в c++ вы могли бы использовать вместо int, short - с вашими лагами это бы очень погло.

  • @vitanick3
    @vitanick3 4 ปีที่แล้ว

    еще в 12 лет писал змейку. алгоритм прорисовки хвоста здесь ужасен. а насколько проще и Красивее не очищать экран, а в последнем звене хвоста рисовать пробел! задумайтесь) красиво, изящно, не мигает. на современных ресурсах компа люди совсем думать перестают (( но за видео лайк, отлично грамотно объясняет автор!

  • @VirtroNation
    @VirtroNation 7 ปีที่แล้ว +4

    Привет, как называется эффект в играх, когда персонаж может быть одновременно с правой и с левой стороны экрана? Это когда персонаж доходит до правой стороны экрана и начинает вроде бы уходить за экран, но на самом деле выходит с левой стороны экрана. Меня интересует лишь общепринятое название, а не алгоритм.

    • @Irizzz886
      @Irizzz886 2 ปีที่แล้ว

      я называю это "телепорт"😁

  • @4AneR
    @4AneR 7 ปีที่แล้ว +61

    Абсолютно неэффективная обработка хвоста. Движение змейки, можно сделать просто стерев последний элемент, и добавив его вперед головы.

    • @theonewhonowz
      @theonewhonowz 7 ปีที่แล้ว +4

      Каждый решает задачу по разному

    • @abursuk
      @abursuk 7 ปีที่แล้ว +32

      да, можно штаны через голову надевать - выбор каждого

    • @theonewhonowz
      @theonewhonowz 7 ปีที่แล้ว +2

      Ну если ты все делаешь по шаблону и не можешь сам решить задачу, а наверняка копи-пастишь исходники, то все очень плохо! Все не пиши мне, я все равно не отвечу!

    • @abursuk
      @abursuk 7 ปีที่แล้ว +16

      ага, вот такая я не уникальная снежинка, не изобретаю велосипед с квадартными колесами и не ищу алгоритмов надевания штанов через голову. А наоборот, предпочитаю использовать уже накопленные человечеством знания в области. а про алгоритм с движением змеи даже искать ничего не надо, если хоть чуточку понимаешь что есть игра, что есть state pattern и владеешь базовой логикой ребенка 10 лет :) я столкнулся со змейкой я во время разработки AI для этой игры (:

    • @MrMes
      @MrMes 7 ปีที่แล้ว

      Re Frost это если голова змеи и тело одинаковые символы.

  • @DunnoOnTheMoon
    @DunnoOnTheMoon 5 ปีที่แล้ว

    Спасибо

  • @AMartin-yt6gn
    @AMartin-yt6gn 7 ปีที่แล้ว +43

    // Готовый код
    #include
    #include
    #include
    #include
    using namespace std;
    bool gameOver;
    const int width = 20;
    const int height = 20;
    int x, y, fruitX, fruitY;
    int score;
    int speed = 500;
    char corm;
    int tailX[100], tailY[100];
    int nTail = 0;
    enum eDirection {STOP = 0, LEFT, RIGHT, UP, DOWN};
    eDirection dir;
    void Setup();
    void Draw();
    void Input();
    void Logic();
    int main() {
    system("color 07");
    char menu;
    cout > menu;
    if (menu == 'Y' || menu == 'y') {
    system("color 70");
    Setup();
    while (!gameOver) {
    Draw();
    Input();
    Logic();
    if (gameOver)
    main();
    }
    }
    else if (menu == 'N' || menu == 'n') {
    system("cls");
    cout

    • @sopliviy_ezh
      @sopliviy_ezh 7 ปีที่แล้ว +6

      Наворотил чуши собачьей

    • @drazzert9473
      @drazzert9473 7 ปีที่แล้ว +1

      Спасибо чувак, неплохой код.

    • @go1_D
      @go1_D 5 ปีที่แล้ว

      Твое дерьмо даже не запускается ахах

  • @НатКис-с1ь
    @НатКис-с1ь 7 ปีที่แล้ว

    круто))

  • @АнатолийИванович-и3н
    @АнатолийИванович-и3н 11 หลายเดือนก่อน

    топ

  • @СтарыйВаленок-к4л
    @СтарыйВаленок-к4л 4 ปีที่แล้ว

    Уважаемый Гоша, эта рубрика весьма интересна, почему же вам её не продолжить. Когда-то ещё на синклере, практически в детстве пробовал писать. Но там был язык бейсик и производил обновление экрана также, через cls... В любом случае спасибо.

  • @timohavol8032
    @timohavol8032 7 ปีที่แล้ว +14

    Как наложить текстуры на это всё дело?

    • @УважаемыйЧеловек-л4с
      @УважаемыйЧеловек-л4с 6 ปีที่แล้ว +4

      Timohavol в консоли никак. Надо делать отдельное приложение

    • @bumstern
      @bumstern 6 ปีที่แล้ว +1

      Погугли про SFML

    • @krenciak
      @krenciak 6 ปีที่แล้ว +2

      Можно с помощью DirectX, но для такой простой змейки подойтет GLUT - th-cam.com/video/cEWNPLtBTAM/w-d-xo.html

  • @sidorstrelok6843
    @sidorstrelok6843 3 ปีที่แล้ว +1

    Помогите пожалуйста, когда змейка забирает 3 фрукт, то с 4-го весь хвост растёт только в горизонтальном направлении

  • @nMnFunny
    @nMnFunny 4 ปีที่แล้ว +1

    есть баг. Дело в том, что, когда выбираешь противоположную сторону, умираешь, так как x равно tailX

  • @ПаукизПоволжья
    @ПаукизПоволжья 7 ปีที่แล้ว

    круто

  • @jamescleave7024
    @jamescleave7024 6 ปีที่แล้ว +5

    При взятии второго и далее фруктов кусок хвоста сначала появляется в верхнем левом углу (9:48) а потом уже присоединяется к змейке. Довольно смутно понимаю как вообще этот хвост работает, можно ли от этого бага избавиться?

    • @1mpalo362
      @1mpalo362 8 หลายเดือนก่อน

      можно, если добавлять элементы по другому, просто переоносить хвость в голову

  • @alexmaltsev7835
    @alexmaltsev7835 7 ปีที่แล้ว +3

    Классные видео снимаешь, но почему ты не сказал, что это перевод видоса NVitanovic? Код ведь идентичен, даже частей как у него 3.) А так, голос приятно слушать и изложено все четко.

  • @Нифирпитус
    @Нифирпитус 3 ปีที่แล้ว +1

    Ну, у меня практически получилось, не считая того, что с левой стенкой, явно что-то не так

  • @Helik36
    @Helik36 7 ปีที่แล้ว +4

    Ребят, а есть курс, как сделать хотя бы ту же змейку, но уже в окне, скажем как сапёр, где можно уровень сложности выбрать, чтобы была окошки: закрыть, свернуть, справка и т.д?

    • @КириллГоловин-э9и
      @КириллГоловин-э9и 7 ปีที่แล้ว +5

      Зачем тебе еще один курс после этого, не все время же копипастить... SFML вот подсказочка, дерзай.

    • @artombondarev7798
      @artombondarev7798 5 ปีที่แล้ว +1

      сам думай, прохрамест...

  • @MEDBEDb78
    @MEDBEDb78 7 ปีที่แล้ว

    змейка себя не ест. игра продолжается.

  • @anatoly203
    @anatoly203 5 ปีที่แล้ว

    надо чтобы фрукт прямо на хвост змейки не срандомило :D

  • @pentalogue_trialogue
    @pentalogue_trialogue ปีที่แล้ว +1

    А что делать, если после съедения первого "фрукта" появляется хвост, а после второго у змейки пропадает этот хвостик?

    • @bogdanstrange6377
      @bogdanstrange6377 11 หลายเดือนก่อน

      Кстати у меня также

  • @sergiykuzmich6241
    @sergiykuzmich6241 7 ปีที่แล้ว +8

    зачем очищать всё поле, когда можно зачищать по координатам там где была змейка

    • @go1_D
      @go1_D 5 ปีที่แล้ว

      КАК ОЧИЩАТЬ ПОЛЕ ПО КООРДИНАТАМ? НАПИШИ КОД

    • @polzuisia
      @polzuisia 4 ปีที่แล้ว

      Я тоже об этом подумал, но код написать такой пока не смогу. Скинь пожалуйста, если сможешь написать.

  • @riverrelaxation8920
    @riverrelaxation8920 9 หลายเดือนก่อน

    Подскажите как работает логика пявления хвоста у змейки.

  • @Ruslan-nj5zw
    @Ruslan-nj5zw ปีที่แล้ว

    у меня почемуто rand() работает не коррекно. после сьедания фрукта новый не появляется. вначале я состался на то что рандомное значение выходит за пределы поля и добавил
    fruitX = 3 + rand() % (width - 3);
    fruitY = 3 + rand() % (height - 3);
    что вы наверняка не вышло, но это не помогает

  • @pomidorka3093
    @pomidorka3093 7 ปีที่แล้ว +4

    Я конечно не уверен, но в коде размещения еды для змеи может произойти такое, что еда появиться за границами и мы не сможем ее достать...

  • @BlackBaron2622
    @BlackBaron2622 7 ปีที่แล้ว +1

    единственное. )) В коде всегда нужно комментить, что и для чего тот или иной цикл, функция, или переменная. Особенно полезно, когда разбираешься потом в этом коде.

  • @timetravel9199
    @timetravel9199 5 ปีที่แล้ว

    Все классно только когда нажимаю на противоположную кнопку он выходит из игры , например у меня уже 4 "o" на хвосте еду вперед нажимаю на заднюю кнопку и выходит из игры. Нужно сделать так чтобы противоположная кнопка не работала.

  • @__-ff2vt
    @__-ff2vt 3 ปีที่แล้ว

    хвост не отображается, но при касании об голову геймовер --> хвост есть. Что делать?
    Вот код блока Draw:
    void Draw() {
    system("cls");
    for (int i = 0; i < width + 1; i++) {
    cout

  • @nexus25d41
    @nexus25d41 5 ปีที่แล้ว

    Отличный урок, спасибо.
    Единственное, что не так - после 3-го съеденного фрукта, если нажимаешь клавишу, противоположную направлению движения, игра завершается.
    Так не должно быть

  • @davidrobinson157
    @davidrobinson157 6 ปีที่แล้ว +2

    Несогласен с двумя моментами. Первое, как рисуется хвост. Легче было бы, если просто удалить последний элемент хвоста (массива) и добавить один элемент перед головой, а не передвигать всю змею. Второе, то что ты творишь с width и height. Зачем весь этот геморой с единицами, если можно было сделать всё нормально.

  • @sket7314
    @sket7314 ปีที่แล้ว

    есть один бак, как его можно поправить. если нажать на кнопку противоположную от направления движения то игра прекратиться, то есть если змейка ползет вверх и нажать клавишу s и т.п.

    • @wizzarrip2054
      @wizzarrip2054 8 หลายเดือนก่อน

      Понимаю что поздно, но это не баг, по сути это и есть условие пройгрыша, змея пытается съесть свой хвост поэтому и умирает, если это же сделать без хвоста, то ничего не будет

  • @ll-zf3tj
    @ll-zf3tj 4 ปีที่แล้ว +3

    пишите змейку сами. Какой смысл если вы просто подсмотрите решение или просто скопируете код?

  • @pofigistgamer
    @pofigistgamer 6 ปีที่แล้ว

    вопрос такой, как запретить двигаться в сторону противоположную движению которое уже происходит. то есть если идет движение влево то запретить двигаться вправо и на оборот, также для вверх и вниз

  • @shishka911
    @shishka911 6 ปีที่แล้ว

    Класс , только как я понял долго

  • @white9680
    @white9680 ปีที่แล้ว +1

    большое спасибо!)
    а как данный код написать на C++?

    • @ShapkaDeda
      @ShapkaDeda 11 หลายเดือนก่อน

      никак

  • @VOVCHANSKY
    @VOVCHANSKY 2 ปีที่แล้ว

    Очень круто! А можно как то задать интервал изменения картинки? А то у меня змея летает как самолет, не успеваю уследить нормально за ней

    • @Irizzz886
      @Irizzz886 2 ปีที่แล้ว +1

      добавь в самом начале библиотеку и в int main после Logic пропиши Sleep(300)

    • @VOVCHANSKY
      @VOVCHANSKY 2 ปีที่แล้ว

      @@Irizzz886 спасибо)

    • @ogabekdavr9974
      @ogabekdavr9974 2 ปีที่แล้ว

      @@Irizzz886 не работает кстати

  • @yanikusgg
    @yanikusgg 7 ปีที่แล้ว +13

    У тебя поле 21*20, ты хоть в курсе??! Нельзя чтоли всё по человечески сделать, без всяких "+1" у width

    • @yanikusgg
      @yanikusgg 7 ปีที่แล้ว +8

      А хотя смысл коммент писать, он всё равно их не читает

    • @AlexandroLavichez
      @AlexandroLavichez 7 ปีที่แล้ว +5

      Тем лучше, значит у тебя по-другому будет, пусть учатся думать самостоятельно

    • @sidorstrelok6843
      @sidorstrelok6843 3 ปีที่แล้ว

      можешь скинуть код? у меня с хвостом проблемы, просто хочу сравнить и найти ошибку. У меня когда 3 фрукт собираю, то 4-10 части тела не следуют идеально, а только горизонтально. тоесть первые 2 части змейки идут за головой, остальные горизонтальной полосой

  • @sabatonbaton6105
    @sabatonbaton6105 2 ปีที่แล้ว

    Можно было через модуль сделать, без убогих условий, если выходит за границу значит от текущей координаты -10 в модуле, тогда если стенка справа,то 11- 10 =1, если слева, то 0 - 10 в модуле получаем 10, вот и все

  • @gemmadeonit
    @gemmadeonit 5 ปีที่แล้ว

    Стало интересно, смогу ли я это на Delphi переписать...

  • @evgeshad3011
    @evgeshad3011 4 ปีที่แล้ว +1

    Есть исходный код ?

  • @АристархКлешня
    @АристархКлешня ปีที่แล้ว

    Добрый день, она у меня носится как бешенная в чем причина, из за мощности компуктера?

  • @patlatyi
    @patlatyi 4 ปีที่แล้ว

    почему фрукты появляются за пределами поля ?

  • @РусланШевцов-й4п
    @РусланШевцов-й4п 3 ปีที่แล้ว +1

    Я не понимаю, почему эта игра написана на С++, ведь кроме функций и статических переменных, ничего больше нету. Если не брать во внимание подключенных библиотек, весь код это обычный С.

  • @Dragon-vf1vw
    @Dragon-vf1vw 5 ปีที่แล้ว

    подскажите, как запустить код в отдельном консольном окне в clion ? у меня после выбора направления, допустим, w появляется бесчисленное количество игровых полей

  • @tati.oxyeli145
    @tati.oxyeli145 2 ปีที่แล้ว

    объясните как хвост работает, 30 мин пытаюсь разобраться, хрень полная, там жк цикл и в нем все значения не известны

  • @expertx3179
    @expertx3179 7 ปีที่แล้ว +3

    Скиньте этот полный код, если не сложно. Я сам переписал, но компилятор ругается. Хочу найти свою ошибку, а по видео не удобно. Спасибо заранее!

  • @diobrando5839
    @diobrando5839 4 ปีที่แล้ว +2

    Помогите пожалуйста, как запустить код???

  • @НатальяПопова-э6у4с
    @НатальяПопова-э6у4с 6 ปีที่แล้ว +6

    все работает но когда ем третий фрукт хвост не пристраивается сзади , а летает по карте.Подскажите что не так

    • @АртёмЛевчук-д2и
      @АртёмЛевчук-д2и 6 ปีที่แล้ว +1

      У вас ошибка примерно на 90-й - 100-й строке кода, в функции логики. А именно в цикле for (int i = 1; i < nTail; i++) {
      prev2X = tailX[i];
      prev2Y = tailY[i];
      tailX[i] = prevX;
      tailY[i] = prevY;
      //здесь у вас написано tailX[i] = prevY; а должно быть tailY[i] = prevY;
      prevX = prev2X;
      prevY = prev2Y;
      }

  • @artur4ik82
    @artur4ik82 7 ปีที่แล้ว +3

    извини что не совсем по теме, но у меня просьба, запиши видео "Как сделать личный кабинет для сайта" Отвечаю если запишешь такое видео то уж точно наберешь много просмотров, так как в интернете на эту тему я ни чего не нашел

  • @pravdin28
    @pravdin28 3 ปีที่แล้ว

    змея после 3 фрукта у меня, теряет хвост и он бегает по экрану сам, это почему? т.е. ест первый, второй, третий и все бегает с таким хвостом, а остальной хвост на экране сам бегает)))

  • @alexlem3597
    @alexlem3597 2 ปีที่แล้ว

    Интересно, как запустить сию игру на Linux, ведь там нет conio.

  • @badstreamlemberg8701
    @badstreamlemberg8701 2 ปีที่แล้ว

    подскажите пожалуйста, досмотрел до 7.29 минуты и у меня пишет ошибку
    [Error] incompatible types in assignment of 'int' to 'int [100]'
    как быть?
    на эти строчки ругается:
    tailX = prevX;
    tailY = prevY;

    • @badstreamlemberg8701
      @badstreamlemberg8701 2 ปีที่แล้ว

      исправил
      int tailX = prevX;
      int tailY = prevY;
      у меня почему то ругался непонятно, хотя мы эти переменные вначале еще объявили

  • @nohypemax8819
    @nohypemax8819 6 ปีที่แล้ว

    Ntail можно просто заменить переменной score

  • @3dportableinc64
    @3dportableinc64 5 ปีที่แล้ว

    как насчет OpenGL или других графических библиотек

  • @GamesTimeux
    @GamesTimeux 7 ปีที่แล้ว +5

    Гоша там в логике есть один маленький баг. Иногда фрукт отрисовывается так , что его не видно на поле. Как это исправить?

    • @mukhamedshisyr679
      @mukhamedshisyr679 7 ปีที่แล้ว +1

      сделай что его координат не должен превышать width and height

    • @GamesTimeux
      @GamesTimeux 7 ปีที่แล้ว

      опять также

    • @GamesTimeux
      @GamesTimeux 7 ปีที่แล้ว

      если не трудно сам посмотри что можно сделать
      #include
      #include
      #include
      #include
      using namespace std;
      bool gameOver;
      const int width = 20;
      const int height = 20;
      int x, y, fruit_x, fruit_y, score;
      int tailX[100], tailY[100];
      int nTail;
      enum edirect { stop = 0, LEFT, RIGHT, up, down };
      edirect dir;
      void setup()
      {
      srand(100);
      gameOver = false;
      dir = stop;
      x = width / 2-1;
      y = height / 2-1;
      fruit_x = rand() % width;
      fruit_y = rand() % height;
      score = 0;
      }
      void draw()
      {
      //i-koorfinata po y, j-koordinata po x.
      system("cls");
      for (int j = 1; j

    • @mukhamedshisyr679
      @mukhamedshisyr679 7 ปีที่แล้ว

      if (x == fruit_x && y == fruit_y)
      {
      score += 1;
      fruit_x = rand() % width;
      fruit_y = rand() % height;//proverit koordinati zmeji i tolko potom otrisovat frukt
      nTail++;
      while(fruit_x >= width || fruit_y >= width || fruit_x < 0 || fruit_y < 0){
      fruit_x = rand() % width;
      fruit_y = rand() % height;
      }
      }

    • @GamesTimeux
      @GamesTimeux 7 ปีที่แล้ว

      не работает

  • @obi-wankenobi6033
    @obi-wankenobi6033 2 ปีที่แล้ว

    Может кто-нибудь подсказать? Я хотел сделать переключатель перед игрой между режимом, когда стена убивает, а когда позволяет пройти сквозь себя. Как это сделать?

    • @mne_pohui
      @mne_pohui 2 ปีที่แล้ว

      выводишь сначала текст
      где пишет
      1 - такой режим
      2 - такой режим
      с помощью
      _getch() узнаёшь на что нажали
      а далее если нажали 1 то запускается первый код иначе второй

  • @user-xl2tf4gq1g
    @user-xl2tf4gq1g 3 ปีที่แล้ว +1

    а ты этот код взял у автора канала NVitanovic с видео C++ Tutorial 18 - Simple Snake Game

    • @monsoda2834
      @monsoda2834 2 ปีที่แล้ว

      Он просто перевёл то видео...

  • @yulian_13
    @yulian_13 7 ปีที่แล้ว

    подскажите, как запустить visual studio 2017 на 32bit?

  • @denis540103
    @denis540103 6 ปีที่แล้ว

    Доделал Змейку, она у меня двигайться быстро почему и как исправить?

  • @ЖеняЛузанов-с1у
    @ЖеняЛузанов-с1у 6 ปีที่แล้ว

    Один из неприятных недостатков этого кода, то что когда змейка движется в напрвлении и нажимая клавишу обратного направления змейка получается сьедает свой хвост и игра заканчивается, а как это пофиксить?

  • @borisbritva2022
    @borisbritva2022 5 ปีที่แล้ว

    я набрал макс 40. xDDDD
    (попробуй эту дичь на вкус)
    кто наберёт больше тот сверх гений + сверх глаз :
    #include
    #include
    #include
    #include
    #include
    #include
    using namespace std;
    bool GameOver;
    string me = "0";
    int width = 52;
    int height = 20;
    int INTsleep = 50;
    int tailX[100], tailY[100];
    int nTail;
    int x, y, fruitX, fruitY, score;
    enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN };
    eDirection dir;
    void Setup() {
    GameOver = false;
    dir = STOP;
    x = width / 2;
    y = height / 2;
    fruitX = rand() % width;
    if (fruitX % 2 == 1)
    fruitX--;
    fruitY = rand() % height;
    if (fruitY % 2 == 1)
    fruitY--;
    score = 0;
    }
    void Draw() {
    system("cls");//system ("clear");
    cout

  • @remoleg
    @remoleg 3 ปีที่แล้ว

    Извините, что не по теме. Насколько необходима в программировании Булева алгебра?

  • @WarCraf4er
    @WarCraf4er 4 ปีที่แล้ว

    А как скорость изменить? Очень уж хардкорно когда змейка быстро движется

    • @theshellia
      @theshellia 4 ปีที่แล้ว

      в main после всего кода написать Sleep(200(*задержка в мс*))

  • @lance9533
    @lance9533 7 ปีที่แล้ว +9

    там где координаты фрукта задаются в рандоме есть баг.

    • @YuraSamusenko
      @YuraSamusenko 5 ปีที่แล้ว +1

      Это в main в начале надо написать srand(time(0)); написав в самом начале кода
      #include
      #include

    • @YuraSamusenko
      @YuraSamusenko 5 ปีที่แล้ว +1

      Просто *

  • @ВалерийГоловков-ы5ю
    @ВалерийГоловков-ы5ю 7 ปีที่แล้ว

    как сделать чтобы играло два игрока и меню игры с выбором типа игры и с таблицей рекордов

    • @КириллГоловин-э9и
      @КириллГоловин-э9и 7 ปีที่แล้ว

      для двух игроков можно извернуться но лучше все переделать под ооп

  • @Didar.Kussain
    @Didar.Kussain ปีที่แล้ว

    Сколько весит?

  • @mrcron9174
    @mrcron9174 7 ปีที่แล้ว

    Гоша, подскажи пожалуйста, что лучше изучать в добавок к С++ для создания графических приложений.

    • @abursuk
      @abursuk 7 ปีที่แล้ว +1

      qt

    • @mrcron9174
      @mrcron9174 7 ปีที่แล้ว

      Ami00 спасибо, но хотелось бы узнать можно ли с помощью openGL или SFML создавать приложения.

    • @abursuk
      @abursuk 7 ปีที่แล้ว +1

      зависит от типа приложения, что ты хочешь создать. опенгл используют для рендеринга 3д графики. при чем это довольно-таки низкоуровневая либа, которая требует вменени на вникание в нее. в крупных проектах, обычно, на таком низком уровне делают выборочные куски, которые требуют оптимизации в плане производительности. реже пишут весь проект на опенгл (у нас на работе пишут CAD систему в том числе на opengl, к примеру). sfml - это библиотека для отрисовки 2д графики, написана на с++, но есть байндинги и на несколько других языков. с ее помощью часто делают 2д игры. делать там, к примеру, оконное приложение с юзер интерфейсом - так себе занятие. так же в sfml сузествует поддержка opengl, что значит, что ты можешь использовать OPENGL напрямую в окне sfml. ну а qt - он многоцелевой, там есть возможность довольно быстро делать гибкий UI (оконное приложение), есть возможность писать 2д и кажется 3д игры(про 3д кажись читал, но сам дела не имел). но я бы игру на qt игру писать не стал, разве что в учебных целях.

    • @mrcron9174
      @mrcron9174 7 ปีที่แล้ว

      Ami00 спасибо большое)

  • @don1234569
    @don1234569 7 ปีที่แล้ว +1

    а можно скорость змейки менять?

    • @muhammadkurbonov4779
      @muhammadkurbonov4779 2 ปีที่แล้ว

      решил проблему со скоростью?