Прикладное программирование 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();
}
Реализация кода:
