![](/img/trans.png)
[英]How to use DrawableGameComponent in Silverlight + XNA?
[英]XNA: Basic DrawableGameComponent override functions (Update, Draw, etc) not being called
我試圖通過讓他們擴展Mircosoft.Xna.Framework.GameCompenent來封裝我的游戲對象,然后僅構建它們並在Game1的Update()方法中管理它們。 我有我的Game1類,Player類和Animation類。 假設動畫管理對象的Texture2D更改,在此實例中為Player。
我的問題是,即使我已經成功擴展了所有內容,沒有語法錯誤,沒有拋出異常,並且已經檢查並重新檢查了我編寫的代碼,否則不會調用覆蓋函數,最終會出現黑屏。
Game1.cs :(注意改變的只有兩行是Player聲明)
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Player player;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
player = new Player(this);
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
base.Draw(gameTime);
}
}
Player.cs:
class Player : Microsoft.Xna.Framework.DrawableGameComponent
{
Rectangle bounds;
Texture2D t;
Animation[] animations = new Animation[4];
String path = @"..\..\..\Content\player.png";
#region Animation Constants
private const int WALK_RIGHT = 0;
#endregion
SpriteBatch spriteBatch;
public Player(Game game) : base(game)
{
//should only ever be one player, all value defaults set in Initialize()
}
public Texture2D T
{
get { return t; }
}
public Rectangle Bounds
{
get { return bounds; }
}
public override void Initialize()
{
base.Initialize();
bounds = new Rectangle(0, 0,
System.Drawing.Image.FromFile(path).Width,
System.Drawing.Image.FromFile(path).Height
);
t = Game.Content.Load<Texture2D>("player");
animations[0] = new Animation(this.Game, "player", "walking", 3);
}
protected override void LoadContent()
{
base.LoadContent();
spriteBatch = new SpriteBatch(this.Game.GraphicsDevice);
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
KeyboardState k = Keyboard.GetState();
if (k.IsKeyDown(Keys.Right)) //walk right
{
bounds.X += 3;
if (animations[WALK_RIGHT].Playing)
{
t = animations[WALK_RIGHT].getTexture();
}
else
{
animations[WALK_RIGHT].Play();
}
}
else if (animations[WALK_RIGHT].Playing)
animations[WALK_RIGHT].Stop();
}
public override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
spriteBatch.Begin();
spriteBatch.Draw(t, bounds, Color.White);
spriteBatch.End();
}
}
Animation.cs:
class Animation : Microsoft.Xna.Framework.GameComponent
{
Game game;
String name; //name of default sprite; standing, unmoving, neutral, etc. The rest of the animation sprite names should derive from this
String keyword;
int frameCount;
int delay; //frames between texture change
String[] paths; //texture pathnames generated by the MakePaths() function
int currentFrame = 0;
int delayCount = 0;
bool playing = false;
public Animation(Game associatedGame, String nameVal, String keywordVal, int frameCountVal)
: base(associatedGame)
{
name = nameVal;
keyword = keywordVal;
frameCount = frameCountVal;
paths = MakePaths();
delay = 10;
}
public Animation(Game associatedGame, String nameVal, String keywordVal, int frameCountVal, int delayVal)
: base(associatedGame)
{
name = nameVal;
keyword = keywordVal;
frameCount = frameCountVal;
paths = MakePaths();
delay = delayVal;
}
private String[] MakePaths()
{
//format: name_keyword_anim[i]
//format example: player_walking_anim1
String[] temp = new String[frameCount];
for (int i = 0; i < frameCount; i++)
{
temp[i] = name + "_" + keyword + "_" + "anim" + i.ToString();
}
return temp;
}
public Texture2D getTexture()
{
return Game.Content.Load<Texture2D>(paths[currentFrame]);
}
public void Play()
{
playing = true;
}
public void Stop()
{
currentFrame = 0;
delayCount = 0;
playing = false;
}
public bool Playing
{
get { return playing; }
}
public override void Update(GameTime gameTime)
{
if (playing)
{
if (delayCount == delay)
{
delayCount = 0;
if ((currentFrame + 1) == frameCount) currentFrame = 0;
else currentFrame++;
}
else delayCount++;
}
base.Update(gameTime);
}
public override string ToString()
{
return "params: " + name + "," + keyword + "," + frameCount.ToString() + "\nUsing paths: " + paths;
}
}
調用的唯一LoadContent,Initialize,Update和Draw方法是Game1中的方法。 讓我感到困惑的是,我之前能夠毫無問題地使用這種技術。 這些函數將由Xna更新過程自然調用。
那么......這是為什么?
您需要將游戲組件添加到組件集合中以自動調用它們
protected override void Initialize()
{
player = new Player(this);
Components.Add(player);
base.Initialize();
}
請參閱http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.game.components.aspx
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.