Курсовая работа по основам программирования. Игра Паровоз


                Государственный комитет Российской Федерации
                           по высшему образованию

              Казанский государственный технический университет
                             имени А.Н. Туполева
       --------------------------------------------------------------
                                Кафедра АСОИУ



                               КУРСОВАЯ РАБОТА

                         по основам программирования

                               ИГРА «Parovoz»



                                          ИСПОЛНИТЕЛЬ: студентка группы 4221
                                                                Петрова Е.Г.
                                                    РУКОВОДИТЕЛЬ: Вафин Р.Р.



                                          Оценка____________________________

                                          Подпись___________________________

                                        "____"________________________2001г.



                                   КАЗАНЬ
                                   2001г.

                                 СОДЕРЖАНИЕ



1.Описание применения .      3

  1.1. Запуск программы.     3

  1.2. Правила игры.   3

2. Описание программы .      4

  2.1. Метод решения задачи .      4

  2.2. Описание используемых классов, структур и функций.      4
   2.2.1. CApp - класс приложения .     4
   2.2.2. CМainWnd- класс главного окна .    4
   2.2.3. Карта сообщений.  5

2.3. Образ главного окна.    6

Приложение  7

  Листинг файла main.cpp     7

  Листинг файла main.h 12

  Листинг файла menu1.h      13

  Листинг файла menu1.rc     13

                           1.Описание применения .


1.1. Запуск программы.


      Запуск программы необходимо производить , находясь в среде Windows 95
: запускаемый файл – parovoz.exe .


1.2. Правила игры.


      После запуска игры, на экране появляется  окно  с  надписью  «выберите
пункт старт». Окно имеет меню, состоящее из нескольких  пунктов.  С  помощью
пунктов  меню  можно:  изменять  цвет  движущегося  объекта  (паровозика   в
красный, синий,  зелёный),  начать  (перезапустить),  осуществить  выход  из
игры. После выбора пункта меню «старт», в левом нижнем углу окна  появляется
паровоз, представляющий собой совокупность геометрических фигур  –  эллипсов
(колёса) и прямоугольников (кабина, трубы). Паровоз движется  слева  направо
и останавливается перед светофором, расположенным приблизительно в  середине
окна над  паровозом.  Пользователь  имеет  возможность  регулировать  цветом
светофора нажатием клавишь ‘к’, ‘з’, ‘ж’, соответствующим  цветам  светофора
– красному, зеленому, жёлтому. Если паровоз  подъезжает  к  светофору,  а  у
светофора активным является зелёный цвет, он  продолжает  своё  движение.  В
противном случае, паровоз останавливается.  При  достижении  правой  стенки,
паровоз появляется у левой стенки, а активным  цветом  светофора  становится
жёлтый цвет. Из верхней  части  паровоза  постоянно  поднимаются  в  верхнюю
часть  окна  окружности,   представляющие   собой   клубни   дыма,   которые
увеличиваются при подъёме.


                           2. Описание программы .



2.1. Метод решения задачи .


         Программа    выполнена    в    стиле     объектно-ориентированного
 программирования,  использованна  библиотека   MFC.   Сама   программа   -
 приложение Windows. Для вывода графических объектов используются  функции:
 Elliplse, Rectangle. Программой обрабатываются события от таймера, нажатия
 клавишь на клавиатуре, выбра соответствующих пунктов меню, а также событие
 WM_PAINT для перерисовки рабочей области.


2.2. Описание используемых классов, структур и функций.



2.2.1. CApp - класс приложения .


      CApp - класс приложения,  порождается классом CWinApp  библиотеки  MFC
обеспечивает инициализацию , выполнение и  завершение  Windows  программы  :
регистрирует , создаёт и отображает основное окно приложения .
Член- функции класса CApp :
InitInstance – виртуальная функция, переопределяется в классе CApp



2.2.2. CМainWnd- класс главного окна .


CMainWnd  -  класс  главного  окна  приложения  ,  наследуется  из    класса
CFrameWnd библиотеки MFC .)

Член - данные класса СMainWnd :
CRect wnd;  /*размер окна*/
            CRect kol1,kol2,korp,kr,temp; /*прямоугольники*/
            CRect svet,ball1,ball2,ball3;/*прямоугольники*/
            CBrush br1[3],br2;          /*кисти*/
            CBrush sv[4];               /*цвета светофора*/
            CRect noga;                 /*нога светофора*/
            CRect balls[5];       /*шарики дыма*/
            CRect kr2;       //кабина
            int numball;          //номер дыма
            int live[5];          //признак жизни дыма
            bool game; /*признак игры или вне игры*/
            int color; /*номер цвета паровоза*/
            int ns;          /*номер увета светофора*/
            int move;  /*флаг движения паровоза*
/Член - функции класса СMainWnd :
      CmainWnd();      -     конструктор класса окна
            afx_msg void OnBegin();обработчик события на выбор пункта меню
«старт»
      afx_msg void OnRed();  -     обработчик события на выбор пункта меню
«Red»
            afx_msg void OnGreen();     -     обработчик события на выбор
пункта меню «Green»
            afx_msg void OnBlue(); -    обработчик события на выбор пункта
меню «Blue»
      afx_msg void OnPaint();     -     ф-ия перерисовки
      afx_msg void OnTimer( UINT nIDEvent );       -     обраб-чик таймера
            afx_msg void OnExit(); -    обработчик события на выбор пункта
меню «Exit»
      afx_msg void OnChar( UINT nChar, UINT nRepCnt, UINT nFlags ); -
реакция на нажатие клавиши клавиатуры
      DECLARE_MESSAGE_MAP()  -    карта сообщений


2.2.3. Карта сообщений.


BEGIN_MESSAGE_MAP(CMainWnd,CFrameWnd)
      ON_COMMAND(IDM_EXIT,OnExit)
      ON_COMMAND(IDM_BEGIN,OnBegin)
      ON_COMMAND(IDM_RED,OnRed)
      ON_COMMAND(IDM_GREEN,OnGreen)
      ON_COMMAND(IDM_BLUE,OnBlue)
      ON_WM_PAINT()
      ON_WM_TIMER()
      ON_WM_CHAR()
END_MESSAGE_MAP()


2.3. Образ главного окна.


На рисунках 1, 2 представленыосновные образы окна приложения.



                                 Приложение



Листинг файла main.cpp


/* в этом файле находятся описания всех функций */

#include 
#include "main.h"
#include "menu1.h"

CMainWnd::CMainWnd()   /*конструктор гл. окна*/
{
      wnd.SetRect(0,0,400,355);//устан-ка размеров окна
      Create(NULL,"parovoz",WS_DLGFRAME   ,wnd,NULL,"MAINMENU");
      game=false;            /*нет игры*/
      color=0;         /*нач. цвет поезда*/
      ns=0;            /*нач. цвет светофора*/
      br1[0].CreateSolidBrush(RGB(255,0,0));//создание кистей
      br1[1].CreateSolidBrush(RGB(0,255,0));
      br1[2].CreateSolidBrush(RGB(0,0,255));

      sv[0].CreateSolidBrush(RGB(255,0,0));//создание кистей
      sv[1].CreateSolidBrush(RGB(0,255,0));//светофора
      sv[2].CreateSolidBrush(RGB(255,255,0));
      sv[3].CreateSolidBrush(RGB(128,128,128));

      br2.CreateSolidBrush(RGB(1,1,1));/*чёрный цвет*/

      for(numball=0;numball<5;numball++)
      {//обнуление признаков жизни дыма
            live[numball]=0;
      }

}

BOOL CApp:: InitInstance()/*ф-ия инициализации окна*/
{
      m_pMainWnd=new CMainWnd;    /*созд объекта окна*/
      m_pMainWnd->ShowWindow(m_nCmdShow);    /*показать окно*/
      return true;     /*удачное завершение*/
}

afx_msg void CMainWnd::OnPaint()  /*ф-ия перерисовки*/
{
      CPaintDC dc(this);     /*созданиее контекста окна*/
      dc.SelectObject(&br2); /*выбор кисти для светофора*/
      dc.Rectangle(svet);    //рисование корп. светофора
      dc.Rectangle(noga);    //рисование ноги
      for(numball=0;numball<5;numball++)
      {//рисование дыма
            if(live[numball]==1)//если дым активен
            {
                 dc.Ellipse(balls[numball]);
            }
      }
      switch(ns) /*переключение между цветами светофора*/
      {
            case 0:    /*если красный*/
                 {
                       dc.SelectObject(sv[0]);
                       dc.Ellipse(ball1);
                       dc.SelectObject(sv[3]);
                       dc.Ellipse(ball2);
                       dc.Ellipse(ball3);
                       break;
                 }
            case 1:    /*если жёлтый*/
                 {
                       dc.SelectObject(sv[2]);
                       dc.Ellipse(ball2);
                       dc.SelectObject(sv[3]);
                       dc.Ellipse(ball1);
                       dc.Ellipse(ball3);
                       break;
                 }
            case 2:/*еесли зеленый*/
                 {
                       dc.SelectObject(sv[1]);
                       dc.Ellipse(ball3);
                       dc.SelectObject(sv[3]);
                       dc.Ellipse(ball1);
                       dc.Ellipse(ball2);
                       break;
                 }
      }
      dc.SelectObject(br1[color]);      /*рисование паровоза*/
      dc.Rectangle(korp);               //корпус
      dc.SelectObject(&br2);
      dc.Rectangle(kr);           //труба
      dc.Rectangle(kr2);          //кабина
      dc.Ellipse(kol1);      //колеса
      dc.Ellipse(kol2);
      char *s="выберете меню старт.";//начальная надпись
      if(game==0) dc.TextOut(50,100,s,strlen(s));
}

void CMainWnd::OnExit()      /*реакция на выход*/
{
      SendMessage(WM_CLOSE); /*послать сообщение о закрытии окна*/
}

afx_msg void CMainWnd::OnTimer( UINT nIDEvent )
{/*обработчик таймера*/
      if(game)   /*если находимся в игре*/
      {
            if(nIDEvent==2)//запуск дыма
            {
                 for(numball=0;numball<5;numball++)
                 {//если дым не активен, активизировать
                       if(live[numball]==0)
                       {
                             live[numball]=1;
                             balls[numball].SetRect(korp.left+35,kr.top-
10,kr.right-5,korp.top);
                             break;
                       }
                 }
            }
            for(numball=0;numball<5;numball++)
            {//сохранить предыдущ. положение дыма
                 temp.CopyRect(balls[numball]);
                 if(live[numball]==1)//если дым активен
                 {
                       balls[numball].OffsetRect(1,-6);//сместить дым
                       balls[numball].top--; //изменить размеры
                       balls[numball].right++;
                       InvalidateRect(temp); //перерисовать
                       InvalidateRect(balls[numball]);
                       if(balls[numball].top<=0) live[numball]=0;//убить
                 }
            }
            if(
(korp.right<=svet.left)||(korp.left>=svet.left+3)||(move==1))
            {    /*если не около светофора или зеленый цвет*/

                 if(korp.left<400)/*если не стена*/
                 {
                 temp.CopyRect(korp);   /*сохранить предыдущие координаты*/
            //сместить всю машину
                 korp.OffsetRect(3,0);
                 InvalidateRect(temp);
                 InvalidateRect(korp);
                 temp.CopyRect(kol1);
                 kol1.OffsetRect(3,0);
                 InvalidateRect(temp);
                 InvalidateRect(kol1);

                 temp.CopyRect(kol2);
                 kol2.OffsetRect(3,0);
                 InvalidateRect(temp);
                 InvalidateRect(kol2);

                 temp.CopyRect(kr);
                 kr.OffsetRect(3,0);
                 InvalidateRect(temp);
                 InvalidateRect(kr);
                 temp.CopyRect(kr2);
                 if(kr2.top==270)
                 {
                       kr2.top=275;
                 }
                 else kr2.top=270;
                 kr2.OffsetRect(3,0);
                 InvalidateRect(temp);
                 InvalidateRect(kr2);
                 }
                 else/*возврат в левую стенку*/
                 {
                       korp.SetRect(0,288,50,300);
                       kr.SetRect(30,280,40,288);
                       kr2.SetRect(10,270,25,288);
                       kol1.SetRect(5,295,15,305);
                       kol2.SetRect(35,295,45,305);
                       ns=1;
                       move=0;
                       InvalidateRect(ball1);
                       InvalidateRect(ball2);
                       InvalidateRect(ball3);
                 }
            }

      }

}

afx_msg void CMainWnd::OnRed()
{/*реакция на выбор красного цвета*/
      color=0;
}
afx_msg void CMainWnd::OnGreen()
{/*выбор зеленого цвета*/
      color=1;
}
afx_msg void CMainWnd::OnBlue()
{
      color=2;
}


afx_msg void CMainWnd::OnBegin()
{
      game=true;
      color=0;
      move=0;
      svet.SetRect(200,100,240,230);
      noga.SetRect(210,230,230,250);
      ball1.SetRect(210,110,230,140);
      ball2.SetRect(210,150,230,180);
      ball3.SetRect(210,190,230,220);
      korp.SetRect(0,288,50,300);
      kr.SetRect(30,280,40,288);
      kr2.SetRect(10,270,25,288);
      kol1.SetRect(5,295,15,305);
      kol2.SetRect(35,295,45,305);
      SetTimer(1,100,NULL);
      SetTimer(2,1000,NULL);
      InvalidateRect(NULL);
}



BEGIN_MESSAGE_MAP(CMainWnd,CFrameWnd)
      ON_COMMAND(IDM_EXIT,OnExit)
      ON_COMMAND(IDM_BEGIN,OnBegin)
      ON_COMMAND(IDM_RED,OnRed)
      ON_COMMAND(IDM_GREEN,OnGreen)
      ON_COMMAND(IDM_BLUE,OnBlue)
      ON_WM_PAINT()
      ON_WM_TIMER()
      ON_WM_CHAR()
END_MESSAGE_MAP()

afx_msg void CMainWnd::OnChar( UINT nChar, UINT nRepCnt, UINT nFlags )
{
      if(game)
      {
            switch(nChar)
            {
                 case 234:
                       {
                       ns=0;
                       break;
                       }
                 case 231:
                       {ns=2;
                             move=1;
                       break;
                       }
                 case 230:
                       {ns=1;
                       }
            }
            InvalidateRect(ball1);
            InvalidateRect(ball2);
            InvalidateRect(ball3);

      }
}

CApp app;


Листинг файла main.h


class CMainWnd: public CFrameWnd  /*класс окна*/
{
      public:
            CRect wnd; /*размер окна*/
            CRect kol1,kol2,korp,kr,temp; /*прямоугольники*/
            CRect svet,ball1,ball2,ball3;/*прямоугольники*/
            CBrush br1[3],br2;          /*кисти*/
            CBrush sv[4];               /*цвета светофора*/
            CRect noga;           /*нога светофора*/
            CRect balls[5];       /*шарики дыма*/
            CRect kr2;       //кабина
            int numball;          //номер дыма
            int live[5];          //признак жизни дыма
            bool game; /*признак игры или вне игры*/
            int color; /*номер цвета паровоза*/
            int ns;          /*номер увета светофора*/
            int move;  /*флаг движения паровоза*/
            CMainWnd();      /*конструктор главного. окна*/
            afx_msg void OnRed(); /*пунуты меню цвета*/
            afx_msg void OnGreen();
            afx_msg void OnBlue();
            afx_msg void OnPaint();     /*ф-ия перерисовки*/
            afx_msg void OnTimer( UINT nIDEvent ); /*обраб-чик таймера*/
            afx_msg void OnExit();//выход
            afx_msg void OnBegin();//перестартовать
            afx_msg void OnChar( UINT nChar, UINT nRepCnt, UINT nFlags );
            DECLARE_MESSAGE_MAP()//карта сообщений
};

class CApp: public CWinApp
{
      public:
            BOOL InitInstance();
};


Листинг файла menu1.h


#define     IDM_BEGIN  100
#define     IDM_RED    101
#define     IDM_GREEN 102
#define     IDM_BLUE   103
#define     IDM_EXIT   104



Листинг файла menu1.rc


#include 
#include "menu1.h"

MAINMENU MENU DISCARDABLE
BEGIN
    POPUP "GAME"
    BEGIN
        POPUP  "COLOR"
      BEGIN
            MENUITEM   "RED",           IDM_RED
            MENUITEM   "GREEN",   IDM_GREEN
            MENUITEM   "BLUE",          IDM_BLUE
      END
        MENUITEM SEPARATOR
      MENUITEM   "START",    IDM_BEGIN
        MENUITEM       "EXIT",         IDM_EXIT
    END
END
-----------------------
Рис. 1. Главное окно после выбора пункта «старт»

Рис. 2. Главное окно до выбора пункта «старт»