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

Прикладное программирование 4 семестр Laba_2

.doc
Скачиваний:
41
Добавлен:
12.06.2015
Размер:
187.9 Кб
Скачать

МИНОБРНАУКИ РОССИИ

федеральное государственное бюджетное образовательное учреждение

высшего профессионального образования

«Московский государственный технологический университет «СТАНКИН»

(ФГБОУ ВПО МГТУ «СТАНКИН»)

Кафедра «Компьютерные Системы Управления»

«Прикладное Программирование»

Отчёт по лабораторной работе № 2

Выполнил:

студент гр. ___ __ _________________

(дата) (подпись)

Принял:старший

преподаватель __________________ ____________ ___ Пушков Р.Л.

(дата) (подпись)

Москва 2014

Вариант №1:Модифицировать программу так, чтобы при помощи клавиш можно было бы задавать радиус создаваемого шара

Код программы:

Описание и реализация класса CBALL:

CBALL.h:

#pragma once

#include <windows.h>

#include <windowsx.h>

class CBALL

{

double R = 10;

public:

double x, y;

double r;

double v_x, v_y;

RECT rect;

HBRUSH hBrush;

CBALL(void);

virtual ~CBALL(void);

virtual void SetParams(double x, double y, double r, double v_x, double v_y, RECT rect);

void Move(DWORD delta_ticks);

void SetBounds(RECT bnds);

virtual void SetColor(unsigned char r, unsigned char g, unsigned char b);

virtual void Draw(HDC dc);

};

CBALL.cpp:

#include "CBALL.h"

CBALL::CBALL(void)

{

}

CBALL::~CBALL(void)

{

}

void CBALL::SetParams(double x, double y, double r, double v_x, double v_y, RECT rect)

{

this->x = x;

this->y = y;

this->r = r;

this->v_x = v_x;

this->v_y = v_y;

this->rect = rect;

}

void CBALL::Draw(HDC dc)

{

Ellipse(dc, x - r, y - r, x + r, y + r);

}

void CBALL::Move(DWORD delta_ticks)

{

double s_delta = ((double)delta_ticks) / 1000.0;

if ((this->x >= rect.right - r) && (this->v_x > 0))

this->v_x = -(this->v_x);

if ((this->x <= r) && (this->v_x < 0))

this->v_x = -(this->v_x);

if ((this->y >= rect.bottom - r) && (this->v_y > 0))

this->v_y = -(this->v_y);

if ((this->y <= r) && (this->v_y < 0))

this->v_y = -(this->v_y);

double dx = v_x * s_delta;

double dy = v_y * s_delta;

this->x += dx;

this->y += dy;

}

void CBALL::SetBounds(RECT bnds)

{

this->rect = bnds;

}

void CBALL::SetColor(unsigned char r, unsigned char g, unsigned char b)

{

}

Описание и реализация классаBallsArray:

BallsArray.h:

#pragma once

#include "CBALL.h"

#include "ColoredBall.h"

class CBallsArray

{

CBALL* *balls;

int count;

int max_balls;

public:

CBallsArray(int max_balls);

virtual ~CBallsArray(void);

CBALL* Add();

void SetBounds(RECT bnds);

void Move(DWORD ticks);

void Draw(HDC dc);

CColoredBall* AddColoredBall();

};

BallsArray.cpp:

#include "BallsArray.h"

CBallsArray::CBallsArray(int max_balls)

{

this->count = 0;

this->max_balls = max_balls;

this->balls = new CBALL* [max_balls];

}

CBallsArray::~CBallsArray(void)

{

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

delete this->balls[i];

delete [] this->balls;

}

CBALL* CBallsArray::Add()

{

if (count >= max_balls)

return NULL;

count++;

balls[count - 1] = new CBALL();

return balls[count - 1];

}

void CBallsArray::Draw(HDC dc)

{

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

balls[i]->Draw(dc);

}

void CBallsArray::Move(DWORD ticks)

{

CBALL* ball1;

CBALL* ball2;

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

{

for (int j = i + 1; i < count; i++)

{

ball1 = this->balls[i];

ball2 = this->balls[j];

double C_x = ball2->x - ball1->x;

double C_y = ball2->y - ball1->x;

double C2 = C_x * C_x + C_y * C_y;

if (C2 <= ((ball1->r + ball2->r) * (ball1->r + ball2->r)))

{

double AC_scalar = ball1->v_x * C_x + ball1->v_y * C_y;

double BC_scalar = ball2->v_x * C_x + ball2->v_y * C_y;

double Ap_v_x = (C_x * AC_scalar) / C2;

double Ap_v_y = (C_y * AC_scalar) / C2;

double At_v_x = ball1->v_x - Ap_v_x;

double At_v_y = ball1->v_y - Ap_v_y;

double Bp_v_x = (C_x * BC_scalar) / C2;

double Bp_v_y = (C_y * BC_scalar) / C2;

double Bt_v_x = ball1->v_x - Bp_v_x;

double Bt_v_y = ball1->v_y - Bp_v_y;

ball1->v_x = Bp_v_x + At_v_x;

ball1->v_y = Bp_v_x + At_v_x;

ball2->v_x = Ap_v_x + Bt_v_x;

ball2->v_y = Ap_v_x + Bt_v_x;

}

}

}

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

balls[i]->Move(ticks);

}

void CBallsArray::SetBounds(RECT bnds)

{

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

balls[i]->SetBounds(bnds);

}

CColoredBall* CBallsArray::AddColoredBall()

{

if (count >= max_balls)

return NULL;

count++;

balls[count - 1] = new CColoredBall();

return (CColoredBall*)(balls[count - 1]);

}

Описание и реализация класса ColoredBall:

ColoredBall.h:

#pragma once

#include "CBALL.h"

class CColoredBall :

public CBALL

{

HBRUSH brush;

public:

CColoredBall(void);

virtual ~CColoredBall(void);

virtual void SetColor(unsigned char r, unsigned char g, unsigned char b);

virtual void Draw(HDC dc);

};

ColoredBall.cpp:

#include "ColoredBall.h"

CColoredBall::CColoredBall(void)

{

this->brush = CreateSolidBrush(RGB(0, 0, 255));

}

CColoredBall::~CColoredBall(void)

{

DeleteBrush(this->brush);

}

void CColoredBall::SetColor(unsigned char r, unsigned char g, unsigned char b)

{

DeleteBrush(this->brush);

this->brush = CreateSolidBrush(RGB(r, g, b));

}

void CColoredBall::Draw(HDC dc)

{

HBRUSH old = SelectBrush(dc, this->brush);

Ellipse(dc, x-r, y-r, x+r, y+r);

SelectBrush(dc, old);

}

Описание и реализация класса CballSettingsmonitor:

CballSettingsmonitor.h:

#pragma once

#include <windows.h>

#include <windowsx.h>

#include "math.h"

#include "CBALL.h"

class CCBallSettingsMonitor

{

double angle;

double speed;

double R;

public:

CCBallSettingsMonitor(void);

~CCBallSettingsMonitor(void);

void Draw(HDC dc);

void SpeedUp();

void SpeedDown();

void AngleUp();

void AngleDown();

void BallBigger();

void BallSmaller();

void GetVXVY(double& v_x, double& v_y);

void GetR(double& r);

};

CballSettingsmonitor.cpp:

#include "CBallSettingsMonitor.h"

CCBallSettingsMonitor::CCBallSettingsMonitor(void)

{

this->angle = 45;

this->speed = 50;

this->R = 10;

}

CCBallSettingsMonitor::~CCBallSettingsMonitor()

{

}

void CCBallSettingsMonitor::SpeedUp()

{

if (this->speed < 120)

speed++;

}

void CCBallSettingsMonitor::SpeedDown()

{

if (this->speed > 10)

speed--;

}

void CCBallSettingsMonitor::BallBigger()

{

if (this->R < 50)

R++;

}

void CCBallSettingsMonitor::BallSmaller()

{

if (this->R >2)

R--;

}

void CCBallSettingsMonitor::AngleUp()

{

angle++;

if (angle >= 360)

angle = 0;

}

void CCBallSettingsMonitor::AngleDown()

{

angle--;

if (angle <= 0)

angle = 360;

}

void CCBallSettingsMonitor::GetR(double& r)

{

r = this->R;

}

void CCBallSettingsMonitor::GetVXVY(double& v_x, double& v_y)

{

double rad_angle = (this->angle / 180) * 3.1415;

v_x = this->speed * cos(rad_angle);

v_y = this->speed * sin(rad_angle);

}

void CCBallSettingsMonitor::Draw(HDC dc)

{

double halfspeed = ((this-> speed / 120) * 30) / 2;

double rad_angle = (this->angle / 180) * 3.1415;

double x = halfspeed * cos(rad_angle);

double y = halfspeed * sin(rad_angle);

Rectangle(dc, 0, 0, 30, 30);

MoveToEx(dc, 15 - x, 15 - y, NULL);

LineTo(dc, 15 + x, 15 + y);

Ellipse(dc, 15 + x - 2, 15 + y - 2, 15 + x + 2, 15 + y + 2);

}

Основная функция:

#include <windows.h>

#include <iostream>

#include "CBALL.h"

#include "BallsArray.h"

#include "CBallSettingsMonitor.h"

#include "ColoredBall.h"

using namespace std;

int g_nCmdShow;

HWND g_mainWnd;

HINSTANCE g_hInstance;

DWORD prev_frame_time;

CBallsArray balls(50);

RECT rect_wndSize;

CCBallSettingsMonitor monitor;

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

switch (msg)

{

case WM_DESTROY:

{

PostQuitMessage(0);

return 0;

}

case WM_PAINT:

{

HDC hDC;

PAINTSTRUCT ps;

hDC = BeginPaint(hWnd, &ps);

balls.Draw(hDC);

monitor.Draw(hDC);

EndPaint(hWnd, &ps);

return 0;

}

case WM_SIZE:

{

rect_wndSize.top = 0;

rect_wndSize.left = 0;

rect_wndSize.bottom = HIWORD(lParam);

rect_wndSize.right = LOWORD(lParam);

balls.SetBounds(rect_wndSize);

return 0;

}

case WM_LBUTTONUP:

{

double xpos = GET_X_LPARAM(lParam);

double ypos = GET_Y_LPARAM(lParam);

CBALL* ball = balls.Add();

if (ball != NULL)

{

double v_x, v_y;

double r;

monitor.GetR(r);

monitor.GetVXVY(v_x, v_y);

ball->SetParams(xpos, ypos, r, v_x, v_y, rect_wndSize);

}

return 0;

}

case WM_KEYDOWN:

{

switch (wParam)

{

case VK_DOWN:

monitor.SpeedDown();

return 0;

case VK_UP:

monitor.SpeedUp();

return 0;

case VK_LEFT:

monitor.AngleUp();

return 0;

case VK_RIGHT:

monitor.AngleDown();

return 0;

case VK_F1:

monitor.BallBigger();

return 0;

case VK_F2:

monitor.BallSmaller();

return 0;

}

break;

}

case WM_RBUTTONUP:

{

double xpos = GET_X_LPARAM(lParam);

double ypos = GET_Y_LPARAM(lParam);

CColoredBall* ball = balls.AddColoredBall();

if (ball != NULL)

{

double v_x, v_y;

double r;

monitor.GetVXVY(v_x, v_y);

monitor.GetR(r);

ball->SetColor(0, 255, 0);

ball->SetParams(xpos, ypos, r, v_x, v_y, rect_wndSize);

}

return 0;

}

default:

break;

}

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

}

void OnIdle()

{

DWORD cur_time = GetTickCount();

DWORD delta_time = cur_time - prev_frame_time;

balls.Move(delta_time);

prev_frame_time = cur_time;

InvalidateRect(g_mainWnd, NULL, TRUE);

}

WPARAM StartMessageLoop()

{

MSG msg;

while (1)

{

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

{

if (msg.message == WM_QUIT)

break;

DispatchMessage(&msg);

}

else

{

Sleep(20);

OnIdle();

}

}

return msg.wParam;

}

BOOL InitWindow()

{

g_mainWnd = CreateWindow(L"LabRab1", L"Лабораторная работа №1",

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, CW_USEDEFAULT,

400, 400,

0, 0,

g_hInstance,

0);

if (!g_mainWnd) return FALSE;

ShowWindow(g_mainWnd, g_nCmdShow);

UpdateWindow(g_mainWnd);

return TRUE;

}

BOOL InitAppClass()

{

ATOM class_id;

WNDCLASS wc;

memset(&wc, 0, sizeof(wc));

wc.lpszMenuName = NULL;

wc.style = CS_HREDRAW | CS_VREDRAW;

wc.lpfnWndProc = (WNDPROC)WndProc;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hInstance = g_hInstance;

wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

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

wc.lpszClassName = L"LabRab1";

class_id = RegisterClass(&wc);

if (class_id != 0)

return TRUE;

return FALSE;

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

{

prev_frame_time = GetTickCount();

g_hInstance = hInstance;

g_nCmdShow = nCmdShow;

if (!InitAppClass())

return 0;

if (!InitWindow())

return 0;

RECT cr;

CBALL* ball;

ball = balls.Add();

ball->SetParams(10, 10, 2, 50, 50, rect_wndSize);

ball = balls.Add();

ball->SetParams(10, 10, 2, -70, -70, rect_wndSize);

GetClientRect(g_mainWnd, &cr);

return StartMessageLoop();

}

Реализация кода: