Čukča nav lasītājs! Čukča rakstnieks! Lidinators v0.7
Nu ko, labs laiciņš pagājis, kopš pēdējās Lidinatora sērijas. Pienācis laiks seriālu atdzīvināt un šodienas sērijas tēma – teksta izvadīšana uz ekrāna.
Teksta izvadīšanai XNA neizmanto vektoru šrifta tehnoloģijas (piem., OpenType), bet atgriežas pie rastra šriftiem. Nē, tas nenozīmē, ka izstrādātājam ir jāizzīmē katra rakstzīme, vienkārši XNA satura konveijers kompilācijas laikā nodrošina vektoru šrifta pārveidošanu par rastra šriftu, kuru atspoguļo SpriteFont klase.
Šajā vietā laikam jāievieto juridiskā atruna. Ir kāds fakts, kuru varbūt ne visi zina, bet šrifti, gluži kā programmatūra, tiek izplatīti ar kādu licenci. Un ne vienmēr šī licence pieļauj tālāku šrifta izplatīšanu. Tātad, lai nesanāktu juridiskas dabas problēmas ir ieteicams noskaidrot, kas izmantotā šrifta licencē ir minēts par tā tālāku izplatīšanu. Microsoft XNA Game Studio ir iekļāvis dažus šriftus, kuru izplatīšana ir atļauta (pieejami arī atsevišķai lejupielādei), tāpat, cik es saprotu, Open Font Library pieejamos šriftus var izplatīt.
Pēc tam, kad ir noskaidrots, kādu šriftu izmantot, nepieciešams to pievienot XNA projekta saturam, “Content” sadaļā izvēloties "Add” –> “New Item”. Dialoga logā izvēlamies tipu “Sprite Font” un ierakstam nosaukumu kāds šriftam tiks izmantots kodā.
Atverot SpriteFont failu Visual Studio redaktorā, var redzēt, ka tas ir XML fails, kurā tiek definēts izmantotais šrifts un tā īpašības. Mainot FontName elementu, var nomainīt izmantoto šriftu:
<FontName>Miramonte</FontName>
Tālāk nedaudz jāpapildina resursu ielādēšanas kods:
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
baseFont = this.Content.Load<SpriteFont>("BaseFont");
base.LoadContent();
}
Un kadra zīmēšanas kods, izmantojot SpriteBatch.DrawString metodi:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(backgroundColor);
base.Draw(gameTime);
this.spriteBatch.Begin();
for (int i = 0; i < this.ships.Count; i++)
{
string text = String.Concat(
"Ship ",
(i + 1),
" HP: ",
this.ships[i].Health);
this.spriteBatch.DrawString(
this.baseFont,
text,
new Vector2(0, i * 50),
this.ships[i].Tint);
}
this.spriteBatch.End();
}
Rezultāts:
Manuprāt, atstarpe starp teksta rindām ir pārāk liela, bet to var labot. Viens no variantiem būtu izmainīt maģisko konstanti 50 zīmēšanas metodes kodā, bet šāds risinājums nebūtu pārāk elastīgs. Piemēram, izmainot šrifta lielumu, izmainītos arī atstarpe starp rindām. Labāk būtu izmantot pārnešanu jaunā rindā, vai arī noteikt teksta izmēru ar SpriteFont.MeasureString metodi, un aprēķināt nākošās rindas pozīciju. Pirmais variants būs labāks gadījumos, kad teksts ir jāizvada vairākās rindās pēc kārtas, savukārt otrais ļauj daudz precīzāk pozicionēt tekstu gan pa horizontāli, gan vertikāli.
Izvēlējos otro variantu, jo tas nākotnē paver plašākas pozicionēšanas iespējas.
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(backgroundColor);
base.Draw(gameTime);
this.spriteBatch.Begin();
float textY = 0;
for (int i = 0; i < this.ships.Count; i++)
{
string text = String.Concat(
"Ship ",
(i + 1),
" HP: ",
this.ships[i].Health);
this.spriteBatch.DrawString(
this.baseFont,
text,
new Vector2(0, textY),
this.ships[i].Tint);
textY += this.baseFont.MeasureString(text).Y;
}
this.spriteBatch.End();
}
Piekrītat, ka izskatās labāk?
Līdz nākošajai sērijai!
pirmkods