0

最近我开始将 XNA 与 MonoMac 一起使用。我上课有问题。我想创建一个里面有纹理和位置信息的类。我也想做绘图功能。

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

    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 和 content 全局化吗?

感谢您的帮助

4

1 回答 1

2

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

所以代替站立,行走1,行走2的3个纹理并使用当前帧属性在它们之间切换,您可以创建一个大纹理来容纳所有3个,这可以通过简单地创建一个大小为大小的空白图像在绘画或任何绘图包中完成所有 3 帧并将它们复制/粘贴到位(记下每个帧的开始/结束位置)

在此处输入图像描述

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

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);
于 2012-06-15T11:01:33.227 回答