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

3 лаба / w3_v4

.cpp
Скачиваний:
8
Добавлен:
09.12.2013
Размер:
6.28 Кб
Скачать
#include <grx20.h>
#include <grxkeys.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

int m = 1000; //максимальное количество объектов

/* Структура "Точка" */
struct TPoint {
	/* переменные */
	int x, y, // координаы объекта
		color, // цвет объекта
		vx, vy; // векторы скорости
	TPoint(int ix, int iy, int ivx, int ivy, int icolor); // конструктор
	virtual ~TPoint(); // деструктор (вызывается при удалении объекта)
	virtual void Draw(int icolor); // отрисовка объекта цветом "color"
	void Show(); // показ объекта
	void Hide(); // скрытие объекта
	void MoveXY(int ix, int iy); // перемещение объекта
};

/* Структура "Прямоугольник", предком данной структуры является структура "Точка" */
struct TBox:public TPoint {
	int w, h; // длина и высота прямоугольника
	TBox(int ix, int iy, int ivx, int ivy, int icolor, int iw, int ih);
	virtual ~TBox();
	virtual void Draw(int icolor);
};

/* Структура "Окружность", предком данной структуры является структура "Точка" */
struct TCircle:public TPoint {
	int r; // радиус окружности
	TCircle(int ix, int iy, int ivx, int ivy, int icolor, int r);
	virtual ~TCircle();
	virtual void Draw(int icolor);
};

/* Описание функций структуры "Точка" */
/* >>> */
TPoint::TPoint(int ix, int iy, int ivx, int ivy, int icolor) {
	x = ix; y = iy; vx = ivx; vy = ivy; color = icolor;
}

TPoint::~TPoint() {
	Hide(); // при удалении объект скрывается
}

void TPoint::Draw(int icolor) {
	GrFilledCircle(x, y, 1, icolor); // Окружность с радиусом 1
}

void TPoint::Show() {
	Draw(color);
}

void TPoint::Hide() {
	Draw(GrAllocColor(0, 0, 0)); // отрисовка фоновым цветом
}

void TPoint::MoveXY(int ix, int iy) {
	Hide();
	/* закольцовка экрана */
	/* >>> */
	if (ix > GrMaxX()) x = ix - GrMaxX() - 1;
	else if (ix < 0) x = GrMaxX() + ix + 1;
	else if (iy > GrMaxY()) y = iy - GrMaxY() - 1;
	else if (iy < 0) y = GrMaxY() + iy + 1;
	else {x = ix; y = iy;}
	/* <<< */
	Show();
}
/* <<< */

/* Описание функций структуры "Прямоугольник" */
/* >>> */
TBox::TBox(int ix, int iy, int ivx, int ivy, int icolor, int iw, int ih):TPoint(ix, iy, ivx, ivy, icolor) {
	w = iw;	h = ih;
}

TBox::~TBox() {
	Hide();
}

void TBox::Draw(int icolor) {
	GrBox(x - w / 2, y - h / 2, x + (w - w / 2), y + (h - h / 2), icolor); // прямоугольник длиной w и высотой h
} 
/* <<< */

/* Описание функций структуры "Окружость" */
/* >>> */
TCircle::TCircle(int ix, int iy, int ivx, int ivy, int icolor, int ir):TPoint(ix, iy, ivx, ivy, icolor) {
	r = ir;
}

TCircle::~TCircle() {
	Hide();
}

void TCircle::Draw(int icolor) {
	GrCircle(x, y, r, icolor); // окружность с радиусом r
}
/* <<< */

/* Структура, в которой хранятся координаты сбора объектов */
struct Center {
	int x, y;
};

int main() {
int state = 0; // 0 - объекты свободно перемещаются, 1 - объекты направляются в Centrer
TPoint * obj[m]; // массив указателей типа TPoint
Center center; // переменная типа Center
srand(time(NULL)); // обновление ключа генератора псевдослучайных чисел
GrSetMode(GR_width_height_color_graphics, 900, 500, GrAllocColor(0, 0, 0)); // создание графического окна
int k = 0, // используется для выбора добавяемого объекта при нажатии клавиши Insert
	n = 0, // количество созданных объектов
	finish; // 1 - все объекты собрались в одной точке */
/* задание точки сбора */
/* >>> */
center.x = GrMaxX() / 2 + rand() % (GrMaxX() / 10) - rand() % (GrMaxX() / 10);
center.y = GrMaxY() / 2 + rand() % (GrMaxY() / 10) - rand() % (GrMaxY() / 10);
/* <<< */
GrKeyType key; // переменная, в которую считывается нажатая клавиша
do {
	while (!GrKeyPressed()) { // пока не нажата клавиша
		GrSleep(10); // пауза 10 мсек
		if(state == 1) { // если объекты должны начать собираться,
						 // то отправляем их по очереди в центр
			for (int i = 0; i < n; i++) {
				obj[i] -> vx = (center.x - obj[i] -> x) / 10 + rand() % 7 - 3;
				obj[i] -> vy = (center.y - obj[i] -> y) / 10 + rand() % 7 - 3;
			}
			finish = 1;
			/* проверка сбора объектов в центре */
			/* >>>> */
			for(int i = 0; i < n && finish == 1; i++) {
				if(fabs(center.x - obj[i] -> x) > 20 || fabs(center.y - obj[i] -> y) > 20) finish = 0;
				else finish = 1;
			}
			/* <<< */
			if(finish == 1) { // если все объектры собрались
				state = 0; // то устанавливаем свободное перемещение
				for(int i = 0; i < n; i++) { // и задаем случайные векторы скоростей
					obj[i] -> vx = rand() % 11 - 5;
					obj[i] -> vy = rand() % 11 - 5;
				}
			}
		}
		/* Перещение объектов */
		/* >>> */
		for(int i = 0; i < n; i++) {
			obj[i] -> MoveXY(obj[i] -> x + obj[i] -> vx, obj[i] -> y + obj[i] -> vy);
		}
		/* <<< */
		if (rand() % 50 == 1 && state == 0) { // собираем элементы в случайный момент времени
			state = 1;
			center.x = GrMaxX() / 2 + rand() % (GrMaxX() / 10) - rand() % (GrMaxX() / 10);
			center.y = GrMaxY() / 2 + rand() % (GrMaxY() / 10) - rand() % (GrMaxY() / 10);
		}
	}
	key = GrKeyRead(); // считывание клавиши в переменную key
	switch(key) { // выбор по нажатой клавише
		/* добавление и показ случайно выбранного объекта */
		/* >>> */
		case GrKey_Insert: 
			if (n < m) { 
				k = rand() % 3;
				switch (k) {
					case 0:
						obj[n] = new TPoint(GrMaxX() / 2, GrMaxY() / 2, rand() % 11 - 5, rand() % 11 - 5, GrAllocColor(rand() % 256, rand() % 256, rand() % 256));
						break;
					case 1:
						obj[n] = new TBox(GrMaxX() / 2, GrMaxY() / 2, rand() % 11 - 5, rand() % 11 - 5, GrAllocColor(rand() % 256, rand() % 256, rand() % 256), rand() % 20, rand() % 20);
						break;
					case 2:
						obj[n] = new TCircle(GrMaxX() / 2, GrMaxY() / 2, rand() % 11 - 5, rand() % 11 - 5, GrAllocColor(rand() % 256, rand() % 256, rand() % 256), rand() % 20);
						break;
				}
			obj[n] -> Show();
			n++;
			} 
			break; 
		/* <<< */
		/* удаление последнего добавленного объекта */
		/* >>> */
		case GrKey_Delete: 
			if (n > 0) { 
				delete obj[n - 1]; 
				n--;
			} 
			break; 
		/* <<< */
	} 
} while(key != GrKey_Escape); // прекращаем процесс и закрываем окно при нажатии клавиши Escape

/* Удаление объектов */
/* >>> */
for(int i = 0; i < n; i++)
{
	delete obj[i];
}
/* <<< */
return 0;
}