Код марио, музыка и взаимодействие с врагами



Тут я сразу уже приведу код- после предыдущей главы всё уже должно быть понятным. При этом мы ещё из этого кода научимся как ввести в игру взаимодействие с врагами, а также музыку.

Все необходимые файлы ты можешь скачать тут: https://yadi.sk/d/dj0sHQi63Mm45U

КОД НИЖЕ
#include <SFML/Graphics.hpp>

#include <SFML/Audio.hpp> // библиотека для работы со звуком

using namespace sf;

float offsetX=0, offsetY=0; // смещения карты

 

// сама карта

const int H = 17;

const int W = 150;

String TileMap[H] = {

"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",

"0                                                                                                                                               0",

"0                                                                               w                                                          0",

"0              w                             w              w                                                                    0",

"0                                 w                                  kk                                                               0",

"0                                                                        k k k k                                                    0",

"0                 c                                                 k kkk kkk w                                                0",

"0                                                                  r k  k k                                                    0",

"0                                                                 rr k k                                                              0",

"0                                                                rrr kk                                                               0",

"0          c kckck                                      rrrr                                                                       0",

"0                                 t0                      rrrrr                                                                       0",

"0G                                00         t0     rrrrrr       G                                                          0",

"0      d g  d        00         00    rrrrrrr                                                                       0",

"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",

"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",

"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",

};

 

// класс игрока, всё как в предыдущей игре

class PLAYER {

public:

           float dx,dy;

           FloatRect rect;

           bool onGround;

           Sprite sprite;

           float currentFrame;

 

           // конструктор класса (начальные данные)

  PLAYER(Texture &image) {

                           sprite.setTexture(image);

                           rect = FloatRect(100,180,16,16);

                           dx=dy=0.1;

                           currentFrame = 0;

    }

 

           // перемещение персонажа

    void update(float time) {

                           rect.left += dx * time;   

               Collision(0);

 

                     if (!onGround) dy=dy+0.0005*time;       

                     rect.top += dy*time;

                       onGround=false;

               Collision(1);

               

               currentFrame += time * 0.005;

                  if (currentFrame > 3) currentFrame -= 3;

 

                  if (dx>0) sprite.setTextureRect(IntRect(112+31*int(currentFrame),144,16,16));

                      if (dx<0) sprite.setTextureRect(IntRect(112+31*int(currentFrame)+16,144,-16,16));

 

                     sprite.setPosition(rect.left - offsetX, rect.top - offsetY);

                     dx=0;

           }

               

           // обработка столкновений

           void Collision(int num) {

               

                           for (int i = rect.top/16 ; i<(rect.top+rect.height)/16; i++)

                           for (int j = rect.left/16; j<(rect.left+rect.width)/16; j++) {

                                                            if ((TileMap[i][j]=='P') || (TileMap[i][j]=='k') || (TileMap[i][j]=='0') || (TileMap[i][j]=='r') || (TileMap[i][j]=='t')) {

                                                                                                                                                                                               if (dy>0 && num==1) { rect.top = i*16 - rect.height; dy=0; onGround=true; }

           if (dy<0 && num==1) { rect.top = i*16 + 16; dy=0;}

           if (dx>0 && num==0) { rect.left = j*16 - rect.width; }                                                                                           if (dx<0 && num==0) { rect.left = j*16 +16;}

 }

           if (TileMap[i][j]=='c') { // TileMap[i][j]=' '; }

}

}

};

 

// класс для учёта врага (он похож на класс игрока)

class ENEMY {

public:

           float dx,dy;

           FloatRect rect;

           Sprite sprite;

           float currentFrame;

           bool life; // жив или мёртв

 

           // конструктор (начальные значения)

    void set(Texture &image, int x, int y) {

                           sprite.setTexture(image);

                           rect = FloatRect(x,y,16,16);

                  dx=0.05;

                           currentFrame = 0;

                           life=true;

    }

               

           // простейший интеллект врага- будет двигаться только по иксу, а при столкновении двигаться в обратную сторону

       void update(float time) {           

                     rect.left += dx * time;

               Collision();

 

                  currentFrame += time * 0.005;

               if (currentFrame > 2) currentFrame -= 2;

 

                  sprite.setTextureRect(IntRect(18*int(currentFrame), 0, 16,16));

                  if (!life) sprite.setTextureRect(IntRect(58, 0, 16,16));

                           sprite.setPosition(rect.left - offsetX, rect.top - offsetY);

}

 

    void Collision() {

                           for (int i = rect.top/16 ; i<(rect.top+rect.height)/16; i++)

                                           for (int j = rect.left/16; j<(rect.left+rect.width)/16; j++)

                                                            if ((TileMap[i][j]=='P') || (TileMap[i][j]=='0')) {

                                                          if (dx>0) { rect.left = j*16 - rect.width; dx*=-1; }                                                                                                      else if (dx<0) { rect.left = j*16 + 16; dx*=-1; }

                                                           }

          }

};

 

int main() { 

    RenderWindow window(VideoMode(400, 250), "Mario");

 

           Texture tileSet; tileSet.loadFromFile("Mario_Tileset.png");

 

           PLAYER Mario(tileSet);

           ENEMY enemy;

           enemy.set(tileSet,48*16,13*16);

 

           Sprite tile(tileSet);

           SoundBuffer buffer; // переменная для работы со звуком

           buffer.loadFromFile("Jump.ogg"); // загрузка звука (будет запускаться при прыжке)

           Sound sound(buffer); // помещение в буфер- будем проигрывать только при прыжке (это далее прописывается при нажатии клавиши вверх)

 

  Music music; // фоновая музыка

  music.openFromFile("Mario_Theme.ogg"); // загрузка из файла

  music.play(); // проигрывание музыки

 

           Clock clock;

               

           // главный цикл игры

  while (window.isOpen()) {

                           float time = clock.getElapsedTime().asMicroseconds();

                           clock.restart();

                           time = time/500; // здесь регулируем скорость игры

                           if (time > 20) time = 20;

 

                           Event event;

                           while (window.pollEvent(event)) {

                                      if (event.type == Event::Closed) window.close();

                           }

                               

                           // что происходит при нажатии клавиш

                           if (Keyboard::isKeyPressed(Keyboard::Left)) Mario.dx=-0.1;

             if (Keyboard::isKeyPressed(Keyboard::Right)) Mario.dx=0.1;

             if (Keyboard::isKeyPressed(Keyboard::Up))   if (Mario.onGround) { Mario.dy=-0.27; Mario.onGround=false; sound.play();}

 

                            Mario.update(time);

                            enemy.update(time);

 

                           // пересечение прямоугольников игрока и врага- при пересечении закрасимся красным, а убивание- если мы на врага падаем

                            if (Mario.rect.intersects( enemy.rect ) ) {

                                            if (enemy.life) {

                                                     if (Mario.dy>0) { enemy.dx=0; Mario.dy=-0.2; enemy.life=false;}

                                                     else Mario.sprite.setColor(Color::Red);

                                            }

                            }

                               

                           // задаём какое должно быть смещение карты

                            if (Mario.rect.left>200) offsetX = Mario.rect.left-200;

 

                           // отрисовка карты

                            window.clear(Color(107,140,255));

                            for (int i=0; i<H; i++)

                                            for (int j=0; j<W; j++) {

                                                           if (TileMap[i][j]=='P') tile.setTextureRect( IntRect(143-16*3,112,16,16) );

                                                           if (TileMap[i][j]=='k') tile.setTextureRect( IntRect(143,112,16,16) );

                                          if (TileMap[i][j]=='c') tile.setTextureRect( IntRect(143-16,112,16,16) );

                                                           if (TileMap[i][j]=='t') tile.setTextureRect( IntRect(0,47,32,95-47) );

                                                           if (TileMap[i][j]=='g') tile.setTextureRect( IntRect(0,16*9-5,3*16,16*2+5) );

                                                           if (TileMap[i][j]=='G') tile.setTextureRect( IntRect(145,222,222-145,255-222) );

                                               if (TileMap[i][j]=='d') tile.setTextureRect( IntRect(0,106,74,127-106) );

                                                           if (TileMap[i][j]=='w') tile.setTextureRect( IntRect(99,224,140-99,255-224) );

                                                           if (TileMap[i][j]=='r') tile.setTextureRect( IntRect(143-32,112,16,16) );

                                                           if ((TileMap[i][j]==' ') || (TileMap[i][j]=='0')) continue;

                                            tile.setPosition(j*16-offsetX,i*16 - offsetY) ;

                                                      window.draw(tile);

                           }

                               

                           // накладывание персонажа и врага на уже нарисованную карту

                           window.draw(Mario.sprite);

             window.draw(enemy.sprite);

                               

                           // вывод всего на экран

                           window.display();

}

// завершение программы

return 0;

}

 

Установка OpenGL

OpenGL- это Open Graphic Library или открытая графическая библиотека. В отличие от SFML, это более низкоуровневая и универсальная библиотека графики. Но при этом она более сложная в освоении, на ней нужно писать больше кода. Также она работает с 3d объектами, а SFML поддерживает только 2d, т.е. плоские вещи. Многие современные игры используют OpenGL. Поэтому мы обязательно рассмотрим эту вещь ниже в нескольких главах, начиная с текущей.

Для того чтобы в devcpp использовать OpenGL, не нужно каких-то специальных ухищрений. Заходим создать проект, выбираем вкладку Multimedia и там выбираем тип проекта OpenGL. Всё. Создастся файл со следующим содержанием (это тестовый код)

/**************************

 * Includes

 *

 **************************/

#include <windows.h>

#include <gl/gl.h>

 

/**************************

 * Function Declarations

 *

 **************************/

LRESULT CALLBACK WndProc (HWND hWnd, UINT message,

WPARAM wParam, LPARAM lParam);

void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC);

void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC);

 

/**************************

 * WinMain

 *

 **************************/

int WINAPI WinMain (HINSTANCE hInstance,

               HINSTANCE hPrevInstance,

               LPSTR lpCmdLine,

               int iCmdShow)

{

WNDCLASS wc;

HWND hWnd;

HDC hDC;

HGLRC hRC;       

MSG msg;

BOOL bQuit = FALSE;

float theta = 0.0f;

 

/* register window class */

wc.style = CS_OWNDC;

wc.lpfnWndProc = WndProc;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hInstance = hInstance;

wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);

wc.hCursor = LoadCursor (NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);

wc.lpszMenuName = NULL;

wc.lpszClassName = "GLSample";

RegisterClass (&wc);

 

/* create main window */

hWnd = CreateWindow (

"GLSample", "OpenGL Sample",

WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,

0, 0, 256, 256,

NULL, NULL, hInstance, NULL);

 

/* enable OpenGL for the window */

EnableOpenGL (hWnd, &hDC, &hRC);

 

/* program main loop */

while (!bQuit)

{

   /* check for messages */

   if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))

   {

       /* handle or dispatch messages */

       if (msg.message == WM_QUIT)

       {

           bQuit = TRUE;

       }

       else

       {

           TranslateMessage (&msg);

           DispatchMessage (&msg);

       }

   }

   else

   {

       /* OpenGL animation code goes here */

 

       glClearColor (0.0f, 0.0f, 0.0f, 0.0f);

       glClear (GL_COLOR_BUFFER_BIT);

 

       glPushMatrix ();

       glRotatef (theta, 0.0f, 0.0f, 1.0f);

       glBegin (GL_TRIANGLES);

       glColor3f (1.0f, 0.0f, 0.0f); glVertex2f (0.0f, 1.0f);

       glColor3f (0.0f, 1.0f, 0.0f); glVertex2f (0.87f, -0.5f);

       glColor3f (0.0f, 0.0f, 1.0f); glVertex2f (-0.87f, -0.5f);

       glEnd ();

       glPopMatrix ();

 

       SwapBuffers (hDC);

 

       theta += 1.0f;

       Sleep (1);

   }

}

 

/* shutdown OpenGL */

DisableOpenGL (hWnd, hDC, hRC);

 

/* destroy the window explicitly */

DestroyWindow (hWnd);

 

return msg.wParam;

}

/********************

 * Window Procedure

 *

 ********************/

LRESULT CALLBACK WndProc (HWND hWnd, UINT message,

                     WPARAM wParam, LPARAM lParam)

{

 

switch (message)

{

case WM_CREATE:

   return 0;

case WM_CLOSE:

   PostQuitMessage (0);

   return 0;

 

case WM_DESTROY:

   return 0;

 

case WM_KEYDOWN:

   switch (wParam)

   {

   case VK_ESCAPE:

       PostQuitMessage(0);

       return 0;

   }

   return 0;

 

default:

   return DefWindowProc (hWnd, message, wParam, lParam);

}

}

/*******************

 * Enable OpenGL

 *

 *******************/

 

void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC)

{

PIXELFORMATDESCRIPTOR pfd;

int iFormat;

 

/* get the device context (DC) */

*hDC = GetDC (hWnd);

 

/* set the pixel format for the DC */

ZeroMemory (&pfd, sizeof (pfd));

pfd.nSize = sizeof (pfd);

pfd.nVersion = 1;

pfd.dwFlags = PFD_DRAW_TO_WINDOW |

PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;

pfd.iPixelType = PFD_TYPE_RGBA;

pfd.cColorBits = 24;

pfd.cDepthBits = 16;

pfd.iLayerType = PFD_MAIN_PLANE;

iFormat = ChoosePixelFormat (*hDC, &pfd);

SetPixelFormat (*hDC, iFormat, &pfd);

 

/* create and enable the render context (RC) */

*hRC = wglCreateContext( *hDC );

wglMakeCurrent( *hDC, *hRC );

 

}

/******************

 * Disable OpenGL

 *

 ******************/

void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)

{

wglMakeCurrent (NULL, NULL);

 wglDeleteContext (hRC);

ReleaseDC (hWnd, hDC);

}

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

Рисование в OpenGL

Научимся теперь делать рисовать простые плоские статичные фигуры. Для этого нам нужно найти код:

 

       /* OpenGL animation code goes here */

 

       glClearColor (0.0f, 0.0f, 0.0f, 0.0f);

       glClear (GL_COLOR_BUFFER_BIT);

 

       glPushMatrix ();

       glRotatef (theta, 0.0f, 0.0f, 1.0f);

       glBegin (GL_TRIANGLES);

       glColor3f (1.0f, 0.0f, 0.0f); glVertex2f (0.0f, 1.0f);

       glColor3f (0.0f, 1.0f, 0.0f); glVertex2f (0.87f, -0.5f);

          glColor3f (0.0f, 0.0f, 1.0f); glVertex2f (-0.87f, -0.5f);

       glEnd ();

       glPopMatrix ();

 

       SwapBuffers (hDC);

 

       theta += 1.0f;

       Sleep (1);

 

В нём мы убираем theta и sleep (задержку) в конце, далее убираем glRotatef- т.е. вращаться ничего не будет. В начале объявление theta тоже можно убрать (float theta = 0.0f; вот эту строку)

Остаётся вот такой сырой код:

       glClearColor (0.0f, 0.0f, 0.0f, 0.0f);

       glClear (GL_COLOR_BUFFER_BIT);

 

       glPushMatrix ();

       glRotatef (theta, 0.0f, 0.0f, 1.0f);

       glBegin (GL_TRIANGLES);

           // здесь будет рисование

       glEnd ();

       glPopMatrix ();

 

       SwapBuffers (hDC);

Первая строчка glClearColor отвечает за заливаемый фон. Цвета тут устроены по системе RGB- Red Green Blue или красный зелёный голубой. Нули дают нам чёрный цвет (отсутствие), а единицы- белый (смешение всех цветов). Используя эти 3 параметра в разных комбинациях, мы получаем разные цвета. Чтобы найти нужный цвет, нужно узнать его код в RGB (интернет и всякие пипетки в помощь)- например в 24-битной это выглядит так (по 8 бит или 256 кодов на каждый компонент) - 97, 126, 28. Теперь нам нужно это в долях выразить и записать: 97/255, 126/255, 28/255. Если код указан в 16-ричной системе счисления типа 9FA235, то нужно разбить по 2 цифры: 9F A2 35 и далее перевести в десятичную систему: 9*16+15, 10*16+2, 3*16+5 и опять выразить это в долях, можно даже самому не считать, а прям так выражениями и записывать. Т.е. аргументы будут такие: (9*16+15)/255, (10*16+2)/255, (3*16+5)/255. Можно даже изощриться и написать функции, которые тебе будут переводить из одного формата в другой, их для удобства можно писать даже в отдельном заголовочном файле.

Вторая строчка чистит экран, её мы не трогаем.

Далее- всё рисуемое заключается между glPushMatrix и glPopMatrix, это мы тоже не трогаем.

glBegin (GL_TRIANGLES); // здесь мы указываем- что именно будем рисовать. У нас указано по умолчанию GL_TRIANGLES, это значит что будет треугольник- он рисуется по 3 точкам.

Сначала научимся ставить точку. Чтобы ставить чисто точки, надо поменять GL_TRIANGLES на GL_POINTS. И далее до glEnd мы эти точки сколько нам надо ставим.

Для постановки точки мы указываем 2 вещи- цвет точки и её позицию. Сначала цвет, потом позиция.

glColor3f (0,1,0); glVertex2f (0,0);

 Здесь у нас будет зелёная точка в позиции 0,0. Это значит центр координат, он у нас находится в центре графического окошка. Единица- это края окна. Как в декартовой системе. Например, -1,1 это будет влево по горизонтали до конца (-1) и вверх по вертикали до конца (1), т.е. левый верхний угол. Если мы поставим 0.5, то это будет посередине от центра до края. Т.е. положение точки тоже выражается в долях, как мы это делаем с цветами.

Чтобы поставить линию, нам нужно в glBegin указать GL_LINES. И отрезок ставится по 2 точкам. Например, если нам нужен чёрный отрезок с левого нижнего угла (но не впритык, а близко к нему) до правого верхнего, можно сделать так:

glColor3f (0,0,0); glVertex2f (-0.9,-0.8);

glColor3f (0,0,0); glVertex2f (0.9,0.8);

Можно поставить ещё одну линию, написав дальше код ещё 2 следующих точек, по которым построится вторая линия.

Если мы поставим цвета 2 точек, по которым строится линия, разными, то цвет будет в виде градиента- переливаться с одного до другого.

Аналогично мы можем треугольник сделать по 3 точкам.

Размер окна можно поменять вот в этой строчке: WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,

0, 0, 256, 256,

Только вместо последних 256 поставить свои размеры. Причём один и тот же код работает для разных размеров, т.к. позиции указываются в долях- т.е. просто будет меняться масштаб фигуры в соответствии с размерами окна.

Для построения непрерывных графиков используем:

glBegin (GL_LINE_LOOP);

Тут конечная точка предыдущей линии будет начальной линией следующей.

Например, вот так мы можем нарисовать окружность на весь экран:

for(double a=0; a < 2*M_PI; a+=0.01) glVertex2f (cos(a),sin(a));

Главное не забыть подключить cmath для синуса и косинуса. Окружность рисуется по принципам полярных координат. M_PI это чисто пи, константа, она прописана в том же cmath.

Чтобы сплющить окружность в эллипс по горизонтали, мы домножаем синус на небольшой коэффициент, например 1.3. Если мы будем прибавлять или отнимать что-то с синусом, то круг будет двигаться вверх или вниз. Если же мы уже аргумент будем менять, то тут интереснее: если прибавить единицу к аргументу, то круг как бы наклонится на 45 градусов. Откуда именно так, полагаю что это из-за того что тангенс 45 градусов равен единице. Ты можешь со всем этим поэкспериментировать.

Ты можешь открыть справочник по высшей математике и посмотреть параметрически заданные графики- и далее реализовать их в OpenGL по полярной системе координат.

Вот этот код нарисует красивый листик конопли:

for(double a=0; a < 2*M_PI; a+=0.01) {

           double r= 0.3*(1+sin(a))*(1+0.9*cos(8*a))*(1+0.1*cos(24*a));

           glVertex2f (r*cos(a),r*sin(a)-0.5);

}

________________________________________________

РАЗДЕЛ 5

ПОЛЕЗНЫЕ ДОПОЛНЕНИЯ

 

Вектор

Мы привыкли использовать массивы, но в с++ также есть добавленный шаблон класса, упрощающий работу с массивами- вектор. Фундаментально он разработан на основе массивов, но программисту не нужно вникать как он работает- он может просто спокойно использовать то что за него уже сделали более продвинутые и профессиональные разработчики.

Для работы с векторами нам нужно подключить соответствующую библиотеку:

#include <vector>

Создаётся вектор так же, как мы делали со стеком или очередью- это шаблон класса, поэтому нужно указывать тип, например: vector <int> x;

Инициализация такого типа: vector <int> v= {1,2,3,4,5}; у меня в devcpp не работала- говорят что нужна версия с++ 11.

Можно инициализировать так:

vector <int> v(3);

v[0]=5; v[1]=7; v[2]=8; cout << v[1] << endl;

Можно работать с векторами как с обычными массивами, но тут есть ряд расширений функционала, сейчас посмотрим ниже.

1. Сравнение векторов- происходит как сравнение обычных переменных:

vector <int> a(3), b(3);

for (int i=0; i<3; i++) {

           a[i]= i*i; b[i]= i*i;

}

if (a==b) cout << "Равны" << endl;

2. Размер вектора: cout << a.size() << endl; // для нашего вектора выведет 3

Можно использовать в цикле:

for (int i=0; i<a.size(); i++) делать что-то там

3. Узнать, пустой ли вектор: a.empty() - логический метод.

4. Добавление элемента в конец вектора:

vector <int> a(3);

for (int i=0; i<a.size(); i++) a[i]= (i+1)*(i+2);

a.push_back(19);

И теперь уже можно выводить элемент a[3], он создался благодаря методу push_back. Также изменился размер вектора, теперь он равен 4.

5. Удаление последней ячейки: a.pop_back(); т.е. это уже наоборот- удалить то что мы только сейчас создали. Теперь размер вектора снова равен 3, но при этом a[3] всё так же доступен и можно вывести, будет 19. Можно обнулить так: a[3]= NULL;

Функции добавления и удаления можно использовать в цикле.

6. Вставка элемента в начало вектора:

a.insert(a.begin(),18);

И можно всё вывести: for (int i=0; i<a.size(); i++) cout << a[i] << " "; // 18 2 6 12 19

А такая команда аналогична push_back: a.insert(a.end(),18);

Стоит помнить, что добавление элементов в начало замедляет программу, поэтому стараемся добавлять только в конец.

7. Значение первой ячейки: a.front(); Последней- a.back();

8. Как создать вектор векторов:

vector < vector <int> > a;

Т.е. мы создали вектор из векторов типа int.

Если у нас есть некоторый вектор x, т.е. мы можем добавить его в наш вектор векторов:

a.push_back ( vector<int>(x));

Пусть у меня: vector <int> x; x.push_back(3); x.push_back(8);

Можно выводить элементы как у двумерного массива: cout << a[0][1] << endl; // выведет 8

Отсюда следует, что можно создавать "неровные" двумерные массивы благодаря векторам, т.е. у нас будет вектор из векторов разного размера. И это будет нормально восприниматься программой. Ниже пример из вектора 2 векторов, где у первого 2 элемента, а у второго 1:

vector <int> x; x.push_back(3); x.push_back(8);

vector <int> y; y.push_back(6);

vector < vector <int> > a;

a.push_back ( vector<int>(x));

a.push_back ( vector<int>(y));

Под размером вектора векторов будет выводиться количество векторов, что в принципе логично- просто это стоило пояснить. На этом мы закончим данную главу.

 


Дата добавления: 2018-09-22; просмотров: 235; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!