첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
다운로드

▶ MainWindow.xaml

<Window x:Class="TestProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="800"
    Height="600"
    Title="파티클 애니메이션 사용하기"
    FontFamily="나눔고딕코딩"
    FontSize="16">
    <Canvas x:Name="canvas" />
</Window>

 

728x90

 

▶ MainWindow.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace TestProject
{
    /// <summary>
    /// 메인 윈도우
    /// </summary>
    public partial class MainWindow : Window
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 난수기
        /// </summary>
        private Random random = new Random();

        /// <summary>
        /// 원 크기
        /// </summary>
        private double circleSize = 150d;

        /// <summary>
        /// 최대 파티클 크기
        /// </summary>
        private double maximumParticleSize = 10d;

        /// <summary>
        /// 분산
        /// </summary>
        private int dispersion = 100;

        /// <summary>
        /// 디스패처 타이머
        /// </summary>
        private DispatcherTimer dispatcherTimer; 

        /// <summary>
        /// 현지 시각
        /// </summary>
        private double currentTime;

        /// <summary>
        /// 마지막 시각
        /// </summary>
        private double lastTime;

        /// <summary>
        /// 경과 시간
        /// </summary>
        private double elapsed;
        
        /// <summary>
        /// 전체 경과 시간
        /// </summary>
        private double totalElapsed;

        /// <summary>
        /// X 좌표 애니메이션
        /// </summary>
        private DoubleAnimation xAnimation;

        /// <summary>
        /// Y 좌표 애니메이션
        /// </summary>
        private DoubleAnimation yAnimation;

        /// <summary>
        /// 투명도 애니메이션
        /// </summary>
        private DoubleAnimation opacityAnimation;

        /// <summary>
        /// 타원
        /// </summary>
        private Ellipse ellipse;

        /// <summary>
        /// 시간
        /// </summary>
        private int time = 0;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainWindow()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();

            InitializeControl();

            InitializeTimer();

            Content = this.canvas;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event
 
        #region 디스패터 타이머 틱 처리하기 - dispatcherTimer_Tick(sender, e)

        /// <summary>
        /// 디스패터 타이머 틱 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void dispatcherTimer_Tick(object sender, EventArgs e)
        {
            this.currentTime  =  Environment.TickCount;
            this.elapsed      =  (double)(this.currentTime - this.lastTime) / 500.0;
            this.totalElapsed += this.elapsed;
            this.lastTime     =  this.currentTime;

            double x = Math.Cos(this.totalElapsed);
            double y = Math.Sin(this.totalElapsed);

            MakeParticle(Brushes.White , x * this.circleSize, y * this.circleSize);
            MakeParticle(Brushes.Gray  , x * this.circleSize, y * this.circleSize);
            MakeParticle(Brushes.Purple, x * this.circleSize, y * this.circleSize);
            MakeParticle(Brushes.Wheat , x * this.circleSize, y * this.circleSize);

            if(this.time > 70)
            {
                for(int i = 0; i < 4; i++)
                {
                    canvas.Children.Remove(canvas.Children[i]);
                }
            }

            this.time++;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region 컨트롤 초기화 하기 - InitializeControl()

        /// <summary>
        /// 컨트롤 초기화 하기
        /// </summary>
        private void InitializeControl()
        {
          //WindowState = WindowState.Maximized;
          //WindowStyle = WindowStyle.None;
          //Width       = SystemParameters.PrimaryScreenWidth;
          //Height      = SystemParameters.PrimaryScreenHeight;
            Cursor      = Cursors.None;
            Background  = Brushes.Black;
        }

        #endregion
        #region 타이머 초기화 하기 - InitializeTimer()
 
        /// <summary>
        /// 타이머 초기화 하기
        /// </summary>
        private void InitializeTimer()
        {
            this.dispatcherTimer = new DispatcherTimer();

            this.dispatcherTimer.Interval = TimeSpan.FromSeconds(0.01);

            this.dispatcherTimer.Start();

            this.dispatcherTimer.Tick += dispatcherTimer_Tick;
        }

        #endregion
 
        #region 파티션 만들기 - MakeParticle(brush, x, y)

        /// <summary>
        /// 파티션 만들기
        /// </summary>
        /// <param name="brush">브러시</param>
        /// <param name="x">X 좌표</param>
        /// <param name="y">Y 좌표</param>
        private void MakeParticle(Brush brush, double x, double y)
        {
            this.ellipse = new Ellipse();

            this.ellipse.Width = this.ellipse.Height = this.random.NextDouble() * this.maximumParticleSize;
            this.ellipse.Fill  = brush;

            Canvas.SetLeft(this.ellipse, x + this.Width  / 2);
            Canvas.SetTop (this.ellipse, y + this.Height / 2);

            this.canvas.Children.Add(this.ellipse);

            AnimateEllipse(this.ellipse);
        }

        #endregion
        #region 타원 애니메이션 실행하기 - AnimateEllipse(ellipse)
        
        /// <summary>
        /// 타원 애니메이션 실행하기
        /// </summary>
        /// <param name="ellipse">타원</param>
        public void AnimateEllipse(Ellipse ellipse)
        {
            this.xAnimation          = new DoubleAnimation();
            this.xAnimation.By       = this.random.Next(-1 * this.dispersion, this.dispersion);
            this.xAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));

            this.yAnimation          = new DoubleAnimation();
            this.yAnimation.By       = this.random.Next(-1 * this.dispersion, this.dispersion);
            this.yAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));

            this.opacityAnimation          = new DoubleAnimation();
            this.opacityAnimation.To       = 0;
            this.opacityAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));

            ellipse.BeginAnimation(Canvas.LeftProperty    , this.xAnimation      );
            ellipse.BeginAnimation(Canvas.TopProperty     , this.yAnimation      );
            ellipse.BeginAnimation(Ellipse.OpacityProperty, this.opacityAnimation);
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요