C# XNA通过SpriteBatch和内容作为参考

C# XNA通过SpriteBatch和内容作为参考,c#,xna,xna-4.0,spritebatch,C#,Xna,Xna 4.0,Spritebatch,最近我开始在MonoMac中使用XNA。 我上课有问题。 我想创建一个包含纹理和位置信息的类。我还想做绘图功能 我的想法是将spriteBatch和内容四处传递,这样我就可以加载纹理并在之后绘制它们。然而,我传递给这个对象的内容对象没有加载任何纹理,当我尝试类外的内容时,它加载的纹理很好,所以纹理必须存在 public class TPlayer { public Texture2D[] textures; public ContentManager Co

最近我开始在MonoMac中使用XNA。 我上课有问题。 我想创建一个包含纹理和位置信息的类。我还想做绘图功能

我的想法是将spriteBatch和内容四处传递,这样我就可以加载纹理并在之后绘制它们。然而,我传递给这个对象的内容对象没有加载任何纹理,当我尝试类外的内容时,它加载的纹理很好,所以纹理必须存在

    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 ();
        }
也许我试着用错了型号。。也许我不想在类内使用spritebatch和内容,但这样我就可以使spritebatch和内容全球化吗


感谢您的帮助

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

因此,您可以创建一个大纹理来容纳所有3个,而不是3个用于站立、行走1、行走2的纹理,并使用“当前帧”属性在它们之间进行切换。只需创建一个与所有3个帧大小相同的空白图像并将其复制/粘贴到位,即可在paint或任何绘图包中完成此操作(注意每一个的开始/结束位置)

您可以创建一个矩形阵列来保存每个精灵在图纸中的位置

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);
        }
    }
}

Content.RootDirectory在进入TPlayer构造函数之前的值是多少?在构造函数中您正在设置值,您确定需要这样做吗?也作为提示(与您的问题无关)我猜你有一个吸引玩家的循环,叫做spritebatch。在循环的任意一边开始和结束,而不是在每个绘制方法中,你会大大加快速度。不,我想我不需要这样做。它被设置为“内容”以前。我只是想猜测哪里会有问题,所以我也试过了。谢谢你的spritebatch建议…从现在起我将只调用一次Begin和End。我通过只将纹理传递给对象,而不是像这里一样将spritebatch传递给draw函数来解决问题:很抱歉给你添麻烦
#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);
        }
    }
}
players[0].SetSpriteSheetIndex(1);