@Mods
Es gibt leider keinen SourceCodeAustausch für "weitere Programmiersprachen", deswegen hab ich das hier reingepackt.
Wenns doch in den normalen SourceCodeAustausch gehört, kann das ja verschoben werden.
Beschreibung:
Mit diesem Code hier könnt ihr Pixelgenau bestimmen, ob ein bestimmter Punkt eines Bildes ein Kollision verursacht oder nicht. Er ist vollständig kommentiert.
Da ich LockBits in Verbindung mit Unsafe verwendet habe, kann er leider nicht ohne weiteres nach VB konvertiert werden, dafür ist das ganze um einiges schneller.
Die Laufzeit beträgt O(1), also sie ist für beliebig große Bilder gleich schnell. Nur die Initialisierung benötigt bei größeren Bildern länger.
Spoiler anzeigen
Verwendung ist denke ich mal klar.
Erst eine neue Instanz mit dem gewünschten Bild erstellen, dann kann einfach mit PixelVisible abgefragt werden, ob ein bestimmter Punkt sichtbar ist oder nicht.
Edit Version 1.1: dank ~blaze~ konnte ich den Code noch etwas optimieren, die Initialisierung sollte nun nur noch etwa ein Drittel der alten Zeit brauchen.
Das ganze ist übrigens durch diesen Thread entstanden.
Es gibt leider keinen SourceCodeAustausch für "weitere Programmiersprachen", deswegen hab ich das hier reingepackt.
Wenns doch in den normalen SourceCodeAustausch gehört, kann das ja verschoben werden.
Beschreibung:
Mit diesem Code hier könnt ihr Pixelgenau bestimmen, ob ein bestimmter Punkt eines Bildes ein Kollision verursacht oder nicht. Er ist vollständig kommentiert.
Da ich LockBits in Verbindung mit Unsafe verwendet habe, kann er leider nicht ohne weiteres nach VB konvertiert werden, dafür ist das ganze um einiges schneller.
Die Laufzeit beträgt O(1), also sie ist für beliebig große Bilder gleich schnell. Nur die Initialisierung benötigt bei größeren Bildern länger.
C#-Quellcode
- /// <summary>
- /// Führt pixelgenaue Kollisionserkennungen für Bitmaps aus.
- /// </summary>
- public class CollisionObject
- {
- byte[] bytes;
- int width, height;
- /// <summary>
- /// Erstellt ein neues CollisionObject aus der angegebenen Bitmap.
- /// </summary>
- /// <param name="bmp"></param>
- public CollisionObject(Bitmap bmp)
- {
- //Höhe und Breite des Bildes Speichern
- width = bmp.Width;
- height = bmp.Height;
- //LockBits für bessere Performance
- var data = bmp.LockBits(new Rectangle(0,0,bmp.Width,bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
- //Byte-Array erstellen
- bytes = new byte[(width * height + 7) / 8]; //Bytes anlegen
- int index = 0; //Position im Array
- int posInByte = 0; //Position des aktuellen Bits im Byte
- unsafe
- {
- for (byte* alpha = (byte*)data.Scan0 + 3, lastAlpha = alpha + width * height * 4; alpha < lastAlpha; alpha += 4 )
- {
- //Alphakanal des aktuellen Pixels prüfen
- if (*alpha > 0)
- bytes[index] = (byte)(bytes[index] | (1 << posInByte)); //wenn Pixel nicht transparen, Bit auf 1 setzen
- posInByte++; //Bitposition erhöhen
- //wenn Byte voll, nächstes auswählen
- if (posInByte == 8)
- {
- index++;
- posInByte = 0;
- }
- }
- }
- bmp.UnlockBits(data); //Bild freigeben
- }
- /// <summary>
- /// Bestimmt, ob das Bild an einer angegebenen Stelle transparent ist oder nicht.
- /// </summary>
- /// <param name="pos"></param>
- /// <returns></returns>
- public bool PixelVisible(Point pos)
- {
- if (pos.X < 0 || pos.Y < 0 || pos.X >= width || pos.Y >= height)
- return false; //Punkt liegt außerhalb der Bildes
- //Position des Bits berechnen
- var bitIndex = pos.Y * width + pos.X; //Gesammtindex berechnen
- var byteIndex = bitIndex / 8; //Index des Bytes im Array berechnen
- var posInByte = bitIndex % 8; //Index des Bits im Byte berechnen
- //Prüfen, ob das Bit 1 ist
- var val = (byte)(1 << posInByte);
- return (bytes[byteIndex] & val) == val;
- }
- }
Verwendung ist denke ich mal klar.
Erst eine neue Instanz mit dem gewünschten Bild erstellen, dann kann einfach mit PixelVisible abgefragt werden, ob ein bestimmter Punkt sichtbar ist oder nicht.
Edit Version 1.1: dank ~blaze~ konnte ich den Code noch etwas optimieren, die Initialisierung sollte nun nur noch etwa ein Drittel der alten Zeit brauchen.
Das ganze ist übrigens durch diesen Thread entstanden.
Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „Artentus“ ()