XNA将SpriteBatch和Content作为参考传递

时间:2012-06-15 10:17:50

标签: c# xna xna-4.0 spritebatch

最近我开始在MonoMac上使用XNA。 我有课的问题。 我想在里面创建一个带有纹理和位置信息的类。我也想制作绘画功能。

我的想法是传递spriteBatch和Content arround所以我可以加载纹理并在之后绘制它们。但是,传入此对象的Content对象不会加载任何纹理,当我在类外部尝试Content时,它会加载纹理,因此纹理必须存在。

    public class TPlayer {
        public Texture2D[] textures;
        public ContentManager Content;
        public SpriteBatch spriteBatch;
        public int currentFrame;
        public Rectangle position;
        public TPlayer(ContentManager ccontent, SpriteBatch cspritebatch){
            this.Content = ccontent;
            this.spriteBatch = cspritebatch;
            this.Content.RootDirectory = "Content";
            this.currentFrame = 0;
            this.position = new Rectangle(250,20,100,150);
            this.LoadContent();
        }

        protected void LoadContent(){
            this.textures[0] = this.Content.Load<Texture2D>("Textures/ToughStanding");
            this.textures[1] = this.Content.Load<Texture2D>("Textures/ToughWalking1");
            this.textures[2] = this.Content.Load<Texture2D>("Textures/ToughWalking2");
        }

        public void Draw(){
            spriteBatch.Begin (SpriteSortMode.Deferred, BlendState.AlphaBlend);
            this.spriteBatch.Draw (textures[0], this.position, Color.White);
            this.spriteBatch.End ();
        }

这是我创建实例的方式:

Player = new TPlayer(this.Content,this.spriteBatch);

也许我试图使用错误的模型..也许我不想在类中使用spritebatch和Content,但是我可以将spritebatch和内容全局化吗?

感谢您的帮助

1 个答案:

答案 0 :(得分:2)

因为你已经解决了自己的问题(干得好!)我将使用这个空间来建议一个稍微少一点的资源密集型方法来绘制你的精灵帧,这也可以解决你的问题,而不是使用单独的纹理每个动画帧都可以将它们组合成一个单一的纹理。交换纹理实际上是一个相对较慢的操作。

所以不是3个纹理代替Standing,Walking1,Walking2并使用当前框架属性在它们之间切换,你可以创建一个大的纹理来容纳所有3个,这可以通过简单地创建一个空白来完成绘画或任何绘图包拍摄所有3帧的大小并将其复制/粘贴到位(注意每个帧的开始/结束位置)

enter image description here

您可以创建一个矩形数组来保存工作表中每个精灵的位置。

spriteSheetRegions = new Rectangle[]
{
    new Rectangle (0,0, 50,50),     // standing.
    new Rectangle (50,0, 100, 50),  // tough walking 1
    new Rectangle (100,0, 150, 50), // tough walking 2
};

然后要为精灵设置动画,只需跟踪哪个矩形是当前帧。

我在下面添加了一个快速游戏类,它显示了整个操作如何与精灵和玩家类一起工作,精灵类可以成为所有精灵的基础而不仅仅是玩家。

#region Using Directives.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
#endregion

namespace sprites
{
    public class Sprite
    {
        // Texture instances.
        public Texture2D spriteSheet;
        protected Rectangle[] spriteSheetRegions;
        protected Rectangle currentSpriteSheetRegion;

        // player instances.
        public Rectangle location;

        // call this to change the image that's drawn for the sprite.
        public void SetSpriteSheetIndex(int index)
        {
            currentSpriteSheetRegion = spriteSheetRegions[index];
        }
    }

    public class TPlayer : Sprite
    {
        public TPlayer()
        {
            // Since your sprite sheets for the player are fixed we can set them up here.
            spriteSheetRegions = new Rectangle[]
            {
                new Rectangle (0,0, 50,50),     // standing.
                new Rectangle (50,0, 100, 50),  // tough walking 1
                new Rectangle (100,0, 150, 50), // tough walking 2
            };
            currentSpriteSheetRegion = spriteSheetRegions[0];
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(spriteSheet, location, currentSpriteSheetRegion, Color.White);
        }
    }

    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        List<TPlayer> players;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            // Create the players and add 3 of them.
            players = new List<TPlayer>();
            players.Add(new TPlayer() { location = new Rectangle(10, 10, 100, 100) });
            players.Add(new TPlayer() { location = new Rectangle(110, 10, 100, 100) });
            players.Add(new TPlayer() { location = new Rectangle(220, 10, 100, 100) });

            base.Initialize();
        }

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // Load up the players content.
            Texture2D playerSpriteSheet = Content.Load<Texture2D>("PlayerSpriteSheet");

            // each player gets a reference to the same texture so there is no duplication.
            for (int i = 0; i < players.Count; i++)
                players[i].spriteSheet = playerSpriteSheet;
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // draw the players.
            spriteBatch.Begin();
            for (int i = 0; i < players.Count; i++)
                players[i].Draw(spriteBatch);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

如果要更改播放器的当前帧,请调用SetSpriteSheetIndex。

如果你想将玩家零的图片设置为你想要的艰难步行1帧。

players[0].SetSpriteSheetIndex(1);