C# XNA通过SpriteBatch和内容作为参考
最近我开始在MonoMac中使用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
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);