new Bitmap(myAssembly.GetManifestResourceStream(
myName_of_project + "." + "cheese.JPG"));
//We draw the image on the Form1:
e.Graphics.DrawImage(cheeseImage, cx, cy);
//We turn on the timer:
timer1.Enabled = true;
}
Теперь всякий раз, когда вызывается метод Form1_Paint, программа рисует сыр на экране с соответствующими координатами cx и cy.
Дважды щёлкаем по значку для компонента Timer (ниже формы в режиме проектирования). Появляется шаблон метода timer1_Tick, который после записи нашего метода updatePositions и библиотечного метода Invalidate (или Refresh) для перерисовки изображения на экране принимает следующий вид.
Листинг 4.4. Метод для смены кадров на экране и перемещения фигуры.
private void timer1_Tick(object sender, EventArgs e)
{
//We call the method:
updatePositions();
//We redraw the screen:
Invalidate();
}
Строим и запускаем программу на выполнение обычным образом:
Build, Build Selection; Debug, Start Without Debugging.
В ответ Visual C# выводит форму Form1 в режиме выполнения, на которой изображение типа встроенного нами рисунка сыра cheese.jpg перемещается из верхнего левого угла по диагонали сверху вниз (в нижний правый угол) и скрывается (рис. 4.3).
Рис. 4.3. Объект перемещается по диагонали сверху вниз. Рис. 4.4. Отскок объекта.
Изображение объекта мерцает, что в дальнейшем будет исправлено применением двойной буферизации.
Таким образом, мы разработали методику анимации, по которой можно перемещать любые объекты на экране .
4.3. Методика проектирования отскока объекта от границы
Разработаем методику решения задачи по отскоку заданного нами объекта от заданных нами границ, например, от границ экрана. В качестве предмета и замкнутого пространства могут быть, например:
резиновый мяч, металлический или пластмассовый шар, который с большой силой бросил человек в каком-то помещении; предмет летает внутри помещения и отскакивает от пола, потолка и стен этого помещения;
пуля, выпущенная из огнестрельного оружия, например, стальная дробь, выпущенная из охотничьего ружья в комнате и в полёте отскакивающая от пола, потолка и стен этой комнаты.
На практике подобные очень сложные задачи решаются после ввода в постановку задачи большого числа допущений.
Мы также введём большое число допущений, после чего задачу формулируем таким образом:
решаем плоскую задачу, т.е. предмет изображаем в виде его проекции на плоскость “x, y”; в качестве примера предмета выбираем кусочек сыра cheese.jpg, проекция которого на плоскость имеет вид прямоугольника;
на этой плоскости “x, y” замкнутое пространство изображаем в виде задаваемой нами замкнутой линии; в качестве примера замкнутой линии выбираем прямоугольник границы экрана;
предмет перемещается в этой плоскости “x, y” до столкновения с границей (линией), а после удара о границу должен отскочить от границы под определённым углом и перемещаться до следующего столкновения с границей, и так далее перемещаться и отражаться от линии;
принимаем обычное допущение, что до столкновения с границей предмет перемещается (летит) по прямой линии;
на основании допущения о том, что угол падения равен углу отражения, принимаем, что после столкновения с линией прямоугольника предмет отскакивает от этой линии под тем же углом; величину угла падения и угла отражения предмета от прямой линии принимаем равной 45 градусам;
перемещение предмета осуществляется поэтапно за интервал времени, который мы установим с помощью компонента Timer (Таймер);
интервал времени устанавливаем по значению свойства Interval компонента Timer; таким образом скорость перемещения объекта можно изменять за счёт изменения свойства Interval;
анимация является бесконечным (если в него не вмешиваться) нециклическим процессом; анимацию можно остановить на любом этапе и запустить вновь.
Для решения этой задачи программа должна отслеживать текущую позицию (в виде координат) объекта, и затем, когда значение одной из двух координат объекта станет равным значению одной из двух координат границы, изменить координаты объекта в противоположном от границы направлении.
Таким образом, в данном проекте приведённый выше метод updatePositions заменяем на следующий.
Листинг 4.5. Отскок объекта от границ.
//Movement on an axis "x" to the right:
bool goingRight = true;
//Movement on an axis of "y" to the down:
bool goingDown = true;
private void updatePositions()
{
if (goingRight)
{
cx++;
}