• 使用 Label 类在 XNA 中显示文本,WPXNA(七)


    平方已经开发了一些 Windows Phone 上的一些游戏,算不上什么技术大牛。在这里分享一下经验,仅为了和各位朋友交流经验。平方会逐步将自己编写的类上传到托管项目中,没有什么好名字,就叫 WPXNA 吧,最后请高手绕道而行吧,以免浪费时间。(为了突出重点和减少篇幅,有些示例代码可能不够严谨。)

    标签

    在游戏中,我们需要向用户显示一些文字信息,比如:玩家的名字,分数等。这时候,可以使用 Label 类。Label 类继承自 Making,所以他是一个元件。以下是 Label 中的部分字段和属性:

    private float blink;
    internal float Alpha = 1;
    internal readonly float Rotation;
    
    internal string Text;
    internal float FontScale;
    protected SpriteFont font;
    protected Color color;
    
    protected Vector2 location;
    public Vector2 Location
    {
        get { return this.location; }
        set { this.location = value; }
    }

    字段 Alpha 表示标签的透明度,1 表示不透明,0 表示完全透明。字段 blink 的值应该在 -1 到 0 之间,如果 blink 不为 0,则标签会闪烁。

    字段 Rotation 表示标签的旋转角度,属性 Location 表示标签的位置。

    字段 Text 表示标签的文本,字段 FontScale 表示文本的缩放比例,字段 font 表示文本的字体,字段 color 表示文本的颜色。

    internal Label ( string name, string resourceName, string text, Vector2 location, int width, int height, float fontScale, Color color, float blink, float alpha, int angle )
        : base ( name, resourceName )
    {
    
        if ( null == text )
            throw new ArgumentNullException ( "text", "text can't be null" );
    
        if ( width > 0 )
            this.Width = width;
    
        if ( height > 0 )
            this.Height = height;
    
        this.Text = text;
        this.location = location;
        this.FontScale = fontScale <= 0 ? 1 : fontScale;
        this.color = color;
        this.blink = blink;
        this.Alpha = alpha < 0 || alpha > 1 ? 1 : alpha;
        this.Rotation = Calculator.Radian ( angle );
    }

    在 Label 的构造函数中,除了上面提到的字段,参数 name 表示元件的名称,参数 resourceName 表示标签使用的字体资源,参数 width 和 height 为标签的大小,可以忽略。你可以调用方法 InitSize 来获取标签的大小。

    internal static void InitSize ( Label label, bool isForce )
    {
    
        if ( null == label )
            return;
    
        if ( label.Width == 0 || isForce )
            label.Width = ( int ) ( label.font.MeasureString ( label.Text ).X * label.FontScale );
    
        if ( label.Height == 0 || isForce )
            label.Height = ( int ) ( label.font.LineSpacing * label.FontScale );
    
    }

    你可以通过 Draw 方法来绘制标签。

    internal static void Draw ( Label label, SpriteBatch batch )
    {
    
        if ( !label.isVisible )
            return;
    
        Color color = label.color;
    
        if ( label.blink != 0 )
        {
            label.Alpha += label.blink;
    
            if ( label.Alpha <= 0.5 || label.Alpha >= 1 )
                label.blink = -label.blink;
    
        }
    
        if ( label.Alpha != 1 )
            color = color * label.Alpha;
    
        batch.DrawString ( label.font, label.Text, label.location * World.Scale, color, label.Rotation, Vector2.Zero, label.FontScale * ( label.Rotation == 0 ? World.Scale : World.FlipScale ), SpriteEffects.None, 0 );
    }

    在 Draw 方法中,我们将根据字段 blink 来不断的调整 Alpha 字段,也就是标签的透明度,这样标签的透明度将在 0.5 和 1 之间改变。

    一个简单的例子

    首先,我们需要使用 ResourceManager 来管理资源,另外,我们定义了两个标签。

    private readonly ResourceManager resourceManager;
    private readonly Label label1;
    private readonly Label label2;

    在构造函数中,我们初始化了 ResourceManager 和 Label,ResourceManager 将包含一个字体资源,他包含在资源项目的 font 目录中,字体资源被命名为 peg。

    之后,我们创建了两个标签。第一个标签是浅绿色,字体缩放大小为 2 倍,第二个标签是垂直的,并且可以闪烁。

    public World ( Color backgroundColor )
        : base ( )
    {
        // ...
    
        this.resourceManager = new ResourceManager ( new Resource[] {
            new Resource ( "peg", ResourceType.Font, @"font\myfont" )
        } );
        this.resourceManager.World = this;
    
        this.label1 = new Label ( "l1", "Hello windows phone!", 2f, Color.LightGreen, 0f );
        this.label2 = new Label ( "l2", "peg", "Nothing!", new Vector2 ( 50, 300 ), 0, 0, 1f, Color.White, -0.01f, 1f, -90 );
    }

    当页面载入之后,我们加载所需要的资源。

    protected override void OnNavigatedTo ( NavigationEventArgs e )
    {
        // ...
    
        this.resourceManager.LoadContent ( );
        this.label1.InitResource ( this.resourceManager );
        this.label2.InitResource ( this.resourceManager );
    
        base.OnNavigatedTo ( e );
    }

    在 OnUpdate 方法中,我们让第二个标签显示游戏进行的时间。

    private void OnUpdate ( object sender, GameTimerEventArgs e )
    {
        this.label2.Text = e.TotalTime.ToString ( );
    }

    在 OnDraw 中,我们通过 Label 的 Draw 方法绘制了两个标签。

    private void OnDraw ( object sender, GameTimerEventArgs e )
    {
        // ...
    
        this.spiritBatch.Begin ( );
        Label.Draw ( this.label1, this.spiritBatch );
        Label.Draw ( this.label2, this.spiritBatch );
        this.spiritBatch.End ( );
    }

    本期视频 http://v.youku.com/v_show/id_XNTY3MzA2MTk2.html
    项目地址 http://wp-xna.googlecode.com/

    更多内容 WPXNA
    平方开发的游戏 http://zoyobar.lofter.com/
    QQ 群 213685539

    欢迎访问我在其他位置发布的同一文章:http://www.wpgame.info/post/decc4_68994c

  • 相关阅读:
    idea炫酷主题下载网站
    You have not concluded your merge (MERGE_HEAD exists)
    内部接口
    Nginx初尝试
    泛型和反射
    使用idea创建web项目
    <转>如果你报createSQLQuery is not valid without active transaction,请看这里
    android 通过pull解析xml文件
    shiro环境搭建
    springmvc文件上传
  • 原文地址:https://www.cnblogs.com/zoyobar/p/wpxna7.html
Copyright © 2020-2023  润新知