现在的位置: 首页 > 专题 > 机器人 > Robotics Studio > 设计中心 > 文档 > 专题 > 机器人 > 正文

Robotics Studio学习教程:第二十七天——在VSE中使用CameraSprite

2014年05月15日 Robotics Studio, 文档, 机器人 ⁄ 转载:原文链接 ⁄ 共 4563字 ⁄ 字号 暂无评论 ⁄ 阅读 1,092 次

 

Robotics Studio学习教程

Robotics Studio学习教程

继之前分享的一篇《Robotics Studio学习教程:第二十六天——让我们在迷宫中加入机器人!》, 我们将继续分享下一篇《Robotics Studio学习教程:第二十七天——在VSE中使用CameraSprite》,让我继续开始我们学习Visual Programming Language,以及使用Robotics Studio学习开发机器人应用的道路吧。

 

[Robotics Studio] CameraSprite in VSE -- Day27

因为迷宫太难了, 先来学其他比较简单的东西 - -

话说 Day21 的时候为了看到机器人的 Camera, 费尽辛苦写了一个窗口, 还要写一些 code 用来连接 虚拟 Camera 送来的讯息以及将数据转成 Image 等等...

但是有了 CameraSprite 就变成好简单...

只要在 虚拟的 Camera Entity 加上一个 CameraSprite (一定要是 Camera Entity 的子对象),
透过 VSE 你就可以在该 Camera 的某个相对位置上看到 Camera 的画面.

就拿相扑机器人的 SumoCompetition 项目来作范例吧,

首先打开该范例, 切到 SimulatedSumoReferee 项目的 SimulatedSumoReferee.cs, 找到 EntityManager.CreateRobot 函式, 在产生出 Camera Entity 的时候, 生出一个 CameraSprite 在该 Camera 上方 1 公尺处, 大小为 50x50 cm, 如下面的四行  code:

  1. // Add a camera
  2. CameraEntity sumoCam = new CameraEntity(176, 144, (float)(27.0 * Math.PI / 180.0), CameraEntity.CameraModelType.AttachedChild); // 20 degree FOV
  3. sumoCam.State.Name = newRobot.State.Name + "/SumoCam";
  4. sumoCam.State.Pose.Position = new Vector3(0, 0.17f, 0.005f);
  5. sumoCam.Rotation = new xna.Vector3(-8.0f, 0, 0);
  6. sumoCam.State.Assets.Mesh = "WebCam.obj";
  7. sumoCam.IsRealTimeCamera = true;
  8. sumoCam.UpdateInterval = 350;   // update less then 3 times per second
  9. //把 CameraSprite 加到 Camera Entity 的子物件當中
  10. CameraSprite camSprite = new CameraSprite(0.5f, 0.5f, SpritePivotType.Center, 0, new Vector3(0, 1, 0));
  11. camSprite.State.Name = newRobot.State.Name + "/camSprite";
  12. camSprite.Flags |= VisualEntityProperties.DisableBackfaceCulling;
  13. sumoCam.InsertEntity(camSprite);
  14. newRobot.InsertEntity(sumoCam);

 

恩, 就这样, 双方的机器人上面都有一个摄影机的画面啦!

clip_image002

决斗过程也都可以看到...

clip_image004

clip_image006

这么简单就混过一天, 可能会被骂的, 所以我再补一点关于 SpriteEntity 的东西好了,

CameraSprite 是继承自 SpriteEntity 的, 如果我们要自己做一个简单的 SpriteEntity, 可以直接用  SpriteEntity, 或继承一个.

假设我们要作一个  TextSprite (我很奇怪为什么微软不帮我们做一个这样的? 反而做 EntityNameSprite ,只会显示 parent 对象的名称?! 这么狭隘的 class?!)

code 如下 :

  1. public class TextSprite : SpriteEntity
  2. {
  3.     private string _fontFamily;
  4.     private float _fontSize;
  5.     private string _text;
  6.     /// <summary>
  7.     /// The font family name of the font to use
  8.     /// </summary>
  9.     [DataMember]
  10.     public string FontFamily
  11.     {
  12.         get { return _fontFamily; }
  13.         set { _fontFamily = value; }
  14.     }
  15.     /// <summary>
  16.     /// The font size of the font to use
  17.     /// </summary>
  18.     [DataMember]
  19.     public float FontSize
  20.     {
  21.         get { return _fontSize; }
  22.         set { _fontSize = value; }
  23.     }
  24.     /// <summary>
  25.     /// Default constructor
  26.     /// </summary>
  27.     public TextSprite() { }
  28.     /// <summary>
  29.     /// Initialization constructor
  30.     /// </summary>
  31.     /// <param name="width"></param>
  32.     /// <param name="height"></param>
  33.     /// <param name="textureWidth"></param>
  34.     /// <param name="textureHeight"></param>
  35.     /// <param name="pivot"></param>
  36.     /// <param name="initialPos"></param>
  37.     /// <param name="family"></param>
  38.     /// <param name="fontSize"></param>
  39.     public TextSprite(string text, float width, float height,
  40.                   int textureWidth, int textureHeight,
  41.                   SpritePivotType pivot, Vector3 initialPos,
  42.                   string family, float fontSize)
  43.         : base(width, height, textureWidth, textureHeight, pivot, initialPos)
  44.     {
  45.         _text = text;
  46.         _fontFamily = family;
  47.         _fontSize = fontSize;
  48.     }
  49.     /// <summary>
  50.     /// Initialize
  51.     /// </summary>
  52.     /// <param name="device"></param>
  53.     /// <param name="physicsEngine"></param>
  54.     public override void Initialize(Microsoft.Xna.Framework.Graphics.GraphicsDevice device,
  55.          PhysicsEngine physicsEngine)
  56.     {
  57.         try
  58.         {
  59.             InitError = string.Empty;
  60.             Font nameFont = new Font(_fontFamily, _fontSize);
  61.             base.Initialize(device, physicsEngine);
  62.             Bitmap target = GetBitmap();
  63.             Graphics g = Graphics.FromImage(target);
  64.             g.FillRectangle(Brushes.DarkBlue, 0, 0, target.Width, target.Height);
  65.             StringFormat nameFormat = new StringFormat();
  66.             nameFormat.Alignment = StringAlignment.Center;
  67.             nameFormat.LineAlignment = StringAlignment.Center;
  68.             g.DrawString(_text, nameFont, Brushes.White,
  69.                    new Rectangle(0, 0, target.Width, target.Height),
  70.                    nameFormat);
  71.             SetBitmap(target);
  72.         }
  73.         catch (Exception ex)
  74.         {
  75.             HasBeenInitialized = false;
  76.             InitError = ex.ToString();
  77.         }
  78.     }
  79. }

 

这样我们就可以在 VSE 当中产生一片文字 (就像魔兽的人物上面都会挂一块名牌)

透过在刚刚的 Add CameraSprite 之后再加上:

  1. //加上 TextSprite
  2. TextSprite txtSprite = new TextSprite("Hello! I am "+newRobot.State.Name, 0.5f, 0.0625f, 512, 64, SpritePivotType.Center, new Vector3(0, 0.25f, 0), "Courier", 14);
  3. txtSprite.State.Name = newRobot.State.Name + "/txtSprite";
  4. newRobot.InsertEntity(txtSprite);

 

clip_image008

 

这个 TextSprite 比原本的 EntityNameSprite 好用多了, 不但可以显示任何字 (要考虑字型), 还可以不限定要加在某个 Entity 当中 (直接加到 VSE).

(因为原本的  EntityNameSprite 一定要挂在某个 Entity 下面, 用来显示该 Entity 的名称)

 

让我们继续一下章教程:

《Robotics Studio学习教程:第二十八天——Pursuit Camera!》

fgx

分享到:

Wopus问答

×