Как стать автором
Поиск
Написать публикацию
Обновить

Учимся говорить по русски.

Наверняка, те кто заинтересовался созданием приложений с использованием XNA, столкнулись с проблемой вывода текста в кириллице. Дело в том, что XNA — инструмент, а не набор готовых средств и многие решения придется реализовывать самому. Как писалось в предыдущей статье XNA/XNA 3.0 – Быстрый старт для профи есть возможность создания своего контент процессора, чем мы и займемся.

Для начала создадим новый проект WindowsGameN. Думаю в картинках нет смысла показывать ).
Далее в дереве проекта добавим выбираем папку Content и добавляем новый объект SpriteFont1.spritefont, его можно открыть любым текстовым редакторов и внести изменения типа размер шрифта, наклон,… с этим разберетесь сами, ничего сложного простой xml файл.
Теперь создаем экземпляр класса SpriteFont на основе нашего SpriteFont1

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

SpriteFont m_SFont;

protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
m_SFont = Content.Load("SpriteFont1");
}


Если сейчас попробывать что-либо написать с использованием кириллицы то увидим ошибку.

image

Собственно, устранение которой мы займемся) Добавляем к имеющемуся солюшену новый проекту WindowsGameLibrary1.
Добавляем класс ContentProcessor1 и переписываем подобным образом:

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;

using TInput = System.String;
using TOutput = System.String;
using System.ComponentModel;
using System.IO;

namespace WindowsGameLibrary1
{
[ContentProcessor(DisplayName = "MyCharacterSetFontProcessor")]
public class Class1 : FontDescriptionProcessor
{
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)
{
string fullPath = Path.GetFullPath(MessageFile);
context.AddDependency(fullPath);

string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);

foreach (char c in letters)
{
input.Characters.Add(c);
}

return base.Process(input, context);
}

[DefaultValue("messages.txt")]
[DisplayName("Message File")]
[Description("Файл с символами которые будут автоматически добавлены в шрифте.")]
public string MessageFile
{
get { return messageFile; }
set { messageFile = value; }
}

private string messageFile = "..\\messages.txt";
}
}


В файле messages.txt содержатся нужные нам символы. Вкратце, мы читаем символы из файла и добавляем их в текущий процессор шрифта.
В файле могут содержаться как набор символов так и строки с фразами которые планируется выводить, повторяющиеся символы автоматически будут проигнорированы.
Мой файл выглядит так

йцукенгшщзхъэждлорпавыфячсмитьбюЙЦУКЕНГШЩЗХЪЭЖДЛОРПАВЫФЯЧСМИТЬБЮ


после этого нужно добавить зависимость проекта от библиотеки, для этого выбираем в дереве наш WindowsGameN, в контекстном меню выбираем Project Dependencies... и указываем зависимость от WindowsGameLibrary1

image

Добавляем референс на библиотеку.
Выбираем наш SpriteFont1.spritefont и в свойстве Content Processor выбираем наш MyCharacterSetFontProcessor.

Вот и все.
Далее тест:

protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

string message = "Все работает!";
Vector2 viewportSize = new Vector2(GraphicsDevice.Viewport.Width,
GraphicsDevice.Viewport.Height);
Vector2 textSize = m_sFont.MeasureString(message);
Vector2 textPosition = (viewportSize - textSize) / 2;

spriteBatch.Begin();
spriteBatch.DrawString(m_sFont, message, textPosition, Color.Black);
spriteBatch.End();

base.Draw(gameTime);
}


Вот и все, классы и проекты назвать ттолько нужно по человечески)
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.