Луна за забором

Типичная задача анимации, когда движущийся объект (например, Луна) становится невидимым за неподвижными объектами (горами, домами, забором).

Используем наш опыт зашиты областей холста (пример с парапланами) с анимацией. Установку забора свяжем с одним событием — кликом на форме, а анимацию — с другим событием — нажатием кнопки «Ночь».

Ваши действия:

На форме размером 900х500 поместим кнопку «Ночь», при нажатии на которую должно потемнеть и по небу мы должны увидеть перемещение Луны. Этому событию поставим в соответствие метод

button1_Click(object sender, EventArgs e)

Тогда метод, задающий появление забора, автоматически будет назван Form1_Click(object sender, EventArgs e).

Создадим два объекта классов Graphics (g) и Region (z).  В конструкторе формы инициализируем холст: g = Graphics.FromHwnd(this.Handle);        Создадим функцию, возвращающую область забора  private Region zabor().  С ее помощью выполним установку и покраску забора:

private void Form1_Click(object sender, EventArgs e)
{
   z = zabor();
   g.FillRegion(Brushes.Peru, z);  // покраска
   g.ExcludeClip(z);  // защита области от изменений
 }

Для перемещения Луны используем метод из предыдущего примера.
Текст файла Form1.cs представлен ниже.

// Заход Луны за забор
// (C) В.А.Рычков,2018
using System;
using System.Drawing;
using System.Windows.Forms;
namespace луна_забор
{
   public partial class Form1 : Form
   {
      Graphics g;     // холст
      Region z;       // область "забор"
      public Form1()
      {
         InitializeComponent();
         g = Graphics.FromHwnd(this.Handle);  // холст
      }
   // задание области "забор"
   private Region zabor()
   {
      int x = 10;
      Rectangle r = new Rectangle(x, 150, 50, 310);
      Region z = new Region(r);
      for (int k = 0; k < 8; k++)
      {
         x += 100;
         r = new Rectangle(x, 150, 50, 310);
         z.Union(r);
      }
      r = new Rectangle(10, 250, 800, 50);
      z.Union(r);
      return z;
   }
   // Установка забора
   private void Form1_Click(object sender, EventArgs e)
   {
      z = zabor();
      g.FillRegion(Brushes.Peru, z);  // покраска
      g.ExcludeClip(z);     // защита области z от изменений
      // ИЛИ g.IntersectClip(z); - тогда рисуем только на заборе
   }
   // Заимствовано из примера "Заход Луны"
   private void button1_Click(object sender, EventArgs e)  // "Ночь"
   {
      Timer timer = new Timer();      // таймер - динамический объект
      timer.Interval = 40;            // тик - каждые 40 миллисекунд
      int count = 0;                  // счетчик перемещений
      int max = 150;                  // их максимальное число
      g.Clear(Color.DarkCyan);        // очистка
      int x = 0;                      // начальные
      int y = 0;                      // координаты
      int d = 90;                     // диаметр шара
      SolidBrush br = new SolidBrush(Color.Yellow); // кисть Луны
      SolidBrush brf = new SolidBrush(Color.DarkCyan); // кисть фона
      g.Clear(Color.DarkCyan);        // очистка
      g.FillEllipse(br, x, y, d, d);  // заливка - первое изображение
   // каждые 40 мс будет удаляться и рисоваться новый шарик, остановка через 150 раз
      timer.Tick += new EventHandler((o, ev) =>
      {
         g.FillEllipse(brf, x, y, d, d);
         x += 5;
         y += 2;
         g.FillEllipse(br, x, y, d, d);
         count++;
         if (count == max)
            timer.Stop();
      }
      );
      timer.Start();   // запустили, остановка - через 150 раз
   }
 }
}

После нажатия кнопки «Ночь» видим заход Луны без забора. Клик на форме — появляется забор. Теперь за забором Луны не видно. При нескольких нажатиях кнопки «Ночь» появляется несколько Лун.

 

Оставьте комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *