Прикладное программирование 4 семестр Laba_2
.docМИНОБРНАУКИ РОССИИ
федеральное государственное бюджетное образовательное учреждение
высшего профессионального образования
«Московский государственный технологический университет «СТАНКИН»
(ФГБОУ ВПО МГТУ «СТАНКИН»)
Кафедра «Компьютерные Системы Управления»
«Прикладное Программирование»
Отчёт по лабораторной работе № 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();
}
Реализация кода: