Nachbesprechung Entwicklung 2D-Engine auf WinForms

Einführung


Vor ein paar Jahren hatte ich die Idee, eine Visual Novel-Engine auf WinForms zu schreiben. Warum auf WinForms? Denn dann wusste ich nicht wirklich wie. In regelmäßigen Abständen hat der Motor Aktualisierungen bis zum heutigen Tag erhalten und erhält diese. In dieser Zeit hat sich ein wenig nützlicher Code angesammelt, der überall verwendet werden kann.

Text in Zeilen aufteilen


// string ActorText -  ,      (Split(' ')) // text_width -  ,     // StrSize -    // StrEndl -    string ActorText_str = ""; //     int old_y = 35, StrSize = 0, StrEndl = 0; MessBox_1.Image = (Image)new Bitmap(MessBox_1.Width, MessBox_1.Height); using (Graphics g = Graphics.FromImage(MessBox_1.Image)) { //   old_y -= 14; for (var i = 0; i <= ActorText.Length; i++) { if (StrSize < text_width & i != ActorText.Length) { StrSize += ActorText[i].Length; if (i != ActorText.Length - 1 & (StrSize + ActorText[i + 1].Length >= text_width)) StrSize = text_width + 12; } else { // String builder for (int CreatLineIter = StrEndl; CreatLineIter < i; CreatLineIter++) ActorText_str += ActorText[CreatLineIter] + " "; // Set endl pos StrEndl = i; if (i != ActorText.Length) StrSize = ActorText[i].Length; old_y += 14; // SetColor(lua.GetTextColor())) -    .   . g.DrawString(ActorText_str, new Font(lua.GetTextFont(), 10, FontStyle.Bold), new SolidBrush(SetColor(lua.GetTextColor())), new Point(10, old_y)); ActorText_str = ""; } } } 

Sprites und PictureBox


Wie Sie wissen, verfügt PictureBox über zwei Bildebenen. Hintergrundbild & Bild. In den ersten Versionen der Engine habe ich ungefähr 5 Boxen verwendet, um Sprites zu zeichnen. Ein solches System hatte mehrere große Nachteile:

  • Probleme mit der Transparenz aufgrund der mehrstufigen Vererbung
  • Legen Sie beim Aktualisieren Formulare an

Später habe ich den Algorithmus über Grafik erstellt, sodass es möglich wurde, Sprites so oft zu zeichnen, wie Sie möchten.

 PictureBox ALeft; Bitmap SpriteListPic; //       // FreeMovePicture - ,    // posX, posY -    // Scale -  private void SpriteBoxesHolder(Image FreeMovePicture, int posX, int posY, float Scale = 2) { using(Graphics SpGr = Graphics.FromImage(SpriteListPic)) { SpGr.DrawImage(FreeMovePicture, posX * 2, posY * 2, FreeMovePicture.Size.Width / Scale, FreeMovePicture.Size.Height / Scale); } ALeft.Image = SpriteListPic; } 

LuaInterface und Try-Catch-ähnliche Funktion


Ein wenig über die Erfahrung mit LuaInterface:

  • Ergänzung zu einem Artikel über LuaInterface über LuaTable: In den meisten Fällen können Sie auf Funktionen verzichten, indem Sie nur Tabellen verwenden.

     lua.NewTable("Scene"); //   //     TextColor public string GetTextColor() { return (string)lua.GetTable("Font")["TextColor"]; } 
  • Probleme mit Speicherlecks bei der Arbeit mit Tabellen
     string TableReaderS(string Table, string Key) { string Ret = ""; using (LuaTable tabx = lua.GetTable(Table)) { Ret = (string)tabx[Key]; } return Ret; } int TableReaderI(string Table, string Key) { int Ret = -1; using (LuaTable tabx = lua.GetTable(Table)) { Ret = (int)(double)tabx[Key]; //   int ... } return Ret; } 

    Jedes Mal, wenn Sie GetTable aufrufen , erhalten Sie ein neues CLR-Objekt, das auf die Lua-Tabelle verweist, auf die diese globale Lua-Variable verweist.
  • Wenn Sie sich nicht sicher sind, welchen Wert die Tabelle überhaupt hat:

     try { Size = TableReaderI("Scene", "Image" + Convert.ToString(num) + "Scale"); } catch (Exception ex) { Size = 2; } 

    Lua gibt einen Wert zurück, aber nicht die Tatsache, dass es sich um eine Zahl handelt. Deshalb fangen (Ausnahme) . Die Option mit double.TryParse ist hier nicht geeignet, weil lua.GetTable gibt keine Zeichenfolge zurück, sondern einen bestimmten Typ, der LuaTable ist und in eine Zeichenfolge konvertiert werden kann, wenn ihm ein solcher Wert zugewiesen wurde, auch mit einer Nummer.

Source: https://habr.com/ru/post/de469599/


All Articles