Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Starfield-Flyby-Animation
KainPlan
myCSharp.de - Member



Dabei seit:
Beiträge: 133
Herkunft: Gelsenkirchen

Themenstarter:

Starfield-Flyby-Animation

beantworten | zitieren | melden

Beschreibung:

Bestimmt nicht das erste und erstrecht nicht das letzte ^^.
Ist eigentlich alles recht selbsterklärend. Wenn fragen auftreten immer her damit. Have Phun.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Forms;

namespace DrawingExt
{
    /// <summary>
    /// The starfield class generates dots that emulates a starfield on flyby.
    /// </summary>
    public class Starfield
    {
        #region Publix
        public float AdditionalAngle { get; set; }
        /// <summary>
        /// The direction in which you want the stars to flyby.
        /// </summary>
        public float ScrollDirection
        {
            get { return _scrollDirection; }
            set { setScrollDir(value); }
        }
        /// <summary>
        /// The starfield class generates dots that emulates a starfield on flyby.
        /// </summary>
        /// <param name="ColorPalette"> Array of colors that are given to the stars.</param>
        /// <param name="Bounds">Bounds of the starfield. Stars only drawn inside this rectangle.</param>
        /// <param name="UpdateInterval">Interval in milliseconds to update the entire starlayer.</param>
        /// <param name="ScrollDirection">The direction in which you want the stars to flyby.</param>
        public Starfield(Color[] ColorPalette, Rectangle Bounds, int UpdateInterval, float ScrollDirection)
        {
            _objects = new List<StarfieldObject>();

            _outputBounds = Bounds;

            _colorPalette = ColorPalette;

            _scrollDirection = ScrollDirection;

            _updateInvoker = new Timer();
            _updateInvoker.Interval = UpdateInterval;
            _updateInvoker.Tick += new EventHandler(updateInvoker);

            _initStarfield();
        }
        /// <summary>
        /// Brings updating to a complete halt.
        /// </summary>
        public void Pause()
        {
            _updateInvoker.Enabled = false;
        }
        /// <summary>
        /// Begins updating.
        /// </summary>
        public void Start()
        {
            _updateInvoker.Enabled = true;
        }
        /// <summary>
        /// Draw all the stars to the desired devicecontext.
        /// </summary>
        /// <param name="dc"> Devicecontext where the stars are to be drawn at. </param>
        public void Draw(Graphics dc)
        {
            _scrollDirection += AdditionalAngle;
            dc.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            dc.TranslateTransform(-(_outputBounds.Width / 2), -(_outputBounds.Height / 2));
            dc.RotateTransform(_scrollDirection, System.Drawing.Drawing2D.MatrixOrder.Append);
            dc.TranslateTransform(_outputBounds.Width / 2, _outputBounds.Height / 2,
                System.Drawing.Drawing2D.MatrixOrder.Append);
            foreach (StarfieldObject obj in _objects) obj.Draw(dc);
            dc.ResetTransform();
        }
        /// <summary>
        /// Add a new StarfieldObject to the handling query.
        /// </summary>
        /// <param name="obj">StarfieldObject to add.</param>
        public void AddObject(StarfieldObject obj)
        {
            _objects.Add(obj);
        }
        #endregion

        #region Privates
        private Timer _updateInvoker;
        private Color[] _colorPalette;
        // = new Color[] { Color.White, Color.WhiteSmoke, 
        // Color.Snow, Color.Silver, Color.Gray, Color.LightGray, Color.DarkGray, };
        private List<StarfieldObject> _objects;
        private Rectangle _bounds;
        private Rectangle _outputBounds;
        private float _scrollDirection;
        private PointF _poc;
        private Point _poMoveDir;
        private int _pocLenght;
        private int _lenOfLife;
        private void setScrollDir(float scrollDirection)
        {
            _scrollDirection = scrollDirection;
        }
        private void _initStarfield()
        {
            // Satz des Pythagoras um ein Quadrat zu erschaffen in das _outputBounds egal in welchem drehungswinkel
            // 100% hinein passt.
            int bSide = (int)Math.Sqrt(Math.Pow(_outputBounds.Width, 2) + Math.Pow(_outputBounds.Height, 2));

            _bounds = new Rectangle(-((bSide - _outputBounds.Width) / 2), -((bSide - _outputBounds.Height) / 2),
                bSide, bSide);

            _pocLenght = _bounds.Height;
            _poc = new Point(_bounds.Left, -1);
            _lenOfLife = _bounds.Width;
            _poMoveDir = new Point(1, 0);

            // Scrollt Sterne ein...
            for (int i = 0; i < _lenOfLife; i++)
            {
                updateInvoker(null, null);
            }
        }
        private PointF getRndPoc()
        {
            PointF p = _poc;
            float rndpoc = ((float)Star.Random.Next(_bounds.Top, _bounds.Bottom));

            if (p.X == -1)
                p.X = rndpoc;
            else if (p.Y == -1)
                p.Y = rndpoc;

            return p;
        }
        private Star[] generateStars()
        {
            Star[] stars = new Star[Star.Random.Next(1, 4)];

            for (int i = 0; i < stars.Length; i++)
            {
                float speed = ((float)Star.Random.Next(50, 350) / 100);
                stars[i] = new Star(_colorPalette, new PointF(speed, speed),
                    getRndPoc());
            }

            return stars;
        }
        private void updateInvoker(object sender, EventArgs e)
        {
            lock (_objects)
            {
                _objects.AddRange(generateStars());

                List<StarfieldObject> remIxs = new List<StarfieldObject>();
                for (int i = 0; i < _objects.Count; i++)
                {
                    StarfieldObject obj = _objects[i];
                    obj.Update(_poMoveDir);
                    if (obj.OutOf(_bounds))
                        remIxs.Add(obj);
                }

                foreach (StarfieldObject obj in remIxs) _objects.Remove(obj);
                GC.Collect();
            }

            if (e != null) OnUpdated();
        }
        #endregion

        #region Events
        /// <summary>
        /// Occurs whenever the starfield is updated.
        /// </summary>
        public event StarfieldUpdated Updated;
        /// <summary>
        /// Occurs whenever the starfield is updated.
        /// </summary>
        protected virtual void OnUpdated()
        {
            if (Updated != null)
            {
                Control target = Updated.Target as Control;
                if (target != null && target.InvokeRequired)
                    target.Invoke(Updated, new object[] { this });
                else
                    Updated(this);
            }
        }
        #endregion
    }
    /// <summary>
    /// Occurs whenever the starfield is updated.
    /// </summary>
    public delegate void StarfieldUpdated(Starfield sf);

    /// <summary>
    /// A generic point object in space.
    /// </summary>
    public class StarfieldObject
    {
        /// <summary>
        /// Generate random numbers.
        /// </summary>
        public static Random Random = new Random();
        /// <summary>
        /// The actual position of this object.
        /// </summary>
        public PointF Position { get; set; }
        /// <summary>
        /// The PoC point of creation is the point where this object has been created.
        /// </summary>
        public PointF PointOfCreation { get; private set; }
        /// <summary>
        /// The speed of this object.
        /// </summary>
        public PointF Speed { get; set; }
        /// <summary>
        /// Create a new object instance.
        /// </summary>
        /// <param name="speed">Speed of the object.</param>
        /// <param name="poc">PoC - Point of Creation. </param>
        public StarfieldObject(PointF speed, PointF poc)
        {
            Speed = speed;
            PointOfCreation = poc;
            Position = poc;
        }
        /// <summary>
        /// Override this method to draw the starfield object.
        /// </summary>
        /// <param name="dc"></param>
        public virtual void Draw(Graphics dc)
        {
            string ex = string.Format("Drawing for {0} is not handled.", 
                this.GetType().FullName);
            throw new Exception(ex);
        }
        /// <summary>
        /// Updates this object in the given direction.
        /// </summary>
        /// <param name="dir">The direction in witch the object should be fly.</param>
        public virtual void Update(PointF dir)
        {
            PointF pos = Position;

            dir.X = dir.X > 1 ? 1 : dir.X < -1 ? -1 : dir.X;
            dir.Y = dir.Y > 1 ? 1 : dir.Y < -1 ? -1 : dir.Y;

            pos.X += Speed.X * dir.X;
            pos.Y += Speed.Y * dir.Y;

            Position = pos;
        }
        /// <summary>
        /// Checks if the object is outside of the given bounds.
        /// </summary>
        /// <param name="bounds">The bounds to check.</param>
        /// <returns>True if the object is outside.</returns>
        public virtual bool OutOf(RectangleF bounds)
        {
            return !bounds.Contains(Position);
            /*
            if (bounds.Left > Position.X) return true;
            else if (bounds.Top > Position.Y) return true;
            else if (bounds.Right < Position.X) return true;
            else if (bounds.Bottom < Position.Y) return true;

            return false;
            */
        }
        /// <summary>
        /// Same as Update() but you probably want to assing a new speed also.
        /// </summary>
        /// <param name="dir">The direction in witch the object should be fly.</param>
        /// <param name="newSpeed">The new speed.</param>
        public virtual void Update(Point dir, PointF newSpeed)
        {
            Speed = newSpeed;
            Update(dir);
        }
 
    }
    /// <summary>
    /// Supplies information about speed, position and color for each star.
    /// </summary>
    class Star : StarfieldObject
    {
        /// <summary>
        /// The color of this star.
        /// </summary>
        public Color Color { get; set; }
        /// <summary>
        /// Create a new star instance.
        /// </summary>
        /// <param name="clPalette">The palette where the star picks a random color.</param>
        /// <param name="speed">Speed of the star.</param>
        /// <param name="poc">PoC - Point of Creation. </param>
        public Star(Color[] clPalette, PointF speed, PointF poc)
            : base(speed, poc)
        {
            int clIdx = Star.Random.Next(0, clPalette.Length - 1);
            Color = clPalette[clIdx];
        }
        /// <summary>
        /// Draws this star on the given devicecontext.
        /// </summary>
        /// <param name="dc">Devicecontext to draw on.</param>
        public override void Draw(Graphics dc)
        {
            dc.FillRectangle(new SolidBrush(Color), Position.X, Position.Y, 1, 1);
        }
    }
}


Schlagwörter: Sternenfeld, Starfield, Generator, Pixel, Drawing
private Nachricht | Beiträge des Benutzers
ErfinderDesRades
myCSharp.de - Experte

Avatar #avatar-3151.jpg


Dabei seit:
Beiträge: 5.299

beantworten | zitieren | melden

hmm. hab kein Plan , wie man damit was zu sehen bekommt - machste'n Sample-Upload?
Der frühe Apfel fängt den Wurm.
private Nachricht | Beiträge des Benutzers
KainPlan
myCSharp.de - Member



Dabei seit:
Beiträge: 133
Herkunft: Gelsenkirchen

Themenstarter:

beantworten | zitieren | melden

Klar mach ich hatte in letzter Zeit etwas weniger von dieser.
private Nachricht | Beiträge des Benutzers
Friedel
myCSharp.de - Member

Avatar #avatar-1931.jpg


Dabei seit:
Beiträge: 830
Herkunft: Nähe Kassel / Hessen

beantworten | zitieren | melden

Hallo KainPlan,

finde die Animation ziemlich gelungen, wenn ich auch nicht weiß für was ich das brauchen könnte.

Gruss
Friedel
Ohne Ziel ist auch der Weg egal.
private Nachricht | Beiträge des Benutzers
dr4g0n76
myCSharp.de - Experte

Avatar #avatar-1768.jpg


Dabei seit:
Beiträge: 2.908
Herkunft: Deutschland

beantworten | zitieren | melden

@KainPlan

ein ähnliches Thema gibt's auch hier:

Schnelle GDI(+) Grafik - wie? [Parallax Scrolling]

vll. findest Du da noch Anregungen
Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.
private Nachricht | Beiträge des Benutzers