12. Структуры

Занятие 12


Это надо знать

На прошлом занятии мы рассматривали пример с движением двух шариков, при этом использовали переменные х1, у1, vx1, vу1 и х2, у2, vx2, vу2. Если шарика будет три, то количество переменных увеличится на 4: х3, у3, vx3, vу3, и каждый новый шарик будет увеличивать количество используемых переменных. А если еще добавить разные радиусы и цвет для каждого шарика, ускорения, то это повлечет увеличение количества переменных на четыре для каждого шарика. Да и  функции DrawBall  и Physics  потребуют написания большего количества параметров.

Вызов функций будет следующим:

     DrawBall (x1, y1, r1, color1); 
     DrawBall (x2, y2, r2, color2); 

     Physics (&x1,  &y1,  &vx1,  &vy1,  &ax1,  &ay2,  dt);
     Physics (&x2,  &y2,  &vx2,  &vy2,  &ax2,  &ay2,  dt);

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

Например, так:

     DrawBall (ball1); 
     DrawBall (ball2); 

     Physics (&ball1,  dt);
     Physics (&ball2,  dt);

Где ball1 и ball2 - переменные, которые хранят в себе весь набор значений для 1-го и 2-го шариков соответственно.

Структура - тип данных, который может хранить элементы разных типов.

Структура - это определяемый пользователем тип с объявлением, описывающим свойства данного типа.
Например, опишем структуру шарика, который имеет координаты, скорости, размер и цвет. Назовем структуру Ball.

    struct Subject
         {
         double x, y;
         double vx, vy;
         double r;
         COLORREF color;
         };

В программе структура описывается до прототипов!!!

После определения структуры можно создавать переменные этого типа:

    Subject  ball1, ball2;

Для доступа к отдельным членам структуры необходимо указать название структурной переменной, поставить точку и указать имя члена структуры.

Например,

    ball2.x         = 125;
    ball2.y         = 600;
    ball2.vx       = 2;
    ball2.vy       = 5;
    ball2.r         = 15;
    ball2.color  = TX_RED;

Задать начальные значения структурной переменной можно и следующим образом:
    Subject ball1 = { 100,  100,  5,  7,  20,  TX_BLUE };     

 // перечисляем значения переменных в том же порядке, как они записаны в структуре, т.е. х = 100, у = 100, vx = 5, vy = 7, r = 20, color = TX_BLUE.

Напишем программу для движения пяти шариков.

В функции MoveBall зададим начальные значения для каждого шарика:

    Subject  ball1 = { 100,  100,  5,  7,  20,  TX_BLUE }; 
    Subject  ball2 = {   10,  150,  3,  2,  10,  TX_RED };   
    Subject  ball3 = { 150,  300,  2,  3,   5,  TX_GREEN };  
    Subject  ball4 = { 450,  500,  7,  9,  15,  RGB (210,  40, 200) }; 
    Subject  ball5 = { 500,  400,  1,  3,  25,  RGB ( 20, 230, 220) }; 

Вызовем функцию рисования шарика 5 раз:
    DrawBall (ball1); 
    DrawBall (ball2); 
    DrawBall (ball3); 
    DrawBall (ball4); 
    DrawBall (ball5); 

Пять раз вызовем функцию, которая отвечает за движение шарика:
    Physics (&ball1,  dt);
    Physics (&ball2,  dt);
    Physics (&ball3,  dt);
    Physics (&ball4,  dt);
    Physics (&ball5,  dt);

Учитывая использование нового типа данных функция  DrawBall  будет переписана следующим образом:

   void DrawBall (Subject  ball)
         {
         txSetColor (TX_BLACK);
         txSetFillColor (ball.color);
         txCircle (ball.x,  ball.y,  ball.r);
         }


Рассмотрим, как будет выглядеть запись  *x = *x + *vx*dt;, если мы используем структуру Subject:

    (*ball).x = (*ball).x + (*ball).vx * dt;

Такую запись можно заменить на:

     ball->x = ball->x + ball->vx * dt;

Функция Physics будет записана следующим образом:

  void Physics (Subject*  ball,  double dt)
      {
     ball->x = ball->x + ball->vx * dt;
     ball->y = ball->y + ball->vy * dt;

      if (ball->x > 600 - ball->r)
         {
          ball->vx = - ball->vx;
          ball->x   = 600 - ball->r;
          }

      if (ball->x < 0 + ball->r)
          {
          ball->vx = - ball->vx;
          ball->x   = 0 + ball->r;
          }

     if (ball->y < 0 + ball->r)
          {
          ball->vy = - ball->vy;
          ball->y   = 0 + ball->r;
          }

      if (ball->y > 400 - ball->r)
          {
          ball->vy = - ball->vy;
          ball->y   = 400 - ball->r;
          }
      }






 Пример 


 Создать движение пяти лягушек.

Создадим структуру, которая описывает параметры лягушки:

struct Subject
    {
    double x, y;
    double vx, vy;

    double sizeX, sizeY;
    COLORREF color;
    };

Вместо функции рисования шарика будем использовать функцию рисования лягушки.

Посмотреть текст программы

Результат выполнения программы


Домашнее задание

Создать структуру, которая содержит параметры вашего героя. Написать программу, которая осуществляет движение нескольких героев (использовать структуру).