DrawRectangle

  • C++/CLI

Es gibt 26 Antworten in diesem Thema. Der letzte Beitrag () ist von TheGameSiders.

    DrawRectangle

    Hey.

    Ich habe ein Panel und möchte dadrauf schonmal fest einen kleinen kasten in der Mitte zeichnen.
    Drumherum sollen dynamische Kästchen gezeichnet werden, wo die Anzahl und Position variabel ist und immer wieder geändert wird.
    Ich kriegs eventuell hin einmal einen Kasten zu zeichnen, aber wie zeichne ich immer wieder, und wo anders?
    Ich habe schon versucht wenigstens 1 statischen Punkt zu machen:

    C-Quellcode

    1. public: System::Void panel1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e)
    2. {
    3. Graphics^ graphicsObj = e->Graphics;
    4. Color aColor = Color::Green;
    5. SolidBrush^ aBrush = gcnew SolidBrush(aColor);
    6. e->Graphics->FillRectangle(aBrush, 100, 100, 200, 300);
    7. }


    Leider wird nichts gezeichnet wenn ich starte..

    Wie mach ich den einen statischen und dann drum herum dynamische?
    Es sollte ca. so aussehen dann:

    for each koordinateXY
    draw Rectangle(x,y,5,5,red)

    So in etwa. Hab das noch nie gemacht in c++ daher weiss ich nicht wie es aussehen muss :/
    Wär nett wenn mir da jemand bei helfen könnte, wenigstens erstmal bei dem Problem, dass bei dem Code oben nichts gezeichnet wird.

    Mfg. :)

    *Topic verschoben*

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Weil ich den ganzen anderen Rest schon in der DLL gemacht habe jetzt.
    Es geht immernoch um dieses Thema, aber ein bisschen anders nun:
    Koordinatensystem

    EDIT: Habe die Hälfte geschafft:

    C-Quellcode

    1. void pictureBox1_Paint(Object^ /*sender*/, System::Windows::Forms::PaintEventArgs^ e)
    2. {
    3. Graphics^ g = e->Graphics;
    4. //Mittelpunkt
    5. Graphics^ graphicsObj = e->Graphics;
    6. Color aColor = Color::GreenYellow;
    7. SolidBrush^ aBrush = gcnew SolidBrush(aColor);
    8. g->FillRectangle(aBrush, 67, 67, 5, 5);
    9. //Radius
    10. Pen^ blackPen = gcnew Pen(Color::LightYellow, 1.0f);
    11. System::Drawing::Rectangle rect = System::Drawing::Rectangle(26, 26, 85, 85);
    12. g->DrawEllipse(blackPen, rect);
    13. }


    Doch wie kann ich zur Laufzeit nun Rectangles verschieben, neu zeichnen, wo anders zeichnen? Das hier ist ja nur einmalig..

    EDIT2:
    Mit einer unendlichen for Schleife ist das machbar, aber wie lösche ich die Punkte die davor gezeichnet wurden? Letztes Problem :)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „TheGameSiders“ ()

    Das ist managed C++, das ist genauso performant wie C# und VB ;) . Zudem ist es eine der größten Fehlkonstruktion die MS sich geleistet hat. C++/CLI ist auch was anderes. GDI+ ist sogar noch relativ schnell, in Kombination mit GDI kommt das sogar fast an Direct2D ran. Wenn, dann würde ich das aber schön in C# machen.
    @TheGameSiders Schreib das ganze testweise mal in C# und wenn es läuft, übersetze es nach CLI, sofern das ühaupt erforderlich ist.
    Ich verwende CLI lediglich als .NET-Wrapper für native C++.
    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!
    @Gonger: Ich weiß, das c++ genauso performant ist wie c# - es ist sogar wesentlich performanter (egal ob nu managed oder nicht)
    Ich weiß aber auch, dass Gdi+ eine lahme Krücke ist - das ist halt designed, um unbewegliche Controls zu präsentieren mit starren Daten, die sich nur ändern, wenn der User das anweist.

    Kombination Gdi+ und Gdi?
    Ich weiß nicht recht, was du damit meinst, bin mir aber ziemlich sicher, dass das nicht an DirectX2D herankommt.
    Soweit ich weiß (korrigiert mich bitte) ist Gdi+ nur ein Wrapper um Gdi, und also ebensowenig hardwarebeschleunigt.

    Wie gesagt, mein Punkt ist: Auch die schnellste Sprache nützt in der Darstellung nicht die Bohne, wenn sie lahme Darstellungs-Technologien aufruft.

    Aber vlt. ist Geschwindigkeit ja garnet der Punkt, sondern der TE wollte es halt in c++ machen.
    GDI ist älter als GDI+. Aber ohne WinApi bekommt man in .Net leider keinen Zugriff.
    GDI Ist nämlich Hardwarebeschleunigt.

    @Te: Ich würde dir trotzdem von CLI abraten, es ist tatsächlich nur für Wrapper verwendbar. Ansonsten gibt es keinen Vorteil (eher im Gegenteil)
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Managed C++ ist genauso langsam wie C#. Normales Iso-C++ ist da deutlich schneller. Controls werden mit GDI gerendert und nicht mit GDI+. DrawFrameControl/DrawTheme*. Mit GDI+ kann man auch Animationen ganz flüssig darstellen. Es ist nicht so schnell wie Direct2D, aber ein Unterschied ist mit dem Auge nicht zu erkennen. Man muss nur wissen wie man GDI und GDI+ einsetzt. Ich sitze seit längerem an einer GUI-Library in C++, dort werden die Controls mit dem Interface graphics gerendert. Habe bis jetzt Direct2D und GDI+ 1.1 drin. Deswegen vergleiche ich beide eigentlich tgl. Das einzig wirklich blöde an GDI+ ist MeasureString, dass ist ungenau. Und DrawImage ist langsam, da braucht man BitBlt.
    ja, vlt. ists schlicht irreführend, die eine oder annere Sprache als schneller oder langsamer zu bezeichnen.
    Denn die zeitkritischen Sachen hat man ja garnet in EigenRegie unter Kontrolle, sondern das wird an diese oder jene Technologie delegiert (DirectX, GDI), und auf diese kommts dann an.

    Und managed c++ ist dann wohl deshalb gleichlahm, weils auf demselben GarbageCollector-Brimborium aufbaut?
    Aber ich hätte wenigstens gedacht, die ganz rohen Operationen: Zuweisungen, Multiplikationen, Schleifen, das solche Sachen doch schneller seien als in c#.

    Ich hab übrigens auch mal vor ewig mit BitBlt rumprobiert, fand aber keinen merkbaren Geschwindigkeits-Vorteil.
    Aber wenn ich mich recht erinnere, war das auch gar nicht so einfach zu messen.

    ErfinderDesRades schrieb:

    Und managed c++ ist dann wohl deshalb gleichlahm, weils auf demselben GarbageCollector-Brimborium aufbaut?

    Nein das ist es nicht. Es ist schlicht weg nichts anderes als C# oder VB.NET. Der Compiler verwendet teilweise ein paar andere IL Befehle die C# oder VB.NET nicht verwenden (ist aber bei C# gegenüber VB.NET genau gleich). Im Grunde kommt aber auch wieder nur eine IL-Assembly raus welche durch den JIT-Compiler läuft und dann ausgeführt wird. Es ist schlichtweg nichts anders. Bis auf die Syntax (und die hat wenig mit C++ gemeinsam) ist da nichts C++ ;) .


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    uff - das ist aber wirklich schlimm.
    Weil dass das c++ VisualStudio mir Methoden in Header-Dateien anlegt, wo's absolutely NoGo ist, hab ich ja auch schon gemerkt. Aber dasses auch keinen Leistungsvorteil bringt, und mit wirklichem c++ kompatibel dann wohl auch nicht - also das kann man ja gar nicht benutzen!

    Nicht zur Übung und schon garnet iwie produktiv

    ;(
    Scheint so ja. Einziger Vorteil ist halt, dass es eine nette Alternative zu PInvokes oder noch schlimmer, COM-Importen ist.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Es gibt 3 Arten von C++ in VS. Managed C++ (das hier, veraltet), C++/CLI und Visual C++. Visual C++ ist reines natives C++. In VS Win32-Projekt wählen -> Console/DLL und Häkchen bei "Leeres Projekt" setzen, sonst generiert VS da irgendeinen Mist rein. Dann hat man richtiges highlevel C++. Das ist dann schnell ;) .

    Methoden werden in C++ übrigens auch manchmal im Header definiert. Wenn sie als inline kompiliert werden sollen, oder ein Template ist.
    Hey :)

    Das ist zwar interessant was schneller ist und was nicht, aber helfen tuts mir nicht :)
    Es geht hier um Mathematik die ich nicht verstehe.

    Ich habe nun mich in die Mitte gesetzt.
    Um mich rum sollen Monster gezeichnet werden.
    Ich habe deren und meine Koordinaten.
    Ich habs jetzt so gelöst (Richtiger Mist):

    Mich in die Mitte gezeichnet.

    C-Quellcode

    1. If (MonsterKoordinateX > 1000 && MonsterKoordinateX < 2000) {
    2. MonsterKoordinate -= 1000
    3. }


    So komme ich ca. immer auf eine Zahl unter 100, die dann auf mein Panel gezeichnet werden kann. Das Problem: Es ist ungenau, nicht relativ zu meiner Position und ich habe 100 (Wirklich) Abfragen da sich X von 0 - 10000 erstreckt.

    Ich glaub ich muss die Entfernung von mir zu dem Monster berechnen, und dann verkleinern, dass es auf mein Panel passt.
    Das problem ist, was wenn MonsterX schon kleiner ist als MeinX, dann kann ich MonsterX nicht von mir abziehen.
    2tes Problem: Y ist IMMER im -Bereich. Wie berechne ich das dann?

    Danke trotzdem für eure Antworten :D

    Mfg.
    sorry, ja, das war jetzt doch ziemlich ins offtopic abgeglitten.
    Zum Topic kann ich auch garnix beitragen. Ich brauch immer eine Vorstellung des Datenmodells, also dass du da zwischen iwelchen Monstern sitzt, das reicht bei weitem nicht.
    Was haben die Monster denn für einen Datentyp, und welche Properties hat der Monster-Datentyp, und du selbst - hast du auch einen Datentyp, oder bist du der Einfachheit halber auch ein Monster?

    jdfs. die Entfernung zwischen 2 Punkten berechnet sich mit pythagoras:

    distanz =( (x1 - x2)^2 + (y1 - y2)^2 )^0.5

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Die vielen If-Abfragen kannst du dir sparen, indem du deine monster in einem array abspeicherst, statt für jedes Monster eine eigene Variable abzuspeichern. Wenn du dann möchtest, dass deine Monster immer im Sichtbereich des Panels sind, hast du zwei möglichkeiten:

    1. Du sorgst dafür, dass sich die Positionen des Monsters gar nicht erst außerhalb des Sichtbereiches befinden, oder

    2. Du bere hnest die relative Position, indem du die aktuelle Position erst durch die Maximale Position dividierst und diesen wert dann mit der maximalen Größe des Panels multiplizierst.

    TheGameSiders schrieb:

    Wie berechne ich das dann?
    Das Problem ist ein geeignetes Koordinatensystem.
    Üblicherweise ist der Ursprung in der Bildmitte, x läuft von links nach rechts und y von unten nach oben.
    In einer PictureBox ist der Ursprung oben links, x läuft nach rechts und y nach unten.
    So musst Du also eine geeignete Transformation schreiben, um von Deinem Spielsystem in das Darstellungssystem zu kommen.
    Poste mal Deine diesbezüglichen Basics.
    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!
    Ich habs jetzt gelöst und es funktioniert perfekt. Sogar was für eine Monsterart es ist kann ich nun farblich darstellen.
    Es flackert jetzt nur noch ein wenig, das muss ich beheben aber sonst gehts alles :) habs mit nem Struct gemacht wo alles drin ist und auch berechnet wird.

    Mfg.
    Ist natürlich erfreulich, dass du deine Probs lösen konntest, eiglich sogar besonders, dass du sie selbst gelöst hast.
    Nur für uns (für mich zumindest) etwas frustrierend, weil wir keine Ahnung haben, ob unsere Einlassungen für dich zumindest Anregungen enthalten haben, oder ob alles ins Klo geschwätzt war.

    Hier noch eine Anregung: Struct ist das falsche Mittel zur Monster-Modellierung. Eine Struct kannst du nicht an eine annere Methode geben und verändern, denn dort kommt nur die Kopie an und wird verändert.