Вводная
Пару лет назад мне пришла идея написать движок для Visual Novel на WinForms. Почему на WinForms? Потому что тогда я ничего другого и не умел толком. Периодически движок получал и получает обновления по настоящий день. За это время накопилось немного полезного кода, который может использоваться повсеместно.
Разделение текста на строки
string ActorText_str = ""; // Конечная строка для отрисовки
// string ActorText - весь текст, разбитый на массив по словам (Split(' '))
int old_y = 35, str = 0, num = 0;
MessBox_1.Image = (Image)new Bitmap(MessBox_1.Width, MessBox_1.Height);
Graphics g = Graphics.FromImage(MessBox_1.Image);
// Считаем строки
old_y -= 14;
for (var i = 0; i <= ActorText.Length; i++)
{
if (str < text_width & i != ActorText.Length)
{
str += ActorText[i].Length;
if (i != ActorText.Length - 1)
if (str + ActorText[i + 1].Length >= text_width)
str = 1116;
}
else
{
for (int j = num + 1; j <= i; j++)
ActorText_str += ActorText[j - 1] + " ";
if (i != ActorText.Length)
str = ActorText[i].Length;
old_y += 14;
num = i;
g.DrawString(ActorText_str, new Font(lua.GetTextFont(), 10, FontStyle.Bold), new SolidBrush(SetColor(lua.GetTextColor())), new Point(10, old_y)); // В целом, можно и TextBox использовать
ActorText_str = "";
}
}
g.Dispose(); // Удаляем Graphics
Спрайты и PictureBox
Как известно, PictureBox имеет два слоя изображения. BackgroundImage & Image. В первых версиях движка для отрисовки спрайтов я использовал порядка 5 боксов. Такая система имела несколько больших минусов:
- Проблемы с прозрачностью из-за многоуровневой наследовательности
- Пролаги формы при обновлении
Позже я сделал алгоритм через Graphics, благодаря чему стало возможно рисовать спрайты сколько угодно и где угодно.
PictureBox ALeft;
Bitmap SpriteListPic; // Наш массив спрайтов для текущего кадра
// FreeMovePicture - Спрайт, который нужно отрисовать
// posX, posY - Позиция на форме
// Scale - Масштабирование
private void SpriteBoxesHolder(Image FreeMovePicture, int posX, int posY, float Scale = 2)
{
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:
- Дополнение для статьи по LuaInterface по поводу LuaTable: Для большинства вещей можно обойтись и без функций, используя только таблицы.
lua.NewTable("Scene"); // Создаём таблицу // Достаём из таблицы значение TextColor public string GetTextColor() { return (string)lua.GetTable("Font")["TextColor"]; }
- Если вы не уверены, что такое значение в таблице вообще есть:
Try { Size = (double)lua.GetTable("Scene")["Image" + Convert.ToString(num) + "Scale"]; } catch (Exception ex) { Size = 2; }
Lua вернёт значение, но не факт, что оно будет числом. Поэтому Catch(Exception).
nazgul-e0
Важно помнить что обработка Exception достаточно ресурсоемкий процесс.
В этом случае более корректно использовать проверку на null + Double.TryParse