첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
본 블로그는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 블로그 콘텐츠 향상을 위해 쓰여집니다.

728x90
반응형
728x170

TestProject.zip
다운로드

▶ ImageSprite.cs

using System;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace TestProject
{
    /// <summary>
    /// 이미지 스프라이트
    /// </summary>
    public class ImageSprite
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 각도
        /// </summary>
        public float Angle;
        
        /// <summary>
        /// 델타 각도
        /// </summary>
        public float DeltaAngle;

        /// <summary>
        /// 중심 포인트
        /// </summary>
        public PointF CenterPoint;
        
        /// <summary>
        /// 속도 포인트
        /// </summary>
        public PointF VelocityPoint;

        /// <summary>
        /// 비트맵
        /// </summary>
        public Bitmap Bitmap;

        /// <summary>
        /// 반경
        /// </summary>
        private float Radius;

        #endregion

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

        #region 생성자 - ImageSprite(angle, deltaAngle, centerPoint, velocityPoint, bitmap)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="angle">각도</param>
        /// <param name="deltaAngle">델타 각도</param>
        /// <param name="centerPoint">중심 포인트</param>
        /// <param name="velocityPoint">속도 포인트</param>
        /// <param name="bitmap">비트맵</param>
        public ImageSprite(float angle, float deltaAngle, PointF centerPoint, PointF velocityPoint, Bitmap bitmap)
        {
            Angle         = angle;
            DeltaAngle    = deltaAngle;
            CenterPoint   = centerPoint;
            VelocityPoint = velocityPoint;
            Bitmap        = bitmap;
            Radius        = Math.Min(bitmap.Width, bitmap.Height) / 2f;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 이동하기 - Move(boundRectangle, elapsed)

        /// <summary>
        /// 이동하기
        /// </summary>
        /// <param name="boundRectangle">경계 사각형</param>
        /// <param name="elapsed">경과 시간</param>
        public void Move(Rectangle boundRectangle, float elapsed)
        {
            CenterPoint.X += VelocityPoint.X * elapsed;

            float right = CenterPoint.X + Radius;

            if(right > boundRectangle.Right)
            {
                right = boundRectangle.Right - (right - boundRectangle.Right);

                CenterPoint.X = right - Radius;

                VelocityPoint.X = -VelocityPoint.X;
            }

            float left = CenterPoint.X - Radius;

            if(left < 0)
            {
                left = -left;

                CenterPoint.X = left + Radius;

                VelocityPoint.X = -VelocityPoint.X;
            }

            CenterPoint.Y += VelocityPoint.Y * elapsed;

            float bottom = CenterPoint.Y + Radius;

            if(bottom > boundRectangle.Bottom)
            {
                bottom = boundRectangle.Bottom - (bottom - boundRectangle.Bottom);

                CenterPoint.Y = bottom - Radius;

                VelocityPoint.Y = -VelocityPoint.Y;
            }

            float top = CenterPoint.Y - Radius;

            if(top < 0)
            {
                top = -top;

                CenterPoint.Y = top + Radius;

                VelocityPoint.Y = -VelocityPoint.Y;
            }

            Angle += DeltaAngle * elapsed;
        }

        #endregion
        #region 그리기 - Draw(graphics)

        /// <summary>
        /// 그리기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        public void Draw(Graphics graphics)
        {
            GraphicsState state = graphics.Save();

            graphics.ResetTransform();

            graphics.RotateTransform(Angle);

            graphics.TranslateTransform(CenterPoint.X, CenterPoint.Y, MatrixOrder.Append);

            graphics.DrawImage(Bitmap, new PointF(-Radius, -Radius));

            graphics.Restore(state);
        }

        #endregion
    }
}

 

728x90

 

▶ MainForm.cs

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

using TestProject.Properties;

namespace TestProject
{
    /// <summary>
    /// 메인 폼
    /// </summary>
    public partial class MainForm : Form
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 이미지 스프라이트 리스트
        /// </summary>
        private List<ImageSprite> imageSpriteList = new List<ImageSprite>();

        /// <summary>
        /// 마지막 시간
        /// </summary>
        private DateTime lastTime;

        #endregion

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

        #region 생성자 - MainForm()

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

            Load                  += Form_Load;
            this.pictureBox.Paint += pictureBox_Paint;
            this.timer.Tick       += timer_Tick;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 폼 로드시 처리하기 - Form_Load(sender, e)

        /// <summary>
        /// 폼 로드시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void Form_Load(object sender, EventArgs e)
        {
            Random random = new Random();

            for(int i = 0; i < 10; i++)
            {
                float angle      = random.Next(-360, 360);
                float deltaAngle = random.Next(-180, 180);
                float scale      = random.Next(2, 5) / 5f;

                Bitmap bitmap = GetBitmap(Properties.Resources.calculator, scale);

                int halfWidth  = (int)(bitmap.Width  / 2f);
                int halfHeight = (int)(bitmap.Height / 2f);

                PointF centerPoint = new PointF
                (
                    random.Next(halfWidth, this.pictureBox.ClientSize.Width   - halfWidth ),
                    random.Next(halfHeight, this.pictureBox.ClientSize.Height - halfHeight)
                );

                float velocityX = random.Next(10, 50);

                if(random.Next(0, 2) == 1)
                {
                    velocityX = -velocityX;
                }

                float velocityY = random.Next(10, 50);

                if(random.Next(0, 2) == 1)
                {
                    velocityY = -velocityY;
                }

                PointF velocityPoint = new PointF(velocityX, velocityY);

                this.imageSpriteList.Add(new ImageSprite(angle, deltaAngle, centerPoint, velocityPoint, bitmap));     
            }

            lastTime = DateTime.Now;

            this.timer.Enabled = true;
        }

        #endregion
        #region 타이머 틱 처리하기 - timer_Tick(sender, e)

        /// <summary>
        /// 타이머 틱 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void timer_Tick(object sender, EventArgs e)
        {
            DateTime currentTime = DateTime.Now;

            float elapsedTime = (float)(currentTime - this.lastTime).TotalSeconds;

            foreach(ImageSprite imageSprite in this.imageSpriteList)
            {
                imageSprite.Move(this.pictureBox.Bounds, elapsedTime);
            }

            this.lastTime = currentTime;

            this.pictureBox.Refresh();
        }

        #endregion
        #region 픽처 박스 페인트시 처리하기 - pictureBox_Paint(sender, e)

        /// <summary>
        /// 픽처 박스 페인트시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void pictureBox_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.InterpolationMode = InterpolationMode.High;

            foreach(ImageSprite imageSprite in this.imageSpriteList)
            {
                imageSprite.Draw(e.Graphics);
            }
        }

        #endregion

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

        #region 비트맵 구하기 - GetBitmap(bitmap, scale)

        /// <summary>
        /// 비트맵 구하기
        /// </summary>
        /// <param name="bitmap">비트맵</param>
        /// <param name="scale">스케일</param>
        /// <returns>비트맵</returns>
        private Bitmap GetBitmap(Bitmap bitmap, float scale)
        {
            int width  = (int)(bitmap.Width  * scale);
            int height = (int)(bitmap.Height * scale);

            Bitmap targetBitmap = new Bitmap(width, height);

            using(Graphics graphics = Graphics.FromImage(targetBitmap))
            {
                PointF[] targetPointArray =
                {
                    new PointF(0    , 0     ),
                    new PointF(width, 0     ),
                    new PointF(0    , height)
                };

                RectangleF sourceRectangle = new RectangleF
                (
                    0,
                    0,
                    Properties.Resources.calculator.Width,
                    Properties.Resources.calculator.Height
                );

                graphics.DrawImage
                (
                    Resources.calculator,
                    targetPointArray,
                    sourceRectangle,
                    GraphicsUnit.Pixel
                );
            }

            return targetBitmap;
        }

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

댓글을 달아 주세요