PlayStation Mobile SDK でプログラミング(15) | PSMでいこう

PSMでいこう

PlayStation Mobile(PlayStation Suite)のプログラムを作るブログです。

雨天延期しまくったやつの末路
PSMでいこう
取り付けに行かないとならないエアコンに埋もれている山田です。こんばんは。

ツイッターのDMでリクエストがあったので、今回は文字表示のプログラムのお話です。おまたせしました。

第4回 の時にも少し書きましたが、PSMの文字列の表示は、みんなが悩むポイントみたいです。山田もいまだにです。

PSMで文字列の表示の方法はいくつかあって、人それぞれでベストな方法はわかりませんので、いろいろ試してください。

(0)準備編
今回のプログラムは
Sce.PlayStation.Core.Imaging
Sce.PlayStation.HighLevel.UI
を使いますので、Using文に追加して下さい。
HiglLevel.UIはソリューションウィンドウの”参照”をダブルクリックして出てきたウィンドウに中のSce.PlayStation.HighLevel.UIのところをチェックを入れて下さい。
PSMでいこう
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行ほど使っている(どうしてこうなった?)ので、もう少しまとめたものを準備します。

次回へ続きます。