2012-06-15 2 views
0

Недавно я начал использовать XNA с MonoMac. У меня проблема с классами. Я хочу создать класс с текстурами и информацией о местоположении внутри. Также я хотел бы сделать функцию рисования.XNA pass SpriteBatch и Content в качестве ссылки

Моя идея состояла в том, чтобы передать 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); 

Может быть, Im пытается использовать неправильную модель .. Может быть, я не должен хотеть использовать SpriteBatch и содержание внутри класса, но чем я могу сделать SpriteBatch и контент глобальный?

Спасибо за вашу помощь

+0

Какова ценность Content.RootDirectory, прежде чем он войдет в ваш конструктор TPlayer? внутри конструктора вы устанавливаете значение, вы уверены, что вам нужно это сделать? – Andy

+0

Также как подсказка (не связанная с вашей проблемой) Я предполагаю, что у вас есть петля, которая рисует игроков, вызывает spritebatch.begin и заканчивает любую сторону этого цикла, а не в каждом методе ничьей, вы ускорите процесс немного. – Andy

+0

Нет, я думаю, мне не нужно это делать. Ранее он был настроен на «Контент». Я просто пытался угадать, где может быть проблема, поэтому я тоже это пробовал. Спасибо за совет спрайтов ... Я буду называть Begin и End только один раз с этого момента. – Simon

ответ

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); 
+0

спасибо ... я сделаю это с вашего пути. – Simon

Смежные вопросы