Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ИГС / Lab_02 / Move11 / Move11 / mov11

.cpp
Скачиваний:
7
Добавлен:
17.04.2018
Размер:
17.58 Кб
Скачать


#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <math.h>
#include <stdio.h>

//идентификатор приложения
HINSTANCE hInstApp;



//название программы
WCHAR const szClassName[] = TEXT("Movement");
//заголовок окна   
WCHAR const szWindowTitle[] = 
	TEXT("Korneev V.   Pictures from bmp-files.                    Ship  and  Birds");


//прототимы функций
BOOL RegisterApp(HINSTANCE hInst);
HWND CreateApp(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void Move_OnCreate();
void Move_OnDestroy(HWND hwnd);
void Move_OnTimer(HWND hwnd);
void Move_OnKeydown(HWND hwnd);
void Move_OnPaint(HWND);




//главная функция
//#pragma argsused
int PASCAL WinMain(HINSTANCE hInst,      //дескриптор(идентификатор) программы
                   HINSTANCE hPrevInstance,
                   LPSTR     lpszCmdParam,
                   int       nCmdShow)
{
	MSG msg;                         //структура для работы с сообщениями

	if(!RegisterApp(hInst))          //регистрация окна
		return FALSE;

	if(!CreateApp(hInst,nCmdShow))   //создание окна
		return FALSE;

	while(GetMessage(&msg,NULL,0,0))  //цикл обработка сообщений 
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return 0;
}

//регистрация окна  
BOOL RegisterApp(HINSTANCE hInst)
{
	WNDCLASS wc;

	wc.style         = CS_HREDRAW | CS_VREDRAW;     //стиль окна  
	wc.lpfnWndProc   = WndProc;                     //имя оконной процедуры
	wc.cbClsExtra    = 0;
	wc.cbWndExtra    = 0;                       
	wc.hInstance     = hInst;                       //дескриптор программы
	wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION); //иконка 
	wc.hCursor	 = LoadCursor(NULL, IDC_ARROW);     //форма курсора
	wc.hbrBackground = GetStockBrush(GRAY_BRUSH);   //цвет окна  
	wc.lpszMenuName  = TEXT("APP_MENU");                  //имя меню окна
	wc.lpszClassName = szClassName;                 //название программы 

	return RegisterClass(&wc);           //регистрация окна  
}


//создание окна  
HWND CreateApp(HINSTANCE hInstance, int nCmdShow)
{

	hInstApp = hInstance;

	 HWND hwnd;   //дескриптор окна 

	 hwnd = CreateWindow(szClassName,      //название программы   
		 	 szWindowTitle,        //заголовок окна  
			 WS_OVERLAPPEDWINDOW,  //вид окна 
			 CW_USEDEFAULT,        //x - координата окна  
			 CW_USEDEFAULT,        //y - координата окна  
//			 CW_USEDEFAULT,        //ширина окна  
//			 CW_USEDEFAULT,        //высота окна  
			 640,
			 480,
			 NULL,          
			 NULL,          
			 hInstance,     
			 NULL);         

	if(hwnd == NULL)
		return hwnd;

	ShowWindow(hwnd,nCmdShow);   //показать окно 
	UpdateWindow(hwnd);          //обновить окно 

	return hwnd;
}

//оконная процедура обрабатывающая сообщения
LRESULT CALLBACK  WndProc(HWND hwnd, UINT msg,
			WPARAM wParam, LPARAM lParam)
{

	switch(msg)
	{
		case WM_CREATE:
			Move_OnCreate();
			break;
		case WM_PAINT:
			Move_OnPaint(hwnd);
			break;
		case WM_TIMER:
			Move_OnTimer(hwnd);
			break;
		case WM_KEYDOWN:
			Move_OnKeydown(hwnd);
			break;
		case WM_DESTROY:
			Move_OnDestroy(hwnd);
			break;
		default:
			return DefWindowProc(hwnd,msg,wParam,lParam);
	}

	return 0L;

}





//размеры окна вывода в мировой системе координат
double xLeft, xRight, yBottom, yTop;
//размеры окна вывода в пикселах в окне программы  
int    nLeft, nRight, mBottom, mTop;


//переход от x к пикселу n
inline int xn(double x)
{
	return (int)((x - xLeft)/(xRight - xLeft)*(nRight - nLeft)) + nLeft;
}

//переход от y к пикселу m
inline int ym(double y)
{
	return (int)((y - yBottom)/(yTop - yBottom)*(mTop - mBottom)) + mBottom;
}


//класс для работы с матрицами аффинных преобразований
//используются однородные координаты
class Matrix2D
{

public:
	double x[3][3];

	Matrix2D();                               //матрица единичная

	void rotate(double fi);                      //матрица поворота
	void displa(double kx, double ky);           //матрица растяжения
	void transl(double tx, double ty );          //матрица трансляции

	//перемножение матриц
	friend Matrix2D operator * (const Matrix2D&, const Matrix2D&);

};

Matrix2D::Matrix2D()
{
	x[0][0] =  1; x[0][1] =  0; x[0][2] =  0;
	x[1][0] =  0; x[1][1] =  1; x[1][2] =  0;
	x[2][0] =  0; x[2][1] =  0; x[2][2] =  1;
}


void Matrix2D::rotate(double fi)
{
	double cosfi = cos(fi), sinfi = sin(fi);
	x[0][0] = cosfi; x[0][1] = -sinfi; x[0][2] = 0;
	x[1][0] = sinfi; x[1][1] =  cosfi; x[1][2] = 0;
	x[2][0] =     0; x[2][1] =      0; x[2][2] = 1;
}

void Matrix2D::displa(double kx, double ky)
{
	x[0][0] = kx; x[0][1] =  0; x[0][2] = 0;
	x[1][0] =  0; x[1][1] = ky; x[1][2] = 0;
	x[2][0] =  0; x[2][1] =  0; x[2][2] = 1;
}

void Matrix2D::transl(double tx, double ty )
{
	x[0][0] =  1; x[0][1] =  0; x[0][2] = tx;
	x[1][0] =  0; x[1][1] =  1; x[1][2] = ty;
	x[2][0] =  0; x[2][1] =  0; x[2][2] =  1;
}


Matrix2D operator * (const Matrix2D& a, const Matrix2D& b)
{
	Matrix2D c;
	double s;
	for(int i=0; i<3; i++)
		for(int j=0; j<3; j++)
		{
			s = 0;
			for(int n=0; n<3; n++)
				s += a.x[i][n]*b.x[n][j];
			c.x[i][j] = s;
		}
	return c;
}


//структура для описания точек фигуры
struct Point
{
	double x;
	double y;
};


//аффинное преобразование координат точки P с помощью
//матрицы A
Point affine( Matrix2D A,  Point P)
{
	Point Pp;
		Pp.x = A.x[0][0]*P.x + A.x[0][1]*P.y + A.x[0][2]*1;
		Pp.y = A.x[1][0]*P.x + A.x[1][1]*P.y + A.x[1][2]*1;
	return Pp;
}




//координты вершин птицы
Point	PtB[25], PtB0[25];

//"время" движения по траектории цента птицы
	double tB , dtB, dtB0;


//создаем 6 матриц аффинный преобразований
	Matrix2D R, R1, T, D, A, T1, T2;

//началтные и текущие точки цента птицы
	double xB0, yB0, xB2, yB2, xB1, yB1;


//флаг остановки и запуска таймера
	int MoveStop;

//время задержки таймера
UINT uElapse;

//флаг движения кадров растровой картинки
int  flagBmp;
//флаг остановки движения после вызрыва
int flagEnd;

HGLOBAL hBuf;

//имена bmp-файлов
char nameShip[50][20];

//функция обрабатывает сообщение  WM_CREATE
void Move_OnCreate()
{
//размеры поля вывода в мировых и экранных координатах
	xLeft = -10; xRight =  10; yBottom =  -7.5; yTop =  7.5;
//	nLeft = 60; nRight  = 700; mTop  = 15; mBottom = 495;
	nLeft = 0; nRight  = 640; mTop  = 0; mBottom = 480;

   
   
//время задержки таймера
	uElapse = 250;

//флаг запуска таймера
	MoveStop = 1;

//заполняем массив имен bmp-файлов nameShip[k]
//имена следущего вида: Ship10.bmp, Ship11.bmp, ... Ship59.bmp 
//всего 50 имен
	char is[3] = "";
	char ssss[30] = "";
	
	for( int k=0; k<50; k++)
	{
		_itoa_s(k+10,is,3,10);
		strcpy_s(ssss,"BMP\\Ship");
		strcat_s(ssss,is);
		strcat_s(ssss,".bmp");
		strcpy_s(nameShip[k],ssss);
	}

	//открываем файл для чтения
	HFILE hFile = _lopen(nameShip[0], OF_READ);
	//определяем размер файла
	LONG FileSize = _llseek(hFile, 0L, FILE_END);

	//выделяет заданное число байт в памяти
	hBuf = GlobalAlloc(GMEM_FIXED, FileSize);
	//закрываем файл
	_lclose(hFile);


	flagBmp = 1;
	flagEnd = 0;
}



//функция обрабатывающая сообщение WM_KEYDOWN
void Move_OnKeydown(HWND hwnd)
{
	if(MoveStop == 0)
	{
		KillTimer(hwnd, 1);
		MoveStop = 1;
	}
	else
	{
		SetTimer(hwnd, 1, uElapse, NULL);
		MoveStop = 0;
	}
}


//функция обрабатывает сообщение  WM_DESTROY
void Move_OnDestroy(HWND hwnd)
{
	KillTimer(hwnd, 1);
	PostQuitMessage(0);   //закрывает окно 
}











//траектория птицы a
Point TrajBa(double t)
{
	Point P;
   P.x = 11 - 0.5*t;
   P.y = -2 + 0.2*t;
   return P;
}

//траектория птицы b
Point TrajBb(double t)
{
	Point P;
   P.x = 11 - 0.5*(t-4);
   P.y = -2 + 0.2*(t-4);
   return P;
}



//рисует птицу  точке x, y
void Bird(HDC hdc, double x,double y, double t)
{

	PtB0[0].x = 2.5;   PtB0[0].y = 2*cos(t);  
	PtB0[1].x = 3.0;   PtB0[1].y = 2*cos(t);  
	PtB0[2].x = 2.0;   PtB0[2].y = 1 + 1*cos(t);  
	PtB0[3].x = 1.0;   PtB0[3].y = 1 + 1*cos(t);  
	PtB0[4].x = -0.5;   PtB0[4].y = 0.0;  
	PtB0[5].x = 1.5;   PtB0[5].y = 0.0;  
	PtB0[6].x = 0.0;   PtB0[6].y = 1 + 1*cos(t);  
	PtB0[7].x = -1.0;  PtB0[7].y = 1 + 1*cos(t);  
	PtB0[8].x = -2.5;  PtB0[8].y = 2*cos(t);  
	PtB0[9].x = -2.0;  PtB0[9].y = 2*cos(t);  

	PtB0[10].x = 3.0;   PtB0[10].y = 0.0;  
	PtB0[11].x = -1.5;  PtB0[11].y = 0.0;  
	PtB0[12].x = -1.2;  PtB0[12].y = 0.4;  
	PtB0[13].x = -2.0;   PtB0[13].y = 0.7;  
	PtB0[14].x = -4.5;   PtB0[14].y = 0.5 + 0.3*cos(3*t);  
	PtB0[15].x = -2.5;   PtB0[15].y = 0.25;  
	PtB0[16].x = -4.2;   PtB0[16].y = -0.2 - 0.3*cos(3*t);  
	PtB0[17].x = -2.2;   PtB0[17].y = 0.0;  
	PtB0[18].x = -0.9;   PtB0[18].y = -0.9;  
	PtB0[19].x = 2.0;   PtB0[19].y = -0.1;  
	PtB0[20].x = 4.0;   PtB0[20].y = -0.2;  
	PtB0[21].x = 3.5;   PtB0[21].y = 0.0;  
	PtB0[22].x = 4.0;   PtB0[22].y = 0.1;  

	PtB0[23].x = -1.9;   PtB0[23].y = 0.9;  
	PtB0[24].x = -1.6;    PtB0[24].y = 0.6;  
	
	double kx, ky, fi;
	kx = 0.1 + 0.02*t; ky = 0.1 + 0.02*t; fi = -0.25;
//	kx = 1; ky = 1;
//создаем матрицы аффинного преобразования
		T1.transl(x,y);
		R1.rotate(fi);
		D.displa(kx, ky);

		A = T1*R1*D;

//совершаем аффинное преобразование точек фигуры
		for(int n=0; n<23; n++)
			PtB0[n] = affine(A,PtB0[n]);

		A = T1*D;

//совершаем аффинное преобразование точек фигуры
		for(int n=23; n<25; n++)
			PtB0[n] = affine(A,PtB0[n]);



	HBRUSH hbrush1 = CreateSolidBrush(RGB(100,120,100));
	HBRUSH hbrushOld = (HBRUSH)SelectObject(hdc,hbrush1);     //выбираем кисть hbrush
	HPEN hpen = CreatePen(PS_SOLID,1,RGB(0x70,0x70,0x70));
	HPEN hpenOld = (HPEN)SelectObject(hdc,hpen);         // выбираем перо hpen


	POINT pt[20];


	pt[0].x = xn(PtB0[6].x); pt[0].y = ym(PtB0[6].y);
	pt[1].x = xn(PtB0[7].x); pt[1].y = ym(PtB0[7].y);
	pt[2].x = xn(PtB0[8].x); pt[2].y = ym(PtB0[8].y);
	pt[3].x = xn(PtB0[9].x); pt[3].y = ym(PtB0[9].y);

	Polygon(hdc,pt,4);

	HBRUSH hbrush2 = CreateSolidBrush(RGB(125,145,125));
	SelectObject(hdc,hbrush2);     //выбираем кисть hbrush

	pt[0].x = xn(PtB0[4].x); pt[0].y = ym(PtB0[4].y);
	pt[1].x = xn(PtB0[5].x); pt[1].y = ym(PtB0[5].y);
	pt[2].x = xn(PtB0[6].x); pt[2].y = ym(PtB0[6].y);
	pt[3].x = xn(PtB0[7].x); pt[3].y = ym(PtB0[7].y);

	Polygon(hdc,pt,4);

	HBRUSH hbrush3 = CreateSolidBrush(RGB(150,170,150));
	SelectObject(hdc,hbrush3);     //выбираем кисть hbrush

	pt[0].x = xn(PtB0[10].x); pt[0].y = ym(PtB0[10].y);
	pt[1].x = xn(PtB0[11].x); pt[1].y = ym(PtB0[11].y);
	pt[2].x = xn(PtB0[12].x); pt[2].y = ym(PtB0[12].y);
	pt[3].x = xn(PtB0[13].x); pt[3].y = ym(PtB0[13].y);
	pt[4].x = xn(PtB0[14].x); pt[4].y = ym(PtB0[14].y);
	pt[5].x = xn(PtB0[15].x); pt[5].y = ym(PtB0[15].y);
	pt[6].x = xn(PtB0[16].x); pt[6].y = ym(PtB0[16].y);
	pt[7].x = xn(PtB0[17].x); pt[7].y = ym(PtB0[17].y);
	pt[8].x = xn(PtB0[18].x); pt[8].y = ym(PtB0[18].y);
	pt[9].x = xn(PtB0[19].x); pt[9].y = ym(PtB0[19].y);
	pt[10].x = xn(PtB0[20].x); pt[10].y = ym(PtB0[20].y);
	pt[11].x = xn(PtB0[21].x); pt[11].y = ym(PtB0[21].y);
	pt[12].x = xn(PtB0[22].x); pt[12].y = ym(PtB0[22].y);

	Polygon(hdc,pt,13);

	HBRUSH hbrush4 = CreateSolidBrush(RGB(175,195,175));
	SelectObject(hdc,hbrush4);     //выбираем кисть hbrush

	pt[0].x = xn(PtB0[2].x); pt[0].y = ym(PtB0[2].y);
	pt[1].x = xn(PtB0[3].x); pt[1].y = ym(PtB0[3].y);
	pt[2].x = xn(PtB0[4].x); pt[2].y = ym(PtB0[4].y);
	pt[3].x = xn(PtB0[5].x); pt[3].y = ym(PtB0[5].y);

	Polygon(hdc,pt,4);

	HBRUSH hbrush5 = CreateSolidBrush(RGB(200,220,200));
	SelectObject(hdc,hbrush5);     //выбираем кисть hbrush

	pt[0].x = xn(PtB0[0].x); pt[0].y = ym(PtB0[0].y);
	pt[1].x = xn(PtB0[1].x); pt[1].y = ym(PtB0[1].y);
	pt[2].x = xn(PtB0[2].x); pt[2].y = ym(PtB0[2].y);
	pt[3].x = xn(PtB0[3].x); pt[3].y = ym(PtB0[3].y);

	Polygon(hdc,pt,4);

	HBRUSH hbrush6 = CreateSolidBrush(RGB(255,0,128));
	SelectObject(hdc,hbrush6);     //выбираем кисть hbrush

	Ellipse(hdc, xn(PtB0[23].x), ym(PtB0[23].y), xn(PtB0[24].x), ym(PtB0[24].y));

    SelectObject(hdc,hpenOld);
	DeleteObject(hpen);           //убираем перо hpen
    SelectObject(hdc,hbrushOld);
	DeleteObject(hbrush1);           //убираем перо hpen
	DeleteObject(hbrush2);           //убираем перо hpen
	DeleteObject(hbrush3);           //убираем перо hpen
	DeleteObject(hbrush4);           //убираем перо hpen
	DeleteObject(hbrush5);           //убираем перо hpen
	DeleteObject(hbrush6);           //убираем перо hpen



}











//копируем файл в память, получаем указатель на первый байт памяти
BYTE* ReadFileToMem(LPSTR lPstr)
{
	//открываем файл для чтения
	HFILE hFile = _lopen(lPstr, OF_READ);
	//определяем размер файла
	LONG FileSize = _llseek(hFile, 0L, FILE_END);
	//указатель файла ставим в начало файла
	_llseek(hFile, 0L, FILE_BEGIN);

	//выделяет заданное число байт в памяти
//	hBuf = GlobalAlloc(GMEM_MOVEABLE, FileSize);
	//получаем указатель на первый байт выделенной памяти
	BYTE* lpBuf = (BYTE*)GlobalLock(hBuf);
	//копируем файл в память
	_hread(hFile, lpBuf, FileSize);

	//закрываем файл
	_lclose(hFile);

	return lpBuf;
}

//получаем указатель на первый байт изображения
BYTE* ImageBytes(BYTE* lpBuf)
{
	//получаем указатель на первый байт структуры BITMAPFILEHEADER
	LPBITMAPFILEHEADER lpfh = (LPBITMAPFILEHEADER)lpBuf;
	//получаем указатель на первый байт изображения
	BYTE* lpOff = (BYTE*)lpfh + lpfh->bfOffBits;
	
	return lpOff;
}


//получаем указатель на первый байт структуры BITMAPINFOHEADER
LPBITMAPINFOHEADER BmpInfHead(BYTE* lpBuf)
{
	//получаем указатель на первый байт структуры BITMAPINFOHEADER
	LPBITMAPINFOHEADER lpih = (LPBITMAPINFOHEADER)(lpBuf + sizeof(BITMAPFILEHEADER));

	return lpih;
}




//функция обрабатывает сообщение  WM_PAINT
void Move_OnPaint(HWND hwnd)
{

	//получаем идентификатор контекста экрана
	PAINTSTRUCT ps;
	HDC hdc = BeginPaint(hwnd, &ps);  

	//создаем контекст памяти hdcMem, совместимый с контекстом экрана hdc
	HDC hdcMem = CreateCompatibleDC(hdc);
	//создаем (пустую) битовую карту совместмую с контекстом экрана
	HBITMAP hBmp = CreateCompatibleBitmap(hdc, 640, 480); 
	//выбираем битовую карту hBmp в контекст памяти hdcMem
	HBITMAP hBmpOld = (HBITMAP)SelectObject(hdcMem, hBmp); 

	//получаем указатель на первый байт блока памяти, куда скопирован файл "ship58.bmp"
	BYTE* lpBuf = ReadFileToMem(nameShip[48]);
	//получаем указатель на первый байт изображения
	BYTE* lpOff = ImageBytes(lpBuf);
	//получаем указатель на первый байт структуры BITMAPINFOHEADER
	LPBITMAPINFOHEADER lpih = BmpInfHead(lpBuf);

	//устанавливает в битовой карте hBmp пиксели изображения по адресом lpOff
	SetDIBits(hdcMem, hBmp, 0, lpih->biHeight, lpOff, (LPBITMAPINFO)lpih, DIB_RGB_COLORS);


	SetTextColor(hdcMem,RGB(230,230,220));
	SetBkColor(hdcMem,RGB(0,0,0));
	TextOut(hdcMem, 225,100,TEXT(" P r e s s   a n y   k e y "),27);


	tB = 0;
	xB2 = TrajBa(tB).x;
	yB2 = TrajBa(tB).y;
	
	Bird(hdcMem,0,0,55);

	//копируем изображение из контекста памяти hdcMem в контекст экрана hdc
	BitBlt(hdc, 0, 0, nRight, mBottom, hdcMem, 0, 0, SRCCOPY);
	
	DeleteObject(hBmp);            //убираем растровое изображение из памяти
	SelectObject(hdcMem, hBmpOld); //востанавливаем контекст памяти
	DeleteDC(hdcMem);                 //убираем контекст памяти

	EndPaint(hwnd, &ps);       //освобождаем контекст устройства 

}



//функция обрабатывает сообщение  WM_TIMER
void Move_OnTimer(HWND hwnd)
{

	//получаем идентификатор контекста экрана
	HDC hdcWin = GetDC(hwnd);  

	//создаем контекст памяти hdcMem, совместимый с контекстом экрана hdc
	HDC hdcMem = CreateCompatibleDC(hdcWin);
	//создаем (пустую) битовую карту совместмую с контекстом экрана
	HBITMAP hBmp = CreateCompatibleBitmap(hdcWin, 640, 480); 
	//выбираем битовую карту hBmp в контекст памяти hdcMem
	HBITMAP hBmpOld = (HBITMAP)SelectObject(hdcMem, hBmp); 

	
	//номер bitmap-ресурса
	static int iBmp = 0;
	int numberBmp;
	if(flagEnd == 1)
		numberBmp = 30;
	else 
		numberBmp = iBmp;
	
  	//получаем указатель на первый байт блока памяти, куда скопирован файл nameShip[]
	BYTE* lpBuf = ReadFileToMem(nameShip[numberBmp]);
	//получаем указатель на первый байт изображения
	BYTE* lpOff = ImageBytes(lpBuf);
	//получаем указатель на первый байт структуры BITMAPINFOHEADER
	LPBITMAPINFOHEADER lpih = BmpInfHead(lpBuf);

	//устанавливает в битовой карте hBmp пиксели изображения по адресом lpOff
	SetDIBits(hdcMem, hBmp, 0, lpih->biHeight, lpOff, (LPBITMAPINFO)lpih, DIB_RGB_COLORS);


	if(flagBmp == 1)
	{
		iBmp++;
		if(iBmp>49)
		{
			flagBmp = 2;
			iBmp--;
		}
	}

	if(flagBmp == 2)
	{
		iBmp--;
		if(iBmp<0)
		{
			flagBmp = 1;
			iBmp++;
		}
	}



	tB += 0.5;
	xB2 = TrajBa(tB).x;
	yB2 = TrajBa(tB).y;
	
	Bird(hdcMem,xB2,yB2,tB);

	xB2 = TrajBb(tB).x;
	yB2 = TrajBb(tB).y;
	
	Bird(hdcMem,xB2,yB2,tB);

	if(xB2 < -10)
		tB = 0;

	//копируем изображение из контекста памяти hdcMem в контекст экрана hdcWin
	BitBlt(hdcWin, 0, 0, nRight, mBottom, hdcMem, 0, 0, SRCCOPY);

	SelectObject(hdcMem, hBmpOld); //востанавливаем контекст памяти
	DeleteObject(hBmp);            //убираем битовую карту
	DeleteDC(hdcMem);                 //освобождаем контекст памяти
	ReleaseDC(hwnd,hdcWin);           //освобождаем контекст экрана
}






Соседние файлы в папке Move11
  • #
    17.04.201817.58 Кб7mov11.cpp
  • #
    17.04.20183.66 Кб8Move11.vcproj
  • #
    17.04.20181.42 Кб7Move11.vcproj.VICTOR1.victor.user