
3. Результаты тестирования программы
Рисунок 1 - Внешний вид программы.
Рисунок 2 – Вид объектов с хаотичным движением.
Рисунок 3 - Вид управляемых объектов.
Рисунок 4 – Закон отражения.
Заключение
В результате курсовой работы мной была составлена программа имитирующая движение одного или нескольких объектов в ограниченном пространстве; а) когда объект движется хаотически, б) является управляемым и в) подчиняется закону отражения при прямолинейном движении. Среда обитания Visual Studio 2012. В работе приведены теоретические сведения, алгоритм данной программы, листинг исходного кода программы на языке C#.
Список литературы:
1. Савельев А.Я. Основы информатики: Учебник для вузов. –М.:Издательство МГТУ им. Н.Э. Баумана, 2001. – 328 с., ил.
2. Методические указания к курсовой работе для студентов всех
специальностей / АМТИ, сост.: А.Д. Ткаченко. Армавир 2000.
3. Герберт Шилдт. C# 4.0 Полное руководство, издательство: Вильямс, 2013г.
4. Михаил Абрамян . Visual C# на примерах, издательство : БХВ-Петербург, 2012г.
5. Андерс Хейлмберг. Язык программирования C#, издательство: Питер, 2012г.
Приложение а
Листинг программы
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Motion
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//Класс движения
class motion
{
private int stepX, stepY; //Смещения по X и Y - для закона отражения
private int status; //Тип движения: 0 - хаотичное движение, 1 - управляемое, 2 - закон отражения
private int x, y; //Координаты центра объекта по X и Y
private int width, height; //Ширина и высота объекта
public static PictureBox pictureBox; //Наш объект для прорисовки
//Конструктор класса
public motion()
{
Random random = new Random(); //Для генерации случайных чисел
this.width = random.Next(50, 150); //Генерируем любую ширину от 50 до 150
this.height = this.width; //Высота будет равнять ширире
this.x = random.Next(this.width, pictureBox.Width) - this.width; //Генерируем позицию по X
this.y = random.Next(this.height, pictureBox.Height) - this.height; //Генерируем позицию по Y
this.stepX = random.Next(7, 15); //Генерируем шаг по X
this.stepY = random.Next(7, 15); //Генерируем шаг по Y
}
//Установить шаги X и Y
public void setStep(int STEPX, int STEPY)
{
this.stepX = STEPX; //Шаг по X
this.stepY = STEPY; //Шаг по Y
}
//Установить статус объекта
public void setStatus(int STATUS)
{
this.status = (STATUS >=0 && STATUS <= 2) ? STATUS : 2;
}
//Установить позицию центра
public void setCenter(int X, int Y)
{
this.x = X;
this.y = Y;
}
//Установить размер объекта
public void setSize(int WIDTH, int HEIGHT)
{
this.width = WIDTH;
this.height = HEIGHT;
}
//Прорисовка объекта
public void draw(object sender, PaintEventArgs e)
{
Graphics graphic = e.Graphics; //Область рисования
Pen pen; //Бордюр объекта
if (this.status == 0) pen = new Pen(Color.Black, 2); //Хаотичный объект - черного цвета
else if (this.status == 1) pen = new Pen(Color.Red, 2); //Управляемый объект - красного цвета
else pen = new Pen(Color.Blue, 2); //Объект, подчиняющийся закону отражения - синего цвета
if (this.status == 1) //Если объект управляемый
{
graphic.DrawRectangle(pen, new Rectangle(this.x, this.y, this.width, this.height)); //Рисуем квадрат
}
else
{
graphic.DrawEllipse(pen, new Rectangle(this.x, this.y, this.width, this.height)); //Рисуем круг
}
}
//Получить ширину объекта
public int getWidth()
{
return this.width;
}
//Получить высоту объекта
public int getHeight()
{
return this.height;
}
//Получить тип объекта
public int getStatus()
{
return this.status;
}
//Получить координату X
public int getX()
{
return this.x;
}
//Получить координату Y
public int getY()
{
return this.y;
}
//Получить шаг по X
public int getStepX()
{
return this.stepX;
}
//Получить шаг по Y
public int getStepY()
{
return this.stepY;
}
}
//Список объектов движения
List<motion> listOfRandom = new List<motion>(); //Список хаотичных объектов
List<motion> listOfDrivers = new List<motion>(); //Список управляемых объектов
List<motion> listOfMirrors = new List<motion>(); //Список объектов, подчиняющихся закону отражения
motion moveObject; //Хранится ссылка на управляемый объект
bool selectedObject; //Флаг, если нажали по управляемому объекту
int selX, selY; //Координаты X и Y нажатия по pictureBox
//Событие создания формы
private void Form1_Load(object sender, EventArgs e)
{
motion.pictureBox = pictureBox1; //Установим pictureBox для класса, чтобы мы могли определять размеры pictureBox
button1_Click(sender, e); //Нажмем сразу по кнопке "Добавить"
}
//Событие прорисовки на pictureBox1
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(Color.White);
//Если есть хаотичные объекты, то
if (listOfRandom.Count > 0)
{
//В цикле прорисовывем каждый объект
foreach (motion o in listOfRandom) o.draw(sender, e);
}
//Если есть управляемые объекты, то
if (listOfDrivers.Count > 0)
{
//В цикле прорисовывем каждый объект
foreach (motion o in listOfDrivers) o.draw(sender, e);
}
//Если есть объекты, подчиняющиеся закону отражения, то
if (listOfMirrors.Count > 0)
{
//В цикле прорисовывем каждый объект
foreach (motion o in listOfMirrors) o.draw(sender, e);
}
}
//Нажатие на кнопку "Добавить"
private void button1_Click(object sender, EventArgs e)
{
//В цикле от 1 до установленного числа будем создавать объекты
for (int i = 1; i <= numericUpDown1.Value; i++)
{
motion m = new motion(); //Создадим объект на основе нашего класса
//Если выбрано "Хаотичное движение"
if (radioButton1.Checked)
{
m.setStatus(0); //Установим у объекта статус 0
listOfRandom.Add(m); //Добавим созданный объект в список хаотичных объектов
}
//Если выбрано "Управляемый" объект
else if (radioButton2.Checked)
{
m.setStatus(1); //Установим статус 1
listOfDrivers.Add(m); //Добавим созданный объект в список управляемых объектов
pictureBox1.Invalidate();
}
//Иначе выбран объект, подчиняющийся законам отражения
else
{
m.setStatus(2); //Установим у объекта статус 2
listOfMirrors.Add(m); //Добавим созданный объект в список объектов, подчиняющихся закону отражения
}
System.Threading.Thread.Sleep(50); //Пауза в 50 мс для точной генерции случайного числа
}
//Если количество объктов, подчиняющихся законам отражения, больше нуля, то включим таймер1
if (listOfMirrors.Count > 0) timer1.Enabled = true;
//Если количество хаотичных объктов больше нуля, то включим таймер2
if (listOfRandom.Count > 0) timer2.Enabled = true;
}
//Таймер 1, отвечающий за объекты, подчиняющиеся законам отражения
private void timer1_Tick(object sender, EventArgs e)
{
//Если этих объектов нет
if (listOfMirrors.Count == 0)
{
timer1.Enabled = false; //Выключить таймер
return; //Прервать выполнение
}
//В цикле обходим все созданные объекты
foreach (motion m in listOfMirrors)
{
int w = m.getWidth(); //Получаем ширину
int h = m.getHeight(); //Получаем высоту
int x = m.getX(); //Получаем координату X
int y = m.getY();//Получаем координату Y
int sX = m.getStepX(); //Получаем шаг смещения по X
int sY = m.getStepY(); //Получаем шаг смещения по Y
//Если координаты по X выходят за пределы pictureBox или равны нулю, то сменим шаг по X на противоположный
if (x + w >= pictureBox1.Width || x + w <= w) sX *= -1;
//Если координаты по Y выходят за пределы pictureBox или равны нулю, то сменим шаг по Y на противоположный
if (y + h >= pictureBox1.Height || y + h <= h) sY *= -1;
m.setCenter(x + sX, y + sY); //Установим координаты центра
m.setStep(sX, sY); //Установим новый шаг
}
pictureBox1.Invalidate(); //Прорисуем все это на pictureBox1
}
//Таймер 2, отвечающий за объекты с хаотичным движением
private void timer2_Tick(object sender, EventArgs e)
{
//Если этих объектов нет
if (listOfRandom.Count == 0)
{
timer2.Enabled = false; //Выключить таймер
return; //Прервать выполнение
}
Random r = new Random(); //Случайное число
//В цикле обходим все созданные объекты
foreach (motion m in listOfRandom)
{
if (m.getStatus() == 0) //Если это хаотичный объект
{
int w = m.getWidth(); //Получаем ширину
int h = m.getHeight(); //Получаем высоту
m.setCenter(r.Next(w, pictureBox1.Width) - w, r.Next(h, pictureBox1.Height) - h); //Устанавливаем новый случайный центр объекта
}
}
pictureBox1.Invalidate(); //Прорисуем все это на pictureBox1
}
//Нажатие по кнопке "Очистить"
private void button2_Click(object sender, EventArgs e)
{
listOfRandom.Clear(); //Очищаем список хаотичных объектов
listOfDrivers.Clear(); //Очищаем список управляемых объектов
listOfMirrors.Clear(); //Очищаем список объектов, подчиняющихся закону отражения
pictureBox1.Invalidate(); //Обновим pictureBox1
}
//Событие нажатия кнопки мыши по pictureBox1
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (listOfDrivers.Count == 0) return; //Если не было создано управляемых объектов
//В цикле пройдем все созданные объекты
foreach (motion m in listOfDrivers)
{
int w = m.getWidth(); //Получаем ширину
int h = m.getHeight(); //Получаем высоту
int x = m.getX(); //Получаем координату X
int y = m.getY(); //Получаем координату Y
//Если нажатие было в пределе нашего объекта, то
if ((e.X <= x + w && e.Y <= y + h) && (e.X >= x && e.Y >= y))
{
moveObject = m; //Ссылаться на данный объект
selectedObject = true; //Установить флаг, что объект выбран
selX = e.X; //Установить коордианы клика по X
selY = e.Y; //Установить коордианы клика по Y
pictureBox1.Cursor = Cursors.SizeAll; //Изменим тип курсора
return; //Прервать дальнейшее выполнение
}
//Иначе
else
{
selectedObject = false; //Установить флаг, что объект не был выбран
}
}
}
//Событие перемещения мыши по pictureBox1
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (!selectedObject) return; //Если объект не был выбран, то ничего не делаем
//Установим позицию центра нашего объекта
moveObject.setCenter(e.X - (e.X - selX), e.Y - (e.Y - selY));
selX = e.X; //Переустановим коордианты клика по X
selY = e.Y; //Переустановим коордианты клика по Y
pictureBox1.Invalidate(); //Обновим все на pictureBox1
}
//Событие, срабатываемое, когда кнопка мыши отпускается
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
moveObject = null; //Уберем ссылку на управляемый объект
selectedObject = false; //Установим флаг, что объект не был выбран
pictureBox1.Cursor = Cursors.Default; //Изменим тип курса по умолчанию
}
}
}