استخلاص المعلومات محرك 2D التنمية على WinForms

خلفية


قبل بضع سنوات ، توصلت إلى فكرة كتابة محرك Visual Novel على WinForms. لماذا على 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 ومحاولة مثل ميزة الصيد


قليلا عن تجربة LuaInterface:

  • ملحق لمقال عن LuaInterface حول LuaTable: بالنسبة لمعظم الأشياء ، يمكنك الاستغناء عن الوظائف باستخدام الجداول فقط.

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

    لوا سيعود قيمة ، ولكن ليس حقيقة أنه سيكون رقما. لذلك قبض (استثناء) . الخيار مع double.TryParse غير مناسب هنا ، لأن لا يُرجع lua.GetTable سلسلة ، لكن نوعًا معينًا ، وهو LuaTable ويمكن تحويله إلى سلسلة إذا تم تعيين مثل هذه القيمة ، أيضًا برقم.

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


All Articles