Archivi categoria: Graphics

Star Wars Credits Control [C# porting]

Sulle esempio di Pablo van der Meer, ho fatto il porting del suo codice c++ in c#.

E’ stato fatto un porting molto basilare, può essere sicuramente migliorato.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication3
{
    public partial class AboutScrollText : Control
    {
        private int m_Active = 0;
        const int NUM_STARS = 100;
        private Random r = new Random();
        private int m_nStarsSpeed = 30;
        private int m_nScrollSpeed = 2;
        private int m_nScrollPos;
        private Timer m_Timer;

        CStar[] m_StarArray;
        String[] m_TextLines;

        private struct CStar
        {
            public int x;
            public int y;
            public int z;
        };

        public AboutScrollText()
        {
            InitializeComponent();

            this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);

            m_StarArray = new CStar[NUM_STARS];

            m_Timer = new Timer();
            m_Timer.Interval = 75;
            m_Timer.Tick += new EventHandler(m_Timer_Tick);

            m_TextLines = new string[8];
            m_TextLines[0] = "A long time ago";
            m_TextLines[1] = "";
            m_TextLines[2] = "in a galaxy far far away";
            m_TextLines[3] = "";
            m_TextLines[4] = "this application";
            m_TextLines[5] = "was programmed by";
            m_TextLines[6] = "";
            m_TextLines[7] = "...?...";
            // initialize stars
            for (int i = 0; i < NUM_STARS; i++)
            {
                m_StarArray[i].x = r.Next(0, 1024);
                m_StarArray[i].x -= 512;
                m_StarArray[i].y = r.Next(0, 1024);
                m_StarArray[i].y -= 512;
                m_StarArray[i].z = r.Next(0, 512);
                m_StarArray[i].z -= 256;
            }

            m_nScrollSpeed = 2; // (m_nScrollSpeed * 100) / 50;
        }

        void m_Timer_Tick(object sender, EventArgs e)
        {
            if (m_Active == 0)
            {
                m_Active = 1;
                this.Invalidate();
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            if (this.DesignMode)
            {
                base.OnPaint(e);
            }
            else
            {
                Graphics g = e.Graphics;
                DoStars(g);
                DoScrollText(g);
                m_Active = 0;
            }
        }

        void DoScrollText(Graphics g)
        {
            int nPosX = 0;
            int nPosY = 0;
            Bitmap b = new Bitmap(this.Width, this.Height);
            Graphics bitmap = Graphics.FromImage(b);

            // black
            Font f = new Font("Tahoma", 24, FontStyle.Regular);
            // draw Credits on the hidden Picture
            for (int i = 0; i < m_TextLines.Length; i++)
            {
                // set position for this line
                SizeF size = bitmap.MeasureString(m_TextLines[i], f);
                nPosY = m_nScrollPos + (i * (int)size.Height);

                if ((nPosY) > 0)
                {
                    nPosX = (this.Width / 2) - ((int)size.Width / 2);

                    if (nPosY > 255)
                    {
                        bitmap.DrawString(m_TextLines[i], f, new SolidBrush(Color.FromArgb(255, 255, 255)), nPosX, nPosY);
                    }
                    else
                    {
                        // set fade color
                        bitmap.DrawString(m_TextLines[i], f, new SolidBrush(Color.FromArgb(nPosY, nPosY, nPosY)), nPosX, nPosY);
                    }
                }
                else
                {
                    // start all over ...
                    if (i == (m_TextLines.Length - 1))
                    {
                        m_nScrollPos = this.Height;
                    }
                }
            }

            int nWidth = this.Width;
            int nHeight = this.Height;

            //MemoryStream memStream = new MemoryStream();
            //bitmap.Save(memStream, ImageFormat.Gif);
            //bitmap.Flush();

            double nScale;
            int nOffset;
            // shrink text from bottom to top to create Star Wars effect
            Rectangle rDest = new Rectangle();
            Rectangle rSrc = new Rectangle();
            Bitmap s = new Bitmap(this.Width, this.Height);
            Graphics sbitmap = Graphics.FromImage(s);

            for (int y = 0; y < nHeight; y += 3)
            {
                nScale = (double)y / (double)nHeight;
                nOffset = (int)(nWidth - nWidth * nScale) / 2;
                rDest.X = nOffset;
                rDest.Y = y;
                rDest.Width = (int)(nWidth * nScale);
                rDest.Height = 3;

                rSrc.X = 0;
                rSrc.Y = y;
                rSrc.Width = nWidth;
                rSrc.Height = 3;

                sbitmap.DrawImage(b, rDest, rSrc, GraphicsUnit.Pixel);
            }

            g.DrawImageUnscaled(s, 0, 0);
            // move text up one pixel
            m_nScrollPos = m_nScrollPos - m_nScrollSpeed;
        }

        void DoStars(Graphics g)
        {
            g.Clear(Color.Black);

            int nFunFactor = 100;
            int x, y, z;
            for (int i = 0; i < NUM_STARS; i++)
            {
                m_StarArray[i].z = m_StarArray[i].z - m_nStarsSpeed;
                if (m_StarArray[i].z > 255)
                {
                    m_StarArray[i].z = -255;
                }
                if (m_StarArray[i].z < -255)
                {
                    m_StarArray[i].z = 255;
                }

                z = m_StarArray[i].z + 256;
                x = (m_StarArray[i].x * nFunFactor / z) + (this.Width / 2);
                y = (m_StarArray[i].y * nFunFactor / z) + (this.Height / 2);

                // create a white pen which luminosity depends on the z position (for 3D effect!)
                int nColor = 255 - m_StarArray[i].z;
                if (nColor < 0) nColor = 0;
                if (nColor > 255) nColor = 255;
                g.DrawEllipse(new Pen(Color.FromArgb(nColor, nColor, nColor), 1), x, y, 2, 2);
            }
        }

        public void Start()
        {
            m_nScrollPos = this.Height;
            m_Timer.Enabled = true;
        }

        public void Stop()
        {
            m_Timer.Enabled = false;
        }

    }
}

Un esempio in c++ che usa Win32 OpenGL Framework lo trovate qui.

Fletto i muscoli e sono nel vuoto.