Проект anim1 с пустым окном

0) Main Menu в VC# 2010 Express: Tools → Options → Show all Settings → Projects and Solutions → Visual Studio projects location: → C:\temp

1) Main Menu в VC# 2010 Express: File → New Project... →
Installed Templates: Windows Forms Application
Name: anim1
→ OK
Появится Form1.cs[Design].

2) Стереть два лишних файла: Form1.Designer.cs и Program.cs. Открыть Solution Explorer - draw1anim1 и после открыть ветку Form1.cs. Кликнуть правой кнопкой на Program.cs. Откроется контекстное меню - кликнуть на DeleteПоявится Message Box : "'Program.cs' will be deleted permanently". Кликнуть ОК. Так же удалите Form1.Designer.cs (не стирайте элемент Form1 полностью - он нужен).Также удалить и нажать на стрелку или плюс для открытия ветки - элемент в дереве проекта Вы найдете эти файлы в окне и

3)Кликните правой кнопкой мыши на Form1. Откроется контекстное меню. Кликните на View Code.
Вы увидите код, созданный автоматически при создании проекта для окна Form1.cs. Сотрите этот код полностью.

4)Напишите в полностью очищенном окне следующие четыре строчки кода:

public class Form1 : System.Windows.Forms.Form

   static void Main() { System.Windows.Forms.Application.Run( newForm
1() ); }
}

5) Кликните Debug в MainMenu. Откроется подменю. Кликните на Start Without Debugging CtrlF5. Мини-программа автоматически скомпилируется и запустится. Обратите внимание на окно Error List в нижней части основного окна Visual Studio. Список ошибок должен быть пуст. Исправляйте ошибки, начиная сверху. После исправления первой, попробуйте снова скомпилировать код, так как часто одна ошибка синтаксиса создает несколько ошибок компиляции кода.

Важно: Всегда закрывайте все запущенные инстанции приложения anim1 перед тем, как внести изменения в код и скомпилировать новую программу! Если есть сомнения все ли инстанции закрыты, запустите системную программу TaskManager, нажав комбинацию клавиш Ctrl+Alt+Del, и если в списке запущенных процессов найдется anim1.exe– удалите его.

Рисовалка с динамическим массивом данных

Если вы не видите код, - двойной клик по Form1.cs, передаст фокус окну с кодом.
Стирайте весь код и в пустом окне Form1.cs напишите следующий код:

using System;

using System.Drawing; 
using System.Windows.Forms; 
using System.Collections; 
public class Form1 : Form { 
	[STAThread] static void Main() 
	{ 
		Application.Run( new Form1() ); 
	} 
	static Graphics g; 
	static Single zoom = 1.01f; 
	static Single cosinus = (Single)Math.Cos( Math.PI/180.0 ); 
	static Single sinus = (Single)Math.Sin( Math.PI/180.0 ); 
	static Brush redbrush = new SolidBrush( Color.Red ); 
	static Pen blackpen = SystemPens.ControlText; 
	static Font arial10 = new Font( "Arial", 10 ); 
	static Int32 myWidth, myHeight; static PointF[] pf; 
	ArrayList polygon = new ArrayList(); 
	Point p0, p1; 
	public Form1() 
	{ 
		Text = "Anim1: Draw an Endless Animation"; 
		Width = 800; 
		Height = 600; 
		g = this.CreateGraphics(); 
		SetStyle(ControlStyles.ResizeRedraw,true); 
	} 
	protected override void OnMouseDown( MouseEventArgs e ) 
	{ 
		polygon.Clear(); 
		Invalidate(); 
		p0 = e.Location; polygon.Add( p0 ); 
	} 
	protected override void OnMouseMove( MouseEventArgs e ) 
	{ 
		if ( e.Button == MouseButtons.None ) return; 
		p1 = e.Location; 
		Int32 dx = p1.X - p0.X; 
		Int32 dy = p1.Y - p0.Y; 
		if ( dx*dx + dy*dy < 100 ) return; 
		g.DrawLine( blackpen, p0, p1 ); 
		polygon.Add( p1 ); 
		p0 = p1; 
	} 
	protected override void OnMouseUp( MouseEventArgs e ) 
	{ 
		if ( polygon.Count < 2 ) return; 
		pf = new PointF[polygon.Count]; 
		for ( Int32 i=0; i < polygon.Count; i++ ) 
			pf[i] = (Point)polygon[i]; 
	} 
	protected override void OnPaint( PaintEventArgs e ) 
	{ 
		e.Graphics.DrawString( "Press the left mouse button and move!", 
					Font, redbrush, Width/2-50, 0 ); 
	} 
	protected override void OnResize( System.EventArgs e ) 
	{ 
		g = this.CreateGraphics(); 
		g.Clear( SystemColors.Control ); 
		myWidth = ClientRectangle.Width; 
		myHeight = ClientRectangle.Height; 
	} 
}

Кликните Debug в MainMenu. Откроется подменю. Кликните на Start Without Debugging CtrlF5. Мини-программа автоматически скомпилируется и запустится. Обратите внимание на окно Error List в нижней части основного окна Visual Studio.

Timer

Версия 2: закройте программу anim1.
Допишите в заголовок класса Form1 под строкой Point p0, p1; следующую строку:

Timer myTimer = new Timer();

Допишите в конструкторе public Form1() под строкой SetStyle(ControlStyles.ResizeRedraw,true); следующие две строки:

myTimer.Tick += new EventHandler( OnTimer );

myTimer.Interval = 1;

Напишите первой командой в функции protected override void OnMouseDown( MouseEventArgs e ):

myTimer.Stop();

А последней командой функции protected override void OnMouseUp( MouseEventArgs e ):

myTimer.Start();

Напишите новую функцию protected static void OnTimer(...) след за функцией protected override void OnResize( SystemEventArgs e ), но перед последней фигурной скобкой, закрывающей класс  Form1 :

protected static void OnTimer( Object myObject, EventArgs myEventArgs )
{
   Single x, y, xmin, ymin, xmax, ymax, xmid, ymid;
   xmin = xmax = pf[0].X;
   ymin = ymax = pf[0].Y;
   for ( Int32 i=1; i < pf.Length; i++ )
   {
      x = pf[i].X;
      y = pf[i].Y;
      if ( x < xmin ) xmin = x;
      if ( x > xmax ) xmax = x;
      if ( y < ymin ) ymin = y;
      if ( y > ymax ) ymax = y;
   }
   xmid = (xmin+xmax) / 2;
   ymid = (ymin+ymax) / 2;
   if ( xmin < 0 || ymin < 0 || xmax > myWidth || ymax > myHeight ) {
      g.Clear( SystemColors.Control );
      g.DrawString( "Press the left mouse button and move!", arial10, redbrush, 320, 0 );
      zoom = 0.99f;
   }
   if ( xmax - xmin < 50 || ymax - ymin < 50 ) {
      g.Clear( SystemColors.Control );
      zoom = 1.01f;
   }
   for ( Int32 i=0; i < pf.Length; i++ )
   {
      x = pf[i].X - xmid;
      y = pf[i].Y - ymid;
      x *= zoom;
      y *= zoom;
      Single xx = x*cosinus - y*sinus;
      Single yy = x*sinus + y*cosinus;
      pf[i].X = xx + xmid;
      pf[i].Y = yy + ymid;
   }
   g.DrawLines( blackpen, pf );
}

Кликните на Start Without Debugging CtrlF5.
Нарисуйте фигуру, посмотрите ка она анимируется.

Мерцание

Чтобы не видеть все линии, а только одну двигающуюся - допишите в функции OnTimer
перед g.DrawLines( blackpen, pf ); следующий код:
g.Clear( SystemColors.Control ); - это сотрет клиентскую часть окна (очистит экран).
Теперь мы видим мерцание (особенно на медленных компьютераъх). Эффект виден сильнее, если увеличить ширину линии. Попробуйте поменять static Pen blackpen = new Pen( Color.Black, 20 ); Операция стирания прерывает плавное движение - это основная проблема перемещения графических объектов.
Решение проблемы через использование двойного буфера: стираем и рисуем на резервном (невидимом) буфере (картинке) и затем копируем ее на видимый экран Client Area.
Описание: Определяем второй Graphics -объект в заголовке класса Form1 в строке static Graphics g; и один Bitmap -объект.

  static Graphics g, bitmap_g;
  static Bitmap bitmap;

Создаем новые объекты в функции OnResize:

    if ( bitmap != null ) bitmap.Dispose();
    bitmap = new Bitmap( myWidth, myHeight );
    if ( bitmap_g != null ) bitmap_g.Dispose();
    bitmap_g = Graphics.FromImage( bitmap );

Меняем строки кода в функции OnTimer: g.Clear(SystemColors.Control); и g.DrawLines( blackpen, pf ); на:

    bitmap_g.FillRectangle( SystemBrushes.Control, 0, 0, myWidth, myHeight );
    bitmap_g.DrawLines( blackpen, pf );
    g.DrawImage( bitmap, 0, 0 ); 

Если мерцание продолжилось, то проверьте для начала удалены ли обе строки g.Clear( SystemColors.Control ); и g.DrawLines( blackpen, pf ); в конце функции OnTimer. Если да, то мерцание будет видно только в начале и конце цикла масштабирования. Чтобы это побороть, нужно закомментарить (написать // перед строкой) обе команды g.Clear( SystemColors.Control ); в обоих if-переходах функции OnTimer.

Подумайте как избавится от мерцания красной надписи вверху экрана и решите эту проблему.

Дополнительные задания

Кликните в главном меню Visual Studio Help -> View Help. Кликните папку Index и вбейте в поле фильтров .NET Framework. Затем перейдите в поле поиска и наберите последовательно ключевые слова: Timer class (System.Windows.Forms), Control.OnResize method (System.Windows.Forms), Math.Cos, Math.Sin, Math.PI, static keyword C#, Graphics.Clear Вы получите статьи, поясняющие назначение, синтаксис и примеры использования соответствующих объектов и методов. Прочтите описание всех использованных в этой работе методов. 
Закройте  Visual Studio, запустите Explorer, сотрите полностью директорию C:\temp\anim1.
Снова запустите Visual Studio и создайте туже программу еще раз и повторяйте процесс, пока не сможете создать аналогичную программу с нуля без описания.

Нарисуйте фигуру в правом нижнем углу. Во время проигрывания анимации потяните за рамки окна и понаблюдайте за соответствующими изменениями анимации. Нужно понять роль переменных myWidth и myHeight.
Притормозите скорость анимации через большее значение myTimer.Interval - 10, 100, 1000.
Ускорьте анимации, увеличив угловой шаг с 1-го до 2-х, 4, 6 градусов.


Попробуйте различные варианты программы (под разными названиями  anim2, anim3 и т.д.), на базе приведенных примеров.

Удачи! :)