Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсовая работа Мельников УК-02.docx
Скачиваний:
0
Добавлен:
23.12.2018
Размер:
715.01 Кб
Скачать

Список використаних джерел

  1. Бьерн Страуструп. Язык программирования С++.[Текст] Специальное издание - «Бином», ISBN 5-7989-0226-2, 5-7940-0064-3, 0-201-70073-5; 2008 г – 1054 с.

  2. Уроки по opengl от NeHe. [Електронний ресурс]. Режим доступу: http://pmg.org.ru/nehe/

  3. Электронное пособие по С++ . [Електронний ресурс]. Режим доступу: http://valera.asf.ru/cpp/book/

  4. Центр разработки на Visual C++. [Електронний ресурс]. Режим доступу: http://msdn.microsoft.com/ru-ru/

Додаток а

Зміст файлу classes.h:

#include <gl\glut.h> //основная библиотека opengl

#include <glaux.h>

#pragma comment(lib, "glaux.lib") //библиотека требуемая для отрисовки битмапа

#include <time.h>

#include <Windows.h>

#include <iostream>

using namespace std;

const float pi=3.141592653589793238;

float bs=2; //BLOCKSIZE

const float wheight=500, wwidth=500; //WINDOW SIZE

const float ortho=50; //размер окна

const int roadwidth=30, exrand=roadwidth-bs*6; //левая и правая стенки

const int wallwidth=10; //ширина стенки 5 блоков 5*2=10

const int playercolor=8; //цвет машинки игрока

bool crashblink=false, goblink=true;

float foncolor[3]={0.5, 0.5, 1}; //цвет фона

int car_i=0, go_i=0; //перменные требуемые для моргания при аварии

//----------------CLASSES------------------------------

class Tshape

{

public:

float x, y;

int color;

void switch_color(int scolor) //метод смены цвета

{

switch(scolor)

{

case -2: glColor3f(0.19215686, 0.60784314, 0.8705882); break; //фон меню голубой

case -1: glColor3f(0.5, 0.5, 1); break; //лиловый ФОН

case 0: glColor3f(0,0,0); break; //черный

case 1: glColor3f(1,0,0); break; //красный

case 2: glColor3f(0,1,0); break; //зеленый

case 3: glColor3f(0,0,1); break; //синий

case 7: glColor3f(1,1,0); break; //желтый

case 8: glColor3f(1,0.5,0); break; //оранжевый

case 9: glColor3f(0.5,0.25,0); break; //коричневый

case 21: glColor3f(0,0.2,0); break; //темно-зеленый

}

}

};

class Tblock: virtual public Tshape //квадратик

{

public:

void block(); // рисуем квадратик

};

class car: public Tblock //машинка

{

public:

float cx, cy, ccolor;

bool crash, godmode;

car(float, float, int, bool, bool); //отрисовует машинку

~car(void); //закрашивает машинку

//void car();

};

class grass: public Tblock

{

public:

float gwidth, gm;

grass(float, float);

~grass (void);

};

class wall: public Tblock

{

public:

float wy;

float wx;

int wpos;

int wcolor;

wall(float, int, int);

~wall(void);

};

class game_over: public Tblock

{

public:

float gox, goy;

int ocolor;

game_over(float, float, int);

~game_over(void) {};

};

class text: virtual public Tshape

{

public:

const char* itext;

void drawtext(const char*, int, float, float);

void hidetext();

};

class Tmenu: public Tblock, public text

{

public:

bool selection;

void show();

void draw_select(bool);

};

//------------------FUNCTIONS---------------------

void Tblock::block()

{

switch_color(color);

glBegin(GL_QUADS);

glVertex2f(x-bs/2, y+bs/2);

glVertex2f(x-bs/2, y-bs/2); //рисует прямоугольник

glVertex2f(x+bs/2, y-bs/2);

glVertex2f(x+bs/2, y+bs/2);

glEnd();

switch_color(0);

glBegin(GL_LINE_LOOP);

glVertex2f(x-bs/2, y+bs/2-0.1);

glVertex2f(x-bs/2, y-bs/2-0.1); //рисует черный ободок

glVertex2f(x+bs/2, y-bs/2);

glVertex2f(x+bs/2, y+bs/2);

glEnd();

switch_color(color);

}

//------CAR------------------

car::car(float _cx, float _cy, int _ccolor, bool _crash, bool _godmode): cx(_cx), cy(_cy), ccolor(_ccolor), crash(_crash), godmode(_godmode)

{

color=ccolor;

if(crash==true) {

switch(crashblink) //моргание машинки при аварии

{

case true: { color=0; car_i++; if(car_i==15) { crashblink=false; car_i=0;} break; }

case false: { color=1; car_i++; if(car_i==15) { crashblink=true; car_i=0;} break; }

}

}

if(godmode==true) bs=3; //увеличение размера блока если включен полет

x=cx;

y=cy;

//----

block();

//----

y=cy+bs;

block();

x=cx-bs;

block();

x=cx+bs;

block();

x=cx;

//----

y=cy+2*bs;

block();

//------

y=cy-bs;

block();

x=cx-bs;

block();

x=cx+bs;

block();

x=cx;

y=cy;

}

//===========

car::~car() //закрашиваем машинку прямоугольником цвета фона

{

glColor3f(foncolor[0], foncolor[1], foncolor[2]);

glBegin(GL_QUADS);

glVertex2f(cx-1.6*bs, cy+2.6*bs);

glVertex2f(cx-1.6*bs, cy-1.6*bs);

glVertex2f(cx+1.6*bs, cy-1.6*bs);

glVertex2f(cx+1.6*bs, cy+2.6*bs);

glEnd();

if(godmode==true) bs=2; //возвращаем размер блока в начальное положение

}

//----GRASS----

grass::grass(float _gwidth=0.0, float _gm=0.0): gwidth(_gwidth), gm(_gm)

{

x=gwidth/2;

bool k=true;

for(y=-ortho-bs/2+gm; y<=ortho+bs; y+=bs)

{

switch(k) //смена цвета блока через один

{

case true: color=2; k=false; break;

case false: color=21; k=true; break;

}

block(); //рисуем справа от центра

x=-x; //отражаем Х

block(); //рисуем слева от центра

x=-x; //отражаем Х обратно

}

}

grass::~grass() {

glColor3f(foncolor[0], foncolor[1], foncolor[2]);

x=gwidth/2;

glBegin(GL_QUADS);

glVertex2f(x-0.6*bs, +ortho);

glVertex2f(x-0.6*bs, -ortho);

glVertex2f(x+0.6*bs, -ortho);

glVertex2f(x+0.6*bs, +ortho);

glEnd();

x=-gwidth/2;

glBegin(GL_QUADS);

glVertex2f(x-0.6*bs, +ortho);

glVertex2f(x-0.6*bs, -ortho);

glVertex2f(x+0.6*bs, -ortho);

glVertex2f(x+0.6*bs, +ortho);

glEnd();

}

//----WALL---- рисуем стенку

wall::wall(float _wy, int _wpos, int _wcolor): wy(_wy), wpos(_wpos), wcolor(_wcolor) {

color=wcolor;

y=wy;

switch(wpos) //устанавливаем координаты по Х в зависимости от положения стенки (слева или справа)

{

case 0: wx=-roadwidth/2+wallwidth/2+bs/2; break;

case 1: wx=roadwidth/2-wallwidth/2-bs/2; break;

}

for(x=wx-wallwidth/2+bs/2; x<=wx+wallwidth/2-bs/2; x+=bs) block(); //ставим 5 блоков

}

wall::~wall() {

glColor3f(foncolor[0], foncolor[1], foncolor[2]);

glBegin(GL_QUADS); //закрашиваем стенку прямоугольником цвета фона

glVertex2f(wx-wallwidth/2-1, wy+0.6*bs);

glVertex2f(wx-wallwidth/2-1, wy-0.6*bs);

glVertex2f(wx+wallwidth/2+1, wy-0.6*bs);

glVertex2f(wx+wallwidth/2+1, wy+0.6*bs);

glEnd();

}

//-----GAME OVER-----

game_over::game_over(float _gox, float _goy, int _ocolor): gox(_gox), goy(_goy), ocolor(_ocolor) {

switch(goblink) //изменяем цвет каждые 15 отрисовок (черный/красный) так дистигается эффект моргания

{

case true: { color=0; go_i++; if(go_i==15) { goblink=false; go_i=0;} break; }

case false: { color=1; go_i++; if(go_i==15) { goblink=true; go_i=0;} break; }

}

int i;

//===== G ===== //устанавливаем координатые блоков, чтобы получилась надпись GAME OVER

int gx[12]={-42, -42, -42, -40, -40, -38, -38, -36, -36, -36, -34, -34 };

int gy[12]={2, 4, 6, 0, 8, 0, 8, 0, 4, 8, 2, 4 };

for (i=0; i<12; i++) { x=gox+gx[i]; y=goy+gy[i]; block(); }

//===== A ======

int ax[10]={-30, -30, -30, -30, -28, -28, -26, -26, -26, -26};

int ay[10]={0, 2, 4, 6, 4, 8, 0, 2, 4, 6};

for (i=0; i<10; i++) { x=gox+ax[i]; y=goy+ay[i]; block(); }

//==== M ======

int mx[13]={-22, -22, -22, -22, -22, -20, -18, -16, -14, -14, -14, -14, -14} ;

int my[13]={0, 2, 4, 6, 8, 6, 4, 6, 0, 2, 4, 6, 8};

for (i=0; i<13; i++) { x=gox+mx[i]; y=goy+my[i]; block(); }

//==== E ======

int ex[14]={-10, -10, -10, -10, -10, -8, -8, -8, -6, -6, -6, -4, -4, -4};

int ey[14]={0, 2, 4, 6, 8, 0, 4, 8, 0, 4, 8, 0, 4, 8};

for (i=0; i<14; i++) { x=gox+ex[i]; y=goy+ey[i]; block(); }

//==== O =====

int ox[12]={2, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 10};

int oy[12]={2, 4, 6, 0, 8, 0, 8, 0, 8, 2, 4, 6};

for (i=0; i<12; i++) { x=gox+ox[i]; y=goy+oy[i]; block(); }

//==== V ====

int vx[9]={14, 14, 16, 16, 18, 20, 20, 22, 22};

int vy[9]={6, 8, 2, 4, 0, 2, 4, 6, 8};

for (i=0; i<9; i++) { x=gox+vx[i]; y=goy+vy[i]; block(); }

//==== E ====

for (i=0; i<14; i++) { x=gox+ex[i]+36; y=goy+ey[i]; block(); }

//==== R ====

int rx[12]={36, 36, 36, 36, 36, 38, 38, 40, 40, 40, 42, 42};

int ry[12]={0, 2, 4, 6, 8, 4, 8, 2, 4, 8, 0, 6};

for (i=0; i<14; i++) { x=gox+rx[i]; y=goy+ry[i]; block(); }

}

//------TEXT------

void text::drawtext(const char* ftext, int _color, float _x, float _y)

{ //метод выводящий текст на экран

x=_x; y=_y; color=_color; itext=ftext;

switch_color(color);

std::string stext;

stext=itext;

int length=stext.size();

glRasterPos2i(x,y);

for(int i=0; i<=length; i++) glutBitmapCharacter(GLUT_BITMAP_9_BY_15, (int)stext.data()[i]);

}

void text::hidetext()

{ //закрашивает текст полигоном в виде шестиугольника

switch_color(7);

glBegin(GL_POLYGON);

glVertex2f(x-0.5, y-0.5);

glVertex2f(x-3.5, y+1.4);

glVertex2f(x-0.5, y+2.5);

glVertex2f(x+23, y+2.5);

glVertex2f(x+26, y+1.4);

glVertex2f(x+23, y-0.5);

glEnd();

}

//--------- MENU -------------

void Tmenu::show() {

x=-49;

y=49;

for(int i=1; i<=2500; i++) //рисует 2500 блоков рандомного цвета на фоне

{

color=(rand()%10)-1;

block();

x+=2;

if(x>50) {x=-49; y-=2;}

}

AUX_RGBImageRec* image; //создаем битмап

image=auxDIBImageLoad("name.bmp"); //полгружаем в него картинку

glRasterPos2d(-30,22); //выбираем место для отрисовки (координаты левого нижнего угла)

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glPixelZoom(1.0, 1.0); //утсанавливаем масштаб

glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE, image->data); //отрисовуем массив пикселей

image=auxDIBImageLoad("controls.bmp");

glRasterPos2d(-46,-46);

glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE, image->data);

image=auxDIBImageLoad("menu.bmp");

glRasterPos2d(-26,-30);

glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE, image->data);

draw_select(true);

}

void Tmenu::draw_select(bool _selection)

{

selection=_selection;

switch(selection) //рисуем подчеркивания в меню

{

case true:

switch_color(-2);

glBegin(GL_QUADS);

glVertex2f(-11, -18);

glVertex2f(-11, -19);

glVertex2f(9, -19);

glVertex2f(9, -18);

glEnd();

switch_color(1);

glBegin(GL_QUADS);

glVertex2f(-20, -5);

glVertex2f(-20, -6);

glVertex2f(20, -6);

glVertex2f(20, -5);

glEnd();

break;

case false:

switch_color(-2);

glBegin(GL_QUADS);

glVertex2f(-20, -5);

glVertex2f(-20, -6);

glVertex2f(20, -6);

glVertex2f(20, -5);

glEnd();

switch_color(1);

glBegin(GL_QUADS);

glVertex2f(-11, -18);

glVertex2f(-11, -19);

glVertex2f(9, -19);

glVertex2f(9, -18);

glEnd();

break;

}

glFlush();

}

Зміст файлу 1.cpp:

#include "classes.h"

long gtc=GetTickCount();

float x, y=-45, m=bs/2, ey=ortho+bs*3, ex=((gtc%(exrand*66+1))/66)-exrand/2, wy=1.5*ortho;

int wpos=gtc%2;

bool godmode=false;

float score_point_float=0;

char score_point_char[30];

grass gr(roadwidth, m);

car player(x, -45, 1, false, false);

car enemy(ex, ey, 1, false, false); //инициализируем обьекты классов с началным положением

wall wa(wy, wpos, 9);

text score;

Tmenu menu;

bool gameover=false;

bool enemycrash=false;

bool KeyDown[256] = {false}; //массив для нажатых кнопочек

int firststart=0;

AUX_RGBImageRec* control; //битмап для картинки

void display() //основная функция отрисовки происходящего

{

if(firststart<5) //первые пять отрисовок чистим экран, позволяет избравиться от некоторых глюков на медленных компьюетрах

{

glClear(GL_COLOR_BUFFER_BIT);

firststart++;

}

wa.~wall();

enemy.~car();

player.~car(); //зарисовуем объекты

gr.~grass();

score.hidetext();

wall wa(wy, wpos, 9); //рисуем стену

grass gr(roadwidth, m); //траву

car enemy(ex, ey, 7, enemycrash, false); //вражескую машинку

score.drawtext(score_point_char , 1, -45, 45); //выводим очки

car player(x, y, playercolor, gameover, godmode); //рисуем нашу машинку

glFlush(); //и наконец выводим всё из буфера на экран

}

void display_over() //функция отрисовки при прогрыше

{

game_over o(0, 0, 1); //рисуем надпись гейм овер

o.~game_over(); //просто используем деструктор для экономии ресурсов

glRasterPos2d(-46,-46); //рисуем помощь об управлении

glDrawPixels(control->sizeX, control->sizeY, GL_RGB, GL_UNSIGNED_BYTE, control->data);

glFlush(); //выводим все из буфера на экран

}

void timer(int=0) //функция-таймер

{

if(gameover==false)

{

if(m==-8) m=0; //зациклим движение травы

m-=1.6; //двигаем траву

if(ey<-ortho-bs*3) //если вражеская машинка уехала за экран создадим новую

{

ey=-ey+5*bs;

gtc=GetTickCount();

ex=((gtc%(exrand*66+1))/66)-exrand/2;

enemycrash=false;

}

if(enemycrash==false) ey-=1.2; //двигаем вражескую машинку

else ey-=1.6;

if(wy<-ortho-bs*3) //если стенка уехала за экран создадим новую

{

wy=-wy;

gtc=GetTickCount();

wpos=gtc%2;

}

wy-=1.6; //двигаем стенку

if(godmode==false) score_point_float+=0.2; //прибавляем очки

else score_point_float-=1; //отнимаем если игрок летит, притом в 5 раз бстрее

sprintf(score_point_char, "SCORE: %.0f", score_point_float); //конвертируем очки в char

if(KeyDown['a']==true && x>-roadwidth/2+bs*2.5) x-=0.8; //двигаем машинку в зависимости от нажатых кнопок

if(KeyDown['d']==true && x<roadwidth/2-bs*2.5) x+=0.8;

if(KeyDown['w']==true && y<ortho-bs*3) y+=0.6;

if(KeyDown['s']==true && y>-ortho+bs*2.5) y-=0.6;

display(); //отрисовуем

//проверяем на столкновения себя и врага

if(godmode==false) if((wpos==0 && wy>y-2*bs && wy<y+3*bs+0.2 && -roadwidth/2+wallwidth/2+bs/2>x-4*bs && -roadwidth/2+wallwidth/2+bs/2<x+4*bs) || (wpos==1 && wy>y-2*bs && wy<y+3*bs+0.2 && roadwidth/2-wallwidth/2-bs/2>x-4*bs && roadwidth/2-wallwidth/2-bs/2<x+4*bs) || (ey>(y-4*bs) && ey<(y+4*bs+0.2) && ex>(x-3*bs) && ex<(x+3*bs))) gameover=true;

if((wpos==0 && wy>ey-2*bs && wy<ey+3*bs+0.2 && -roadwidth/2+wallwidth/2+bs/2>ex-4*bs && -roadwidth/2+wallwidth/2+bs/2<ex+4*bs) || (wpos==1 && wy>ey-2*bs && wy<ey+3*bs+0.2 && roadwidth/2-wallwidth/2-bs/2>ex-4*bs && roadwidth/2-wallwidth/2-bs/2<ex+4*bs)) enemycrash=true;

}

else //gameover

{

display_over(); //отрисовуем проигрыш

if(KeyDown['r']==true) //делаем рестарт при нажатии R

{

x=0;

y=-45;

m=bs/2;

ey=ortho+bs*3;

gtc=GetTickCount();

ex=((gtc%(exrand*66+1))/66)-exrand/2; wy=1.5*ortho;

score_point_float=0;

KeyDown['r']=false; //"отжимаем" кнопку

gameover=false;

glClear(GL_COLOR_BUFFER_BIT); //чистим экран

}

}

if(KeyDown['f']==true) glutTimerFunc(10, timer, 0); //ускоряем таймер при нажатой F

else glutTimerFunc(20, timer, 0);

}

void Keyboard(unsigned char key, int _x, int _y) //проверяем нажатие кнопок

{

if(key!='r')

{

KeyDown[key] = true; //и вносим в булевый массив значения нажатых кнопок

if(KeyDown['e']==true) godmode=true;

}

else if(gameover==true) KeyDown[key] = true;

}

void KeyboardUp(unsigned char key, int _x, int _y)

{

if(key!='r')

{

KeyDown[key] = false; //"отжимаем кнопки"

if(KeyDown['e']==false) godmode=false;

}

}

void menu_select(bool select)

{

if(select==true) //начинаем игру при выборе NEW GAME

{

glutKeyboardFunc(Keyboard);

glutKeyboardUpFunc(KeyboardUp);

glutIgnoreKeyRepeat(true);

firststart=true;

glutDisplayFunc(display_over);

glutDisplayFunc(display); //вызов функции Дисплей

timer();

}

else //либо вызодим при выборе EXIT

{

exit(0);

}

}

void MKeyboard(unsigned char key, int _x, int _y) //проверяем нажатые кнопки в меню

{

if(key==13) menu_select(menu.selection);

}

void SKeyboard(int key, int x, int y) //проверяем нажатые кнопки в меню

{

if(key==GLUT_KEY_UP || key==GLUT_KEY_DOWN)

{

switch(menu.selection)

{

case true: menu.draw_select(false); break;

case false: menu.draw_select(true); break;

}

}

}

void draw_menu() //отрисовуем меню

{

menu.show();

glutSpecialFunc(SKeyboard); //регистрируем функции мониторящие клавиатуру

glutKeyboardFunc(MKeyboard);

}

int main(int argc, char **argv)

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //выбираем режим отображеия, у нас одинарная буферизация и 3 цвета

glutInitWindowSize(wwidth, wheight); //размер окна

glutCreateWindow("SQ CaRs"); //инициализируем окошко

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glClearColor(foncolor[0], foncolor[1], foncolor[2], 1.0); //цвет фона

glOrtho(-ortho, ortho, -ortho, ortho, -0.5, 0.5); //размеры окон

FreeConsole(); //убираем консоль

glutDisplayFunc(draw_menu); //вызов функции draw_menu

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

control=auxDIBImageLoad("controls.bmp"); //хагружаем в битмап картинку

glutMainLoop();

}

26