雨天延期しまくったやつの末路
取り付けに行かないとならないエアコンに埋もれている山田です。こんばんは。
ツイッターのDMでリクエストがあったので、今回は文字表示のプログラムのお話です。おまたせしました。
第4回
の時にも少し書きましたが、PSMの文字列の表示は、みんなが悩むポイントみたいです。山田もいまだにです。
PSMで文字列の表示の方法はいくつかあって、人それぞれでベストな方法はわかりませんので、いろいろ試してください。
(0)準備編
今回のプログラムは
Sce.PlayStation.Core.Imaging
Sce.PlayStation.HighLevel.UI
を使いますので、Using文に追加して下さい。
HiglLevel.UIはソリューションウィンドウの”参照”をダブルクリックして出てきたウィンドウに中のSce.PlayStation.HighLevel.UIのところをチェックを入れて下さい。
HighLevel.UIでの基本形(何も表示しない)
using System;
using System.Collections.Generic;
using Sce.PlayStation.Core;
using Sce.PlayStation.Core.Environment;
using Sce.PlayStation.Core.Graphics;
using Sce.PlayStation.Core.Input;
using Sce.PlayStation.Core.Imaging;
using Sce.PlayStation.HighLevel.UI;
namespace mojitest
{
public class AppMain
{
private static GraphicsContext graphics;
static Scene scene;
static Label label;
public static void Main (string[] args)
{
Initialize ();
while (true) {
SystemEvents.CheckEvents ();
Update ();
Render ();
}
}
public static void Initialize ()
{
// Set up the graphics system
graphics = new GraphicsContext ();
//UISystemを初期化します
UISystem.Initialize(graphics);
//シーンを作成します
scene = new Scene();
UISystem.SetScene(scene);
//newで作ります
label = new Label();
//これを書くと、シーンの後ろにウィジェットが追加されます
scene.RootWidget.AddChildLast (label);
}
public static void Update ()
{
// Query gamepad for current state
var gamePadData = GamePad.GetData (0);
List touchData = Touch.GetData(0);
//UISystemの更新です
UISystem.Update(touchData);
}
public static void Render ()
{
// Clear the screen
graphics.SetClearColor (0.0f, 0.0f, 0.0f, 0.0f);
graphics.Clear ();
//UISystemを描画します
UISystem.Render();
// Present the screen
graphics.SwapBuffers ();
}
}
}
(1)一番簡単な方法
それは、HighLevel.UI の Labelを使うこと。
using System;
using System.Collections.Generic;
using Sce.PlayStation.Core;
using Sce.PlayStation.Core.Environment;
using Sce.PlayStation.Core.Graphics;
using Sce.PlayStation.Core.Input;
using Sce.PlayStation.Core.Imaging;
using Sce.PlayStation.HighLevel.UI;
namespace mojitest
{
public class AppMain
{
private static GraphicsContext graphics;
static Scene scene;
static Label label;
public static void Main (string[] args)
{
Initialize ();
while (true) {
SystemEvents.CheckEvents ();
Update ();
Render ();
}
}
public static void Initialize ()
{
// Set up the graphics system
graphics = new GraphicsContext ();
UISystem.Initialize(graphics);
scene = new Scene();
UISystem.SetScene(scene);
label = new Label();
label.Text = "テキスト文字列です";
label.X = 0;
label.Y = 0;
label.Width = 960;
label.Height = 544;
label.TextColor = new UIColor(1.0f,1.0f,1.0f,1.0f);
label.Font = new UIFont(FontAlias.System,60,FontStyle.Bold);
label.HorizontalAlignment = HorizontalAlignment.Right;
label.VerticalAlignment = VerticalAlignment.Middle;
label.LineBreak = LineBreak.AtCode;
label.Alpha = 1.0f;
label.Visible = true;
scene.RootWidget.AddChildLast (label);
}
public static void Update ()
{
// Query gamepad for current state
var gamePadData = GamePad.GetData (0);
List touchData = Touch.GetData(0);
UISystem.Update(touchData);
}
public static void Render ()
{
// Clear the screen
graphics.SetClearColor (0.0f, 0.0f, 0.0f, 0.0f);
graphics.Clear ();
UISystem.Render();
// Present the screen
graphics.SwapBuffers ();
}
}
}
解説:
簡単に文字列を表示することができます。オブジェクト指向な感じで、ドットを付けてX とか Fontとか書けば変更されます。このHighLevel.UIのLabelは、とても遅いです。これが速く動くんであれば、誰も何も悩まないのに。100文字ぐらいだと処理落ちしないで表示されます。文字が増えれば増えるほど処理落ちします。最後は止まりそうなぐらいに。ただ簡単にImageBox のイメージと一緒にシーンに追加して扱えるので処理落ちしてもいい所には使います。「デッドエンドヴァレンタイ」だとバックログの文字表示や、セーブデータの日付表示に使っています。なぜ使うのかというと、この先のやり方だととても行数が多くなるので・・・。
長所:とても簡単
短所:とても遅い
(2)文字を画像にする方法
Labelを使わないので多少スピードアップを図れます。
using System;
using System.Collections.Generic;
using Sce.PlayStation.Core;
using Sce.PlayStation.Core.Environment;
using Sce.PlayStation.Core.Graphics;
using Sce.PlayStation.Core.Input;
using Sce.PlayStation.Core.Imaging;
using Sce.PlayStation.HighLevel.UI;
namespace mojitest
{
public class AppMain
{
private static GraphicsContext graphics;
static Scene scene;
static ImageBox imagebox;
static Image image;
static Texture2D texture2d;
public static void Main (string[] args)
{
Initialize ();
while (true) {
SystemEvents.CheckEvents ();
Update ();
Render ();
}
}
public static void Initialize ()
{
// Set up the graphics system
graphics = new GraphicsContext ();
UISystem.Initialize(graphics);
scene = new Scene();
UISystem.SetScene(scene);
image = new Image(ImageMode.Rgba,new ImageSize(960,60),
new ImageColor (255,0,0,0));
image.DrawText("テキスト文字列です",
new ImageColor(255,255,255,255),
new Font(FontAlias.System,60,FontStyle.Regular),
new ImagePosition(0,0));
texture2d = new Texture2D(960,60,false,PixelFormat.Rgba);
texture2d.SetPixels(0,image.ToBuffer());
image.Dispose();
imagebox = new ImageBox();
imagebox.Image = new ImageAsset(texture2d);
texture2d.Dispose();
imagebox.X = 0;
imagebox.Y = 0;
imagebox.Width = 960;
imagebox.Height= 60;
imagebox.Alpha = 1.0f;
imagebox.Visible = true;
scene.RootWidget.AddChildLast (imagebox);
}
public static void Update ()
{
// Query gamepad for current state
var gamePadData = GamePad.GetData (0);
List touchData = Touch.GetData(0);
UISystem.Update(touchData);
}
public static void Render ()
{
// Clear the screen
graphics.SetClearColor (0.0f, 0.0f, 0.0f, 0.0f);
graphics.Clear ();
UISystem.Render();
// Present the screen
graphics.SwapBuffers ();
}
}
}
解説:
画像を表示するためにImageBoxを用意します。ImageBoxのイメージImageBox.Imageを作成するためにImageとそのImageを作成するためにTexture2dを用意します。
DrawTextと書くとImageにテキストを画像として作成します。Texture2dはImageBoxのImageを作る際のImageAssetを作るために作成します。
(イメージ図(Imageだけに・・・))
Image
↓
Image ← DrawText
↓
ImageBox ← Texture2d ← Image
いらない画像はDisposeしないと後でメモリ不足になって停止しちゃうので、Texture2dを作ったらimage.Dispose()と書いてImageはディスポーズします。
ImageBoxを作ったらtexture2d.Dispose()と書いて不要になったTexture2dをディスポーズします。
長所:Labelより速いし、そんなに難しくない。
短所:拡大縮小はできても、回転ができない。
次回、回転するためにSce.PlayStation.HighLevel.GameEngine2Dでの文字の表示の方法と、そもそもHighLevel なのを使うとかなり起動が遅くなるし、画像をAssetするだけのためにしか使ってないんだから、HighLevelなのを使わない書きかたの記事を書きます。現状のだと文字を表示するためだけに300行ほど使っている(どうしてこうなった?)ので、もう少しまとめたものを準備します。
次回へ続きます。