Desarrollo de un motor 2D de desarrollo en WinForms

Introductorio


Hace un par de años se me ocurrió la idea de escribir un motor de Novela Visual en WinForms. ¿Por qué en WinForms? Porque entonces realmente no sabía cómo. Periódicamente, el motor ha recibido y está recibiendo actualizaciones hasta el día de hoy. Durante este tiempo, se ha acumulado un pequeño código útil que se puede usar en todas partes.

División de texto en líneas


// 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 y PictureBox


Como sabes, PictureBox tiene dos capas de imágenes. Imagen de fondo e imagen. En las primeras versiones del motor, usé alrededor de 5 cajas para dibujar sprites. Tal sistema tenía varias grandes desventajas:

  • Problemas con la transparencia debido a la herencia multinivel
  • Diseñe formularios al actualizar

Más tarde, hice el algoritmo a través de Gráficos, por lo que fue posible dibujar sprites tanto como quieras en cualquier lugar.

 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; } 

Característica LuaInterface y try-catch


Un poco sobre la experiencia con LuaInterface:

  • Suplemento para un artículo en LuaInterface sobre LuaTable: para la mayoría de las cosas, puede prescindir de funciones utilizando solo tablas.

     lua.NewTable("Scene"); //   //     TextColor public string GetTextColor() { return (string)lua.GetTable("Font")["TextColor"]; } 
  • Problemas con pérdidas de memoria al trabajar con tablas
     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; } 

    Cada vez que llama a GetTable , obtiene un nuevo objeto CLR que hace referencia a la tabla Lua a la que hace referencia esta variable global Lua.
  • Si no está seguro de cuál es el valor de la tabla:

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

    Lua devolverá un valor, pero no el hecho de que será un número. Por lo tanto, captura (excepción) . La opción con double. TryParse no es adecuada aquí, porque lua.GetTable no devuelve una cadena, sino un cierto tipo, que es LuaTable y se puede convertir en una cadena si se le asignó dicho valor, también con un número.

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


All Articles