在WinForms上汇报开发2D引擎

介绍性


几年前,我想到了在WinForms上编写Visual Novel引擎的想法。 为什么在WinForms上? 因为那时我真的不知道怎么做。 引擎已定期收到并正在接收到当天的更新。 在这段时间里,积累了一些有用的代码,可以在任何地方使用。

将文本分成几行


// 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 = ""; } } } 

精灵和PictureBox


如您所知, PictureBox具有两个图像层。 BackgroundImage和图像。 在引擎的第一个版本中,我使用了大约5个框来绘制精灵。 这样的系统有几个很大的缺点:

  • 多级继承带来的透明性问题
  • 更新时布置表格

后来,我通过“图形”制作了该算法,因此可以在任意位置绘制任意数量的精灵。

 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和try-catch之类的功能


关于LuaInterface的经验:

  • 关于LuaTable的 LuaInterface文章的补充:在大多数情况下,仅使用表就可以不使用函数。

     lua.NewTable("Scene"); //   //     TextColor public string GetTextColor() { return (string)lua.GetTable("Font")["TextColor"]; } 
  • 使用表时出现内存泄漏问题
     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; } 

    每次调用GetTable时 ,都会获得一个新的CLR对象,该对象引用了此全局Lua变量引用的Lua表。
  • 如果您不确定表中的值是什么:

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

    Lua将返回一个值,但不会返回一个数字。 因此Catch(Exception) 。 带double.TryParse的选项在这里不适用,因为 lua.GetTable不返回字符串,而是返回某种类型的LuaTable ,如果为其分配了这样的值(也可以带有数字),则可以将其转换为字符串。

Source: https://habr.com/ru/post/zh-CN469599/


All Articles