Inhaltsverzeichnis

improve

CSharp oder C#. Siehe auch C, C++, .NET oder powershell

This guy has awesome books.

dotnetbook_petzold.pdf

reverse_csharp.pdf

ILSpy, DNSpy

Klassen

using System;
 
namespace HelloWorld
{
    class Hello 
    {         
 
        #region Main Region
 
        static void Main(string[] args)
        {
 
            Console.WriteLine("Parameter: " + args[0]);
 
        }   
 
        #endregion
 
    }   
}
C:\Windows\Microsoft.Net\Framework64\v3.5\csc.exe /target:exe /out:HelloWorld.exe HelloWorld.cs

https://benohead.com/blog/2014/08/13/three-options-to-dynamically-execute-csharp-code/

Threads

Die Thread-Klasse aus dem System.Threading Namespace ermöglicht die Erstellung und Steuerung von Threads.

using System;
using System.Threading;
 
namespace ThreadExample
{
    public class Program
    {
        static void Main()
        {
            Thread thread = new Thread(DoWork);
            thread.Start(); // Thread starten
 
            // Hauptthread setzt seine Arbeit fort
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Main Thread: " + i);
                Thread.Sleep(1000);
            }
        }
 
        static void DoWork()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Worker Thread: " + i);
                Thread.Sleep(1000);
            }
        }
    }
}

Die Task Parallel Library ist eine leistungsfähigere und modernere Methode zur Verwaltung von Threads in C#. Sie bietet eine höhere Abstraktionsebene und erweiterte Funktionen für die parallele Verarbeitung.

using System;
using System.Threading.Tasks;
 
namespace ThreadExample
{
    public class Program
    {
        static void Main()
        {
            Task task = Task.Run(DoWork);
 
            // Hauptthread setzt seine Arbeit fort
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Main Thread: " + i);
                Task.Delay(1000).Wait();
            }
 
            task.Wait(); // Warten, bis der Task abgeschlossen ist
        }
 
        static void DoWork()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Worker Thread: " + i);
                Task.Delay(1000).Wait();
            }
        }
    }
}

WinForm

using System;
using System.Windows.Forms;
 
namespace WinFormsExample
{
    public class Program : Form
    {
        private Button button;
 
        public Program()
        {
            button = new Button();
            button.Text = "Click me!";
            button.Click += Button_Click;
 
            Controls.Add(button);
        }
 
        private void Button_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Button clicked!");
        }
 
        [STAThread]
        public static void Main()
        {
            Application.Run(new Program());
        }
    }
}

Winform in Console Application - https://www.youtube.com/watch?v=FJ76vL_EwXA

Layouts

In C# gibt es sogenannte Layout-Manager, die ähnlich wie in Java zur dynamischen Platzierung und Anordnung von Steuerelementen in Windows Forms-Anwendungen verwendet werden können. Die Layout-Manager in C# werden als „Layout Controls“ bezeichnet.

FlowLayout

using System;
using System.Windows.Forms;
 
namespace LayoutExample
{
    public class Program : Form
    {
        public Program()
        {
            FlowLayoutPanel flowLayoutPanel = new FlowLayoutPanel();
            flowLayoutPanel.Dock = DockStyle.Fill; // Füllt den verfügbaren Platz im Formular aus
 
            Button button1 = new Button();
            button1.Text = "Button 1";
            flowLayoutPanel.Controls.Add(button1);
 
            Button button2 = new Button();
            button2.Text = "Button 2";
            flowLayoutPanel.Controls.Add(button2);
 
            Button button3 = new Button();
            button3.Text = "Button 3";
            flowLayoutPanel.Controls.Add(button3);
 
            Controls.Add(flowLayoutPanel);
        }
 
        [STAThread]
        public static void Main()
        {
            Application.Run(new Program());
        }
    }
}

TableLayout

using System;
using System.Windows.Forms;
 
namespace LayoutExample
{
    public class Program : Form
    {
        public Program()
        {
            TableLayoutPanel tableLayoutPanel = new TableLayoutPanel();
            tableLayoutPanel.Dock = DockStyle.Fill; // Füllt den verfügbaren Platz im Formular aus
 
            tableLayoutPanel.ColumnCount = 2;
            tableLayoutPanel.RowCount = 2;
 
            Button button1 = new Button();
            button1.Text = "Button 1";
            tableLayoutPanel.Controls.Add(button1, 0, 0);
 
            Button button2 = new Button();
            button2.Text = "Button 2";
            tableLayoutPanel.Controls.Add(button2, 1, 0);
 
            Button button3 = new Button();
            button3.Text = "Button 3";
            tableLayoutPanel.Controls.Add(button3, 0, 1);
 
            Button button4 = new Button();
            button4.Text = "Button 4";
            tableLayoutPanel.Controls.Add(button4, 1, 1);
 
            Controls.Add(tableLayoutPanel);
        }
 
        [STAThread]
        public static void Main()
        {
            Application.Run(new Program());
        }
    }
}

GroupBoxLayout

using System;
using System.Windows.Forms;
 
namespace LayoutExample
{
    public class Program : Form
    {
        public Program()
        {
            GroupBox groupBox = new GroupBox();
            groupBox.Text = "Group Box";
            groupBox.Dock = DockStyle.Fill; // Füllt den verfügbaren Platz im Formular aus
 
            Button button1 = new Button();
            button1.Text = "Button 1";
            button1.Location = new System.Drawing.Point(10, 20);
            groupBox.Controls.Add(button1);
 
            Button button2 = new Button();
            button2.Text = "Button 2";
            button2.Location = new System.Drawing.Point(10, 60);
            groupBox.Controls.Add(button2);
 
            Controls.Add(groupBox);
        }
 
        [STAThread]
        public static void Main()
        {
            Application.Run(new Program());
        }
    }
}

Pointer

Auch in C# gibt es sogenannte Zeiger (Pointer), allerdings sind sie auf spezielle Kontexte beschränkt und der direkte Zugriff auf den Speicher über Zeiger ist in C# stark eingeschränkt und nur in sogenannten „unsafe“ Codeblöcken erlaubt.

unsafe class Program
{
    static void Main(string[] args)
    {
        int number = 10;
        int* p = &number; // Zeiger auf die Variable 'number' erstellen
 
        Console.WriteLine(*p); // Ausgabe: 10 (Wert über den Zeiger dereferenzieren)
 
        *p = 20; // Wert über den Zeiger ändern
 
        Console.WriteLine(number); // Ausgabe: 20 (Änderung des Werts über den Zeiger)
 
        Console.ReadLine();
    }
}

Datenstrukturen

Array

int[] numbers = new int[5]; // Deklaration und Initialisierung eines Integer-Arrays mit einer Größe von 5
 
numbers[0] = 1; // Wertzuweisung an das erste Element
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;
numbers[4] = 5;
 
Console.WriteLine(numbers[2]); // Ausgabe: 3 (Zugriff auf das dritte Element)

List

List<string> fruits = new List<string>(); // Deklaration einer generischen Liste von Zeichenketten
 
fruits.Add("Apple"); // Elemente hinzufügen
fruits.Add("Banana");
fruits.Add("Orange");
 
Console.WriteLine(fruits.Count); // Ausgabe: 3 (Anzahl der Elemente in der Liste)
 
fruits.Remove("Banana"); // Element entfernen
 
foreach (string fruit in fruits)
{
    Console.WriteLine(fruit); // Ausgabe: Apple, Orange (Durchlaufen der Liste)
}

Stack

Stack<int> stack = new Stack<int>(); // Deklaration eines generischen Stapels von Ganzzahlen
 
stack.Push(1); // Elemente auf den Stapel legen
stack.Push(2);
stack.Push(3);
 
Console.WriteLine(stack.Pop()); // Ausgabe: 3 (Entfernen des obersten Elements)

Queue

Queue<string> queue = new Queue<string>(); // Deklaration einer generischen Warteschlange von Zeichenketten
 
queue.Enqueue("John"); // Elemente in die Warteschlange einfügen
queue.Enqueue("Jane");
queue.Enqueue("Mike");
 
Console.WriteLine(queue.Dequeue()); // Ausgabe: John (Entfernen des ersten Elements)

Linked List

LinkedList<int> linkedList = new LinkedList<int>(); // Deklaration einer generischen verknüpften Liste von Ganzzahlen
 
linkedList.AddLast(1); // Elemente am Ende der Liste hinzufügen
linkedList.AddLast(2);
linkedList.AddLast(3);
 
LinkedListNode<int> node = linkedList.Find(2); // Suchen nach einem Knoten mit Wert 2
linkedList.AddAfter(node, 4); // Element nach dem gefundenen Knoten einfügen
 
foreach (int num in linkedList)
{
    Console.WriteLine(num); // Ausgabe: 1, 2, 4, 3 (Durchlaufen der Liste)
}

Dictionary

Dictionary<string, int> dictionary = new Dictionary<string, int>(); // Deklaration eines generischen Wörterbuchs mit Zeichenketten als Schlüssel und Ganzzahlen als Werte
 
dictionary.Add("Apple", 10); // Schlüssel-Wert-Paare hinzufügen
dictionary.Add("Banana", 5);
dictionary.Add("Orange", 3);
 
Console.WriteLine(dictionary["Banana"]); // Ausgabe: 5 (Zugriff auf den Wert mit dem Schlüssel "Banana")
 
dictionary["Apple"] = 15; // Wert aktualisieren
 
foreach (KeyValuePair<string, int> pair in dictionary)
{
    Console.WriteLine(pair.Key + ": " + pair.Value); // Ausgabe: Apple: 15, Banana:
}

Set

HashSet<string> set = new HashSet<string>(); // Deklaration eines Hashsets von Zeichenketten
 
set.Add("Apple"); // Elemente hinzufügen
set.Add("Banana");
set.Add("Orange");
set.Add("Apple"); // Duplikate werden automatisch entfernt
 
Console.WriteLine(set.Count); // Ausgabe: 3 (Anzahl der eindeutigen Elemente im Set)
 
set.Remove("Banana"); // Element entfernen
 
foreach (string item in set)
{
    Console.WriteLine(item); // Ausgabe: Apple, Orange (Durchlaufen des Sets)
}

Singleton

using System;
 
namespace Test
{
 
	public class Program
	{
 
		public static void Main(string[] args)
		{
 
			// Constructor is protected -- cannot use new
			Singleton s1 = Singleton.Instance();
			Singleton s2 = Singleton.Instance();
 
			// Test for same instance
			if (s1 == s2)
			{
				Console.WriteLine("Objects are the same instance");
			}
 
		}
 
	}
 
	public class Singleton
	{
 
		static Singleton instance;
 
		// Constructor is 'protected'
		protected Singleton()
		{
		}
 
		/* 
		public static Singleton Instance(string str)
		{
 
			if (instance == null)
			{
				instance = new Singleton();
			}
			return instance;
 
		}
		*/
 
		/*
		// not thread safe
		public static Singleton Instance
		{
			get
			{
				if (instance == null)
				{
					instance = new Singleton();
				}
				return instance;
			}
		}
		*/
 
		/*
		// thread safe
		private static readonly object padlock = new object();
 
		public static Singleton Instance
		{
			get
			{
				lock (padlock)
				{
					if (instance == null)
					{
						instance = new Singleton();
					}
					return instance;
				}
			}
		}
		*/
 
	}
 
}

Generic Types

using System;
using System.Collections.Generic;
 
namespace GenericApp
{
 
    public class TestClass<T>
    {
 
        // define an Array of Generic type with length 5
        T[] obj = new T[5];
        int count = 0;
 
        public void  Add(T item)
        {
 
            if (count + 1 < 6)
            {
                obj[count] = item;
 
            }
            count++;
        }
 
        //indexer for foreach statement iteration
        public T this[int index]
        {
            get { return obj[index]; }
            set { obj[index] = value; }
        }
 
    }
 
    class Program
    {
 
        static void Main(string[] args)
        {
 
            //instantiate generic with Integer
            TestClass<int> intObj = new TestClass<int>();
 
            intObj.Add(1);
            intObj.Add(2);
            intObj.Add(3);    
            intObj.Add(4);
            intObj.Add(5);
 
            //displaying values
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine(intObj[i]);   //No unboxing
            }
 
        }
 
    }
 
}

COM InterOp

using System;
using System.Runtime.InteropServices;
 
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("E0F805D1-77CC-4C14-930E-5D65A1A39A2F")]
public interface IMyComInterface
{
    void SayHello(string name);
}
 
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[Guid("1C9D8F2B-8D52-45A7-9E3D-ED6F2CE010E0")]
public class MyComClass : IMyComInterface
{
    public void SayHello(string name)
    {
        Console.WriteLine($"Hello, {name}!");
    }
}

Für InterOp registrieren (systemweit)

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe /codebase /tlb ClassLibrary.dll
$comObject = New-Object -ComObject "MyComClass"
$comObject.SayHello("World")

Server-Client

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Net;
using System.Net.Sockets;
 
namespace ConsoleServer
{
 
    public enum MessageType
    {
        String,
        Int,
        Float,
        Vector
    }
 
    [Serializable]
    public struct Vector3
    {
        public float X { get; set; }
        public float Y { get; set; }
        public float Z { get; set; }
 
        public Vector3(float x, float y, float z)
        {
            X = x;
            Y = y;
            Z = z;
        }
    }
 
    [Serializable]
    public class Message
    {
 
        public MessageType Type { get; set; }
        public string Content { get; set; }
        public int IntValue { get; set; }
        public float FloatValue { get; set; }
        public Vector3 VectorValue { get; set; }
 
        public Message(MessageType type, string content = "", int intValue = 0, float floatValue = 0.0f, Vector3 vectorValue = default(Vector3))
        {
            Type = type;
            Content = content;
            IntValue = intValue;
            FloatValue = floatValue;
            VectorValue = vectorValue;
        }
 
        public byte[] ToBytes()
        {
            using (MemoryStream stream = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, this);
                return stream.ToArray();
            }
        }
 
        public static Message FromBytes(byte[] data)
        {
            using (MemoryStream stream = new MemoryStream(data))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                return (Message)formatter.Deserialize(stream);
            }
        }
    }
 
    public class Peer
    {
 
        private TcpClient client;
 
        public Peer(TcpClient _client)
        {
            client = _client;
        }
 
        public TcpClient Client { get { return client; } }
 
    }
 
    public class MultiplayerServer
    {
 
        private TcpListener tcpListener;
        private Thread listenerThread;
        private List<Peer> peers = new List<Peer>();
 
        public MultiplayerServer()
        {
            this.tcpListener = new TcpListener(IPAddress.Any, 5555);
            this.listenerThread = new Thread(new ThreadStart(ListenForClients));
            this.listenerThread.Start();
        }
 
        private void ListenForClients()
        {
 
            this.tcpListener.Start();
 
            while (true)
            {
 
                TcpClient client = this.tcpListener.AcceptTcpClient();
                Peer peer = new Peer(client);
                peers.Add(peer);
 
                Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
                clientThread.Start(peer);
 
            }
        }
 
        private void HandleClientComm(object _peer)
        {
 
            Peer peer = (Peer)_peer;
 
            TcpClient tcpClient = peer.Client;
 
            NetworkStream clientStream = peer.Client.GetStream();
 
            byte[] messageBuffer = new byte[4096];
            int bytesRead;
 
            while (true)
            {
                bytesRead = 0;
 
                try
                {
                    bytesRead = clientStream.Read(messageBuffer, 0, 4096);
                }
                catch
                {
                    break;
                }
 
                if (bytesRead == 0)
                    break;
 
                Message receivedMessage = Message.FromBytes(messageBuffer);
                //Console.WriteLine("Received message from client: " + receivedMessage.Content);
 
                // Fire the MessageReceived Event
                MessageReceived(receivedMessage, peer);
 
                // response
                /*
                Message responseMessage = new Message(MessageType.String, "Server has received your message: " + receivedMessage.Content);
                SendMessageToClient(tcpClient, responseMessage);
                SendMessageToAllClients(responseMessage);
                */
 
            }
 
            peers.Remove(peer);
            tcpClient.Close();
 
        }
 
        public void SendMessageToClient(Peer peer, Message message)
        {
            NetworkStream clientStream = peer.Client.GetStream();
            byte[] messageBytes = message.ToBytes();
            clientStream.Write(messageBytes, 0, messageBytes.Length);
        }
 
        public void SendMessageToAllClients(Message message)
        {
            byte[] messageBytes = message.ToBytes();
            //foreach (TcpClient client in connectedClients)
            foreach(Peer peer in peers)
            {
                NetworkStream clientStream = peer.Client.GetStream();
                clientStream.Write(messageBytes, 0, messageBytes.Length);
            }            
        }
 
        public void StartListening()
        {
            // Implement your game logic here for the server
        }
 
        protected virtual void OnMessageReceived(Message message, Peer peer)
        {
            MessageReceived?.Invoke(message, peer);
        }
 
        public event Action<Message, Peer> MessageReceived;
 
    }
 
    public class MultiplayerClient
    {
 
        private TcpClient tcpClient;
        private Thread clientThread;
        private NetworkStream clientStream;
 
        public MultiplayerClient()
        {
            this.tcpClient = new TcpClient();
            this.clientThread = new Thread(new ThreadStart(ConnectToServer));
            this.clientThread.Start();
        }
 
        private void ConnectToServer()
        {
 
            this.tcpClient.Connect("127.0.0.1", 5555);
            this.clientStream = this.tcpClient.GetStream();
 
            byte[] serverResponseBuffer = new byte[4096];
            int bytesRead;
 
            while (true)
            {
                bytesRead = 0;
 
                try
                {
                    bytesRead = this.clientStream.Read(serverResponseBuffer, 0, 4096);
                }
                catch
                {
                    break;
                }
 
                if (bytesRead == 0)
                    break;
 
                Message serverResponse = Message.FromBytes(serverResponseBuffer);
                OnMessageReceived(serverResponse);
            }
        }
 
        protected virtual void OnMessageReceived(Message message)
        {
            MessageReceived?.Invoke(message);
        }
 
        public event Action<Message> MessageReceived;
 
        // Methode zum Senden von Nachrichten an den Server
        public void SendMessageToServer(Message message)
        {
            byte[] messageBytes = message.ToBytes();
            this.clientStream.Write(messageBytes, 0, messageBytes.Length);
        }
 
    }
 
    public class Game
    {
 
        private MultiplayerClient client;
        private MultiplayerServer server;
 
        private bool isClient, isServer = false;
 
        public Game()
        {
 
            Console.WriteLine("Choose your role: [1] Server / [2] Client");
            string roleChoice = Console.ReadLine();
 
            if (roleChoice == "1")
            {
                server = new MultiplayerServer();
                server.StartListening();
                server.MessageReceived += OnServerMessageReceived;
                isServer = true;
            }
            else if (roleChoice == "2")
            {
                client = new MultiplayerClient();
                client.MessageReceived += OnMessageReceived;
                isClient = true;
            }
            else
            {
                Console.WriteLine("Invalid input. Exiting the program.");
            }
        }
 
        private void OnMessageReceived(Message message)
        {
            Console.WriteLine("[client] Received message from server: " + message.Content);
        }
 
        private void OnServerMessageReceived(Message message, Peer peer)
        {
            Console.WriteLine("[server] Received message from server: " + message.Content);
            server.SendMessageToAllClients(message);
            server.SendMessageToClient(peer, message);
        }
 
        public void Run()
        {
            if (isClient)
            {
                string msg;
 
                while (true)
                {
                    msg = Console.ReadLine();
                    client.SendMessageToServer(new Message(MessageType.String, msg));
                }
            }
        }
 
        public static void Main()
        {
            Game game = new Game();
            game.Run();
        }
    }
 
}

Sprite Animation

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System;
using System.Drawing;
using System.Windows.Forms;
 
namespace AnimationPlayer
{
 
    public class SpriteAnimation
    {
 
        private  PictureBox pictureBox1;
        private  Image spriteSheet;
        private  int frameWidth;
        private  int frameHeight;
        private int currentFrame;
        private int totalFrames;
        private int currentAnimation;
 
        public SpriteAnimation(PictureBox pictureBox, Image spriteSheet, int frameWidth, int frameHeight, int totalFrames, int _currentAnimation)
        {
            this.pictureBox1 = pictureBox;
            this.spriteSheet = spriteSheet;
            this.frameWidth = frameWidth;
            this.frameHeight = frameHeight;
            this.totalFrames = totalFrames;
                this.currentAnimation = _currentAnimation;
 
            // Setzen Sie die Größe des PictureBox-Steuerelements auf die Größe eines Frames.
            pictureBox.Size = new Size(frameWidth, frameHeight);
 
            // Event-Handler für das Paint-Ereignis hinzufügen, um die Animation zu zeichnen.
            pictureBox.Paint += PictureBox_Paint;
        }
 
        private void PictureBox_Paint(object sender, PaintEventArgs e)
        {
                // Berechnen Sie die Quell- und Zielrechtecke für das aktuelle Frame.
                Rectangle sourceRect = new Rectangle(currentFrame * frameWidth, currentAnimation * frameHeight, frameWidth, frameHeight);
                Rectangle destRect = new Rectangle(0, 0, frameWidth, frameHeight);
 
                // Zeichnen Sie das aktuelle Frame auf das PictureBox-Steuerelement.
                e.Graphics.DrawImage(spriteSheet, destRect, sourceRect, GraphicsUnit.Pixel);
        }
 
        public void StartAnimation()
        {
            // Erstellen Sie einen Timer, um die Animation zu steuern.
            Timer timer = new Timer();
            timer.Interval = 120; // Passen Sie die Intervallzeit an Ihre Anforderungen an.
            timer.Tick += Timer_Tick;
            timer.Start();
        }
 
        private void Timer_Tick(object sender, EventArgs e)
        {
            // Aktualisieren Sie das aktuelle Frame und zeichnen Sie die Animation erneut.
            currentFrame = (currentFrame + 1) % totalFrames;
            pictureBox1.Invalidate(); // Ruft das Paint-Ereignis auf.
 
                if (!pictureBox1.Visible)
                    pictureBox1.Visible = true;
        }
 
        public void ChangeAnimation(int newFrameWidth, int newFrameHeight, int newTotalFrames, int newAnimation)
        {
            // Ändern Sie die Animationseinstellungen.
            frameWidth = newFrameWidth;
            frameHeight = newFrameHeight;
            totalFrames = newTotalFrames;
            currentAnimation = newAnimation;
 
            // Setzen Sie die Größe des PictureBox-Steuerelements auf die Größe eines Frames.
            pictureBox1.Size = new Size(frameWidth, frameHeight);
 
            // Setzen Sie das aktuelle Frame auf den Anfang.
            currentFrame = 0;
 
            // Zeichnen Sie die Animation neu.
            pictureBox1.Invalidate();
 
        }
 
    }
 
 
    public partial class Form1 : Form
    {
        public Form1()
        {
 
            InitializeComponent();
 
            PictureBox pictureBox1 = new PictureBox();
            pictureBox1.Width = 256;
            pictureBox1.Height = 384;
            pictureBox1.Visible = true;
            pictureBox1.Location = new Point(10, 10);
 
            Controls.Add(pictureBox1);
 
            PictureBox pictureBox2 = new PictureBox();
            pictureBox2.Width = 256;
            pictureBox2.Height = 384;
            pictureBox2.Visible = true;
            pictureBox2.Location = new Point(100, 100);
 
            Controls.Add(pictureBox2);
 
            PictureBox pictureBox3 = new PictureBox();
            pictureBox3.Width = 256;
            pictureBox3.Height = 384;
            pictureBox3.Visible = true;
            pictureBox3.Location = new Point(200, 200);
 
            Controls.Add(pictureBox3);
 
            PictureBox pictureBox4 = new PictureBox();
            pictureBox4.Width = 256;
            pictureBox4.Height = 384;
            pictureBox4.Visible = true;
            pictureBox4.Location = new Point(300, 300);
 
            Controls.Add(pictureBox4);
 
            // Laden Sie Ihr Spritesheet-Bild und passen Sie die Parameter an.
            Image spriteSheet = Image.FromFile("C:\\Users\\manuel\\Desktop\\EasyScript_RPG_Cutscene_Demo_Source\\Demo\\Resources\\NPC01.png");
            int frameWidth = 64; // Breite eines Frames in Pixeln
            int frameHeight = 96; // Höhe eines Frames in Pixeln
            int totalFrames = 4; // Gesamtanzahl der Frames in einer Spalte
 
            // Erstellen Sie eine Instanz der SpriteAnimation-Klasse.
            SpriteAnimation spriteAnimation1 = new SpriteAnimation(pictureBox1, spriteSheet, frameWidth, frameHeight, totalFrames, 0);
 
            // Starten Sie die Animation.
            spriteAnimation1.StartAnimation();
 
            for(int i = 0; i < 99999999; )
            {
                int t = (int)(Math.PI + i / Math.E);
                i++;
            }
 
            SpriteAnimation spriteAnimation2 = new SpriteAnimation(pictureBox2, spriteSheet, frameWidth, frameHeight, totalFrames, 1);
 
            // Starten Sie die Animation.
            spriteAnimation2.StartAnimation();
 
            for (int i = 0; i < 99999999;)
            {
                int t = (int)(Math.PI + i / Math.E);
                i++;
            }
 
            SpriteAnimation spriteAnimation3 = new SpriteAnimation(pictureBox3, spriteSheet, frameWidth, frameHeight, totalFrames, 2);
 
            // Starten Sie die Animation.
            spriteAnimation3.StartAnimation();
 
            for (int i = 0; i < 99999999;)
            {
                int t = (int)(Math.PI + i / Math.E);
                i++;
            }
 
            SpriteAnimation spriteAnimation4 = new SpriteAnimation(pictureBox4, spriteSheet, frameWidth, frameHeight, totalFrames, 3);
 
            // Starten Sie die Animation.
            spriteAnimation4.StartAnimation();
 
        }
 
    }
 
}