近期发布
专辑列表

Windows Phone 游戏合集
JQueryElement
IEBrowser
WPXNA

使用元件类 Shape 在 XNA 中显示缩放图形,WPXNA(三)(带视频)

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

元件

游戏中有些元素并不适合作为精灵,所以平方将这些元素归入元件,比如:按钮和标签。而这里我们首先建立了一个基类 Making:

internal abstract class Making
    : IDisposable
{
    protected readonly string resourceName;
    internal readonly string Name;

    protected bool isVisible = true;
    internal virtual bool IsVisible
    {
        get { return this.isVisible; }
        set { this.isVisible = value; }
    }

    protected Making ( string name, string resourceName )
    {
        this.Name = name;
        this.resourceName = resourceName;
    }

    internal virtual void InitResource ( ResourceManager resourceManager )
    { }

    public virtual void Dispose ( )
    { }

}

我们定义了字段 resourceName 和 Name,分别表示元件所用的资源名称和元件自身的名称。其中资源名称也就是 Resource 结构的 Name 字段。比如:如果元件使用了一张图片,则就需要关联图片的资源名称。而 Name 表示元件名称,必须是唯一的。

Making 的 IsVisible 属性用来控制是否显示元件,你可以在派生类中访问这个属性来决定是否显示。

InitResource 方法用来从 ResourceManager 获取所需要的资源,这里需要由派生类来决定载入哪些资源。

Making 类还实现了 IDisposable 接口,用来释放不需要的内容,但你并不需要释放从 ResourceManager 获取的资源,因为这些资源应该由 ResourceManager 管理。

图形

我们从 Making 类派生了 Shape 类,用来在屏幕上显示一个图形,这是一个简单的类,但是之后我们还会创建更复杂的电影类。

internal class Shape
    : Making
{

    internal static void Draw ( Shape shape, GameTime time, SpriteBatch batch )
    {

        if ( !shape.isVisible )
            return;

        batch.Draw ( shape.Texture, shape.location * World.Scale, null, Color.White, 0, Vector2.Zero, World.TextureScale, SpriteEffects.None, shape.order );
    }

    internal Texture2D Texture;

    protected Vector2 location;
    public virtual Vector2 Location
    {
        get { return this.location; }
        set { this.location = value; }
    }

    protected readonly float order;

    // ...
    internal Shape ( string name, string resourceName, Vector2 location, float order )
        : base ( name, resourceName )
    {
        this.location = location;
        this.order = order;
    }

    internal override void InitResource ( ResourceManager resourceManager )
    { this.Texture = resourceManager.GetTexture ( this.resourceName ); }

}

Shape 类包含一个 Texture2D 类型的字段,他就是我们需要绘制的图形,这个字段将在 InitResource 方法中得到初始化,我们从 ResourceManager 获取图形资源。

Location 属性表示图形的位置,你可以在任何时候修改图形的位置。而 order 字段是一个保留字段,暂时没有效果。

使用静态方法 Draw 来完成最后的绘制任务,我们还根据元件的 isVisible 字段来确定是否显示图形。注意,在 Draw 方法中的 Scale 和 TextureScale 字段,他们属于 World 类,分别表示整个游戏的比例和图像的缩放比例。

显示图形

最后,我们来显示图形,首先定义 ResourceManager 和 Shape,并初始化他们。

private readonly ResourceManager resourceManager;
private readonly Shape birdShape;

public World ( Color backgroundColor )
    : base ( )
{
    // ...

    this.resourceManager = new ResourceManager ( new Resource[] {
        new Resource ( "bird", ResourceType.Image, @"image\bird" )
    } );
    this.resourceManager.World = this;

    this.birdShape = new Shape ( "shape.bird", "bird", new Vector2 ( 50, 50 ) );
}

我们使用 ResourceManager 定义我们需要的资源,虽然没有使用 LoadContent 方法载入资源,但是你还是可以创建任何元件,这里我们创建了一个关于小鸟的 Shape 类。

protected override void OnNavigatedTo ( NavigationEventArgs e )
{
    // ...

    this.resourceManager.LoadContent ( );
    this.birdShape.InitResource ( this.resourceManager );

    base.OnNavigatedTo ( e );
}

当我们调用了 LoadContent 方法之后,我们需要使用 InitResource 方法让 Shape 类从 ResourceManager 获取他所需要的图像资源,否则绘制将出现错误。

private void OnDraw ( object sender, GameTimerEventArgs e )
{
    this.GraphicsDevice.Clear ( this.BackgroundColor );

    this.spiritBatch.Begin ( );
    Shape.Draw ( this.birdShape, new GameTime ( e.TotalTime, e.ElapsedTime ), this.spiritBatch );
    this.spiritBatch.End ( );
}

最后,我们使用 Shape 的静态方法 Draw 来绘制图形,其中的第二个参数可以设置为 null,因为这里我们不需要他。需要注意的是,你仍然需要调用 SpriteBatch 类的 Begin 和 End 方法。

缩放和移动

通过设置 World 的 TextureScale 和 Scale 字段,可以控制游戏的比例和图像的缩放比例,同时修改他们就可以将游戏调整为何时的大小。在下面的代码中,我将游戏大小减少一半。

public partial class World
    : PhoneApplicationPage
{

    internal static float TextureXScale = 1;
    internal static float TextureYScale = 1;
    internal static Vector2 TextureScale = new Vector2 ( TextureXScale, TextureYScale );

    internal static float XScale = 1;
    internal static float YScale = 1;
    internal static Vector2 Scale = new Vector2 ( XScale, YScale );
    internal static Vector2 FlipScale = new Vector2 ( YScale, XScale );
    
    public World ( Color backgroundColor )
        : base ( )
    {
        // ...

        TextureXScale = 0.5f;
        TextureYScale = 0.5f;
        TextureScale = new Vector2 ( TextureXScale, TextureYScale );

        XScale = 0.5f;
        YScale = 0.5f;
        Scale = new Vector2 ( XScale, YScale );
        FlipScale = new Vector2 ( YScale, XScale );
    }

}

修改 Shape 类的 Location 属性,就可以实现图形的移动。

private void OnUpdate ( object sender, GameTimerEventArgs e )
{
    this.birdShape.Location += new Vector2 ( 1f, 1f );
}

在这里,由于我们调整了 Scale,所以在屏幕上小鸟不会移动 1 个像素,而是 0.5 像素。

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

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

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

posted @ 2013-05-24 18:32  麦丝平方  阅读(965)  评论(0编辑  收藏  举报