Raster über Picturebox legen

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von aw1973.

    Raster über Picturebox legen

    Hallo,

    ich probiere gerade etwas für unsere Jugend auf dem Schützenfest zu bauen.

    Wir haben ein System, mit dem kann man mit einer Laserwaffe (Gewehr/Pistole) auf eine Leinwand schießen, das System läuft im Hintergrund und löst dann auf dem Computer einen Mausklick an der entsprechenden Position aus.
    Ein Test mit Picturebox und CreateGraphics klappt wunderbar um Kreise an der Position des Einschusses zu zeichnen.

    Nun möchte ich folgendes, in der PictureBox wird ein Vogel (wie vom Schützenfest) abgebildet, den sollen die Kids runterholen. Mir fehlt so etwas der Ansatz gerade, die ich das angehe.
    Überlegt habe ich; ein Raster (in Form einer Tabelle) über die PB legen, den Vogel in den Hintergrund und wenn ein Feld getroffen wird (OnClick) wird es eingefärbt mit der Hintergrundfarbe.

    Es muss ein Raster vorhanden sein, damit das ganze keine Pixelshow wird. Ich dachte an 100x100 Felder, Die Felder sollten definierbar sein, so das man mitbekommt, wenn der Vogel fliegt.


    Für hinweise bin ich danbkbar.

    Viele Grüsse

    Andreas
    Willkommen im Forum.

    Ich werd aus der Beschreibung nicht ganz schlau.
    Was habe ich verstanden: Eine PicBox mit einem Vogelbild, welche sich bewegt (Vogel fliegt). Ist die Bewegung egal oder nur von links nach rechts?
    Wenn der User an eine bestimmte Stelle klickt (alias mit der Laserwaffe auf die Leinwand schießt), soll entweder was gezeichnet werden oder irgendwas soll die Hintergrundfarbe von irgendwas bekommen. Sollbilder wären an der Stelle sinnvoll, weil ich aus der Beschreibung nicht schlau werde, was da sich in was ändern soll. Vogel durchlöchert oder Einschusslöcher zeichnen?
    Das mit dem Raster ist zwar an sich einfach zu zeichnen, das mit der Pixelshow hingegen habe ich nicht verstanden und den Sinn dahinter auch nicht begriffen.
    Aber: CreateGraphics ist in 98 % der Anwendungsfälle falsch. Der wohl zu verwendende Form.Paint- oder PicBox.Paint-EventHandler stellt ein Graphics-Objekt zur Verfügung, welches genutzt werden sollte.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    hier mal 2 Bilder. (später ist da ein Schützenfest Holzvogel zu sehen...)

    Die roten Linien sind nur zum testen.





    Sobald ein Schuss in der Leinwand erkannt wird (Roter kreis (noch nicht mittig)) wird ein Teil des Bildes (Vogel) ausgeblendet.
    Jetzt mache ich das mit .FillRectangle(Brushes.White...)




    im Prinzip funktioniert das soweit, ich muss halt vorher festlegen welche Bereich getroffen werden müssen und das mein Programm merkt, wann alles weg ist.

    Ich bin mit dem Ansatz nicht wirklich zufrieden, allerdings fehlt mir auch die Erfahrung mit VB (meine Letzen VB Experimente waren zu Windows 95 Zeiten)


    VB.NET-Quellcode

    1. Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
    2. Dim SX As Integer
    3. Dim SY As Integer
    4. SX = PictureBox1.PointToClient(Cursor.Position).X
    5. SY = PictureBox1.PointToClient(Cursor.Position).Y
    6. Dim SXc As Integer
    7. Dim SYc As Integer
    8. SXc = CSng(CInt(SX / 10) * 10)
    9. SYc = CSng(CInt(SY / 10) * 10)
    10. TextBox1.Text = PictureBox1.PointToClient(Cursor.Position).ToString() & CSng(CInt(SX / 10) * 10) & "/" & CSng(CInt(SY / 10) * 10)
    11. Dim g As Graphics = PictureBox1.CreateGraphics
    12. Dim Radius = 30
    13. Dim rectangle As New Rectangle(SXc,
    14. SYc,
    15. Radius, Radius)
    16. Dim Shot As New Rectangle(SXc,
    17. SYc,
    18. 9, 9)
    19. g.FillRectangle(Brushes.White, rectangle)
    20. g.DrawEllipse(Pens.Red, Shot)
    21. End Sub
    @aw1973 Falsche Herangehensweise.
    Arbeite im MouseDown-Event, da bekommst Du die korrekten Koordinaten.
    Invalidisiere den entsprechenden Bereich und male dann im Paint-Event der PictureBox.
    Die Koordinaten musst Du dann allerdings in der Klasse zwischenspeichern.
    Und teste dies:
    Öffne das Notepad, positioniere es über Deinem Bild, lasse es los und minimiere es.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    @aw1973 Falsche Herangehensweise.
    Arbeite im MouseDown-Event, da bekommst Du die korrekten Koordinaten.


    Die Koordinaten will ich am liebsten direkt aus dem Netzwerk der Treffererkennung abrufen, das ist aber erstmal im Hintergrund...
    Primär gehts um die Darstellung


    RodFromGermany schrieb:


    Invalidisiere den entsprechenden Bereich und male dann im Paint-Event der PictureBox.
    Die Koordinaten musst Du dann allerdings in der Klasse zwischenspeichern.
    Und teste dies:
    Öffne das Notepad, positioniere es über Deinem Bild, lasse es los und minimiere es.


    Mit dem Notepad verstehe ich nicht!
    Was hältst Du von der Idee Dir einen Treffermatrix anzulegen (2-Dimensionales Array). Darin kannst Du dann eintragen welcher Bereich schon getroffen. Diese Matrix kannst Du dann auch durchsuchen, ob alle gewünschten Einträge vorhanden sind.
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).
    Das mit dem Notepad ist ein Programm-Test. Wenn Dein Programm läuft und Du das notepad-Fenster über Dein Programmfenster ziehst, wirst Du entweder was Auffälliges sehen oder eben nicht. Wenn nicht, hast Du richtig programmiert. Mehr will ich erstmal nicht verraten :rolleyes:
    Es geht also darum festzustellen, wieviele Teile des Vogels schon getroffen wurden. Hm, ok, aber das fänd ich als Spieler nicht besonders prickelnd, wenn ich einen Vogel vor mir habe. Der kann ja gerne ein paar Zonen haben, die er auch getroffen überlebt. Aber einen sich bewegenden Zombievogel zu haben, der auch ohne Kopf fliegt, fänd ich befremdlich.
    Auch das Raster über der Leinwand wäre nix. Der Vogel soll ja durchlöchert werden. Es reichen also (viele kleine) Zonen in der VogelPicBox. Auf dem Hintergrund können ja Einschusslöcher gemalt werden. Aber für die Zielübungslogik braucht es das Raster eben nur für den Vogel.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:

    Das mit dem Notepad ist ein Programm-Test. Wenn Dein Programm läuft und Du das notepad-Fenster über Dein Programmfenster ziehst, wirst Du entweder was Auffälliges sehen oder eben nicht. Wenn nicht, hast Du richtig programmiert. Mehr will ich erstmal nicht verraten :rolleyes:


    Ahh! ok, das klappt :)


    VaporiZed schrieb:

    Es geht also darum festzustellen, wieviele Teile des Vogels schon getroffen wurden. Hm, ok, aber das fänd ich als Spieler nicht besonders prickelnd, wenn ich einen Vogel vor mir habe. Der kann ja gerne ein paar Zonen haben, die er auch getroffen überlebt. Aber einen sich bewegenden Zombievogel zu haben, der auch ohne Kopf fliegt, fänd ich befremdlich.


    So ist es halt auf den Festen, es wird mit einer Schrotflinte auf den Vogel geschossen, teile fallen ab und wer das letze stück auf den Boden wirft ist Schützenkönig.

    VaporiZed schrieb:

    Auch das Raster über der Leinwand wäre nix. Der Vogel soll ja durchlöchert werden. Es reichen also (viele kleine) Zonen in der VogelPicBox. Auf dem Hintergrund können ja Einschusslöcher gemalt werden. Aber für die Zielübungslogik braucht es das Raster eben nur für den Vogel.


    Das beste wäre, man könnte Formen/Zonen frei einzeichnen ähnlich die wie HTML Imgmap, wenn in der Zone ein Treffer ist, fällt das teil runter, also wird überlagert/ausgeblendet wie auch immer.

    Das ganze wäre die Perfekte Aufgabe für das "Flash" :)
    Da wär eine Möglichkeit, dass das Vogelbild eben aus mehreren PicBoxen besteht und wenn eine getroffen ist, fällt die ab oder verschwindet oder wasauchimmer. Und wenn die letzte PicBox getroffen ist, ist ausdieMaus. Leider wären die PicBoxBilder dann rechteckig.
    Das mit der Imagemap, ach da war mal was. Man kann schon Polygondaten definieren, aber das weiß ich leider nicht mehr im Detail.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hallo,

    ich hab mal in Excel mittels API`s das Excel-Fenster in verschiedene Formen gebracht.

    hab das nach längerem hin und her mit den Variablentypen nun auch mal auf eine Picturebox anwenden können.
    ( Mit den Variablentypen bin ich unter NET und Win64 noch nicht ganz durchgestiegen, im VBA sind bei den API's alle Typen LONG)

    So kann man einer Picturebox eine "beliebige" Form geben.


    VB.NET-Quellcode

    1. Private Declare Function CreatePolygonRgn Lib "gdi32" (ByRef lpPoint As POINTAPI, ByVal nCount As Integer, ByVal nPolyFillMode As Integer) As Integer
    2. Private Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As IntPtr, ByVal hRgn As Integer, ByVal bRedraw As Boolean) As Integer
    3. Structure POINTAPI
    4. Dim x As Integer
    5. Dim y As Integer
    6. End Structure
    7. Private Sub Form1_Click(sender As Object, e As EventArgs) Handles Me.Click
    8. Dim region As Integer
    9. Dim ret As Integer
    10. Dim count As Integer = 5
    11. Dim iMode As Integer = 1
    12. Dim p(count) As POINTAPI
    13. p(0).x = 0 : p(0).y = 0
    14. p(1).x = 80 : p(1).y = 50
    15. p(2).x = 20 : p(2).y = 100
    16. p(3).x = 120 : p(3).y = 100
    17. p(4).x = 100 : p(4).y = 0
    18. region = CreatePolygonRgn(p(0), count, iMode)
    19. ret = SetWindowRgn(PictureBox1.Handle, region, True)
    20. End Sub

    Hallo,

    ich habe nun viel experimentiert und wieder echt spass am VB bekommen :)
    Für das Projekt, habe ich nun als Frontend Unity verwendet, eine Umgebung die für genau den Zweck entwickelt wurde und im Hintergrund läuft ein kleines VB Program das zwischen Treffererkennung und Spiele kommuniziert.