[英]Difficulty loading a texture and passing it to a class in XNA 4.0
這是ac#/ XNA 4.0類的作業,不,我不是HWgrade-zombie。 我會讓您知道我提出這個問題的情況,完成的“研究”的數量,以及我希望學習而不是獲得成績的方法,但是它被認為是虛假的並且被刪除了。
無論如何,我遇到的問題是我試圖加載到Game1.cs中的“ textureImage”中的內容(子畫面表),然后通過“ userControlledSprite”傳遞給“ Sprite.cs”進行繪制.cs”,在編譯程序時不會被繪制。 我是C#和XNA的新手,我理解這個問題(內容已加載,但未正確傳遞),但是我迷失了解決方法。
這是我的程序組成的完整的三個類:
Game1.cs-調用userControlledSprite。
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;
namespace Proj06
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
static Texture2D textureImage;
static Point frameSize = new Point(52,50);
static Point currentFrame = new Point(0, 0);
static Point sheetSize = new Point(4, 1);
static Vector2 position = Vector2.Zero;
static int collisionOffset = 1;
static Vector2 speed;
userControlledSprite UserControlledSprite1;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
textureImage = Content.Load<Texture2D>(@"images/Picture");
UserControlledSprite1 = new userControlledSprite(textureImage, position, frameSize, collisionOffset, currentFrame, sheetSize, speed);
}
protected override void UnloadContent()
{
/// Ignore this void
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);
UserControlledSprite1.Draw(gameTime, spriteBatch);
base.Draw(gameTime);
}
}
}
Sprite.cs-繪制精靈並設置其動畫效果,並檢查碰撞。
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;
namespace Proj06
{
abstract class Sprite
{
Texture2D textureImage;
protected Point frameSize;
Point currentFrame;
Point sheetSize;
int collisionOffset;
int timeSinceLastFrame = 0;
int millisecondsPerFrame;
const int defaultMillisecondsPerFrame = 16;
protected Vector2 speed;
protected Vector2 position;
public Sprite(Texture2D textureImage, Vector2 position, Point frameSize,
int collisionOffset, Point currentFrame, Point sheetSize, Vector2 speed)
: this(textureImage, position, frameSize, collisionOffset, currentFrame,
sheetSize, speed, defaultMillisecondsPerFrame)
{
}
public Sprite(Texture2D textureImage, Vector2 position, Point frameSize,
int collisionOffset, Point currentFrame, Point sheetSize, Vector2 speed,
int millisecondsPerFrame)
{
this.textureImage = textureImage;
this.position = position;
this.frameSize = frameSize;
this.collisionOffset = collisionOffset;
this.currentFrame = currentFrame;
this.sheetSize = sheetSize;
this.speed = speed;
this.millisecondsPerFrame = millisecondsPerFrame;
}
public virtual void Update(GameTime gameTime, Rectangle clientBounds)
{
timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
if (timeSinceLastFrame > millisecondsPerFrame)
{
timeSinceLastFrame = 0;
++currentFrame.X;
if (currentFrame.X >= sheetSize.X)
{
currentFrame.X = 0;
++currentFrame.Y;
if (currentFrame.Y >= sheetSize.Y)
{
currentFrame.Y = 0;
}
}
}
}
public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch)
{
spriteBatch.Begin();
spriteBatch.Draw(textureImage,
position,
new Rectangle(currentFrame.X * frameSize.X,
currentFrame.Y * frameSize.Y,
frameSize.X, frameSize.Y),
Color.White, 0, Vector2.Zero,
1f, SpriteEffects.None, 0);
spriteBatch.End();
}
public abstract Vector2 direction
{
get;
}
public Rectangle collisionRect
{
get
{
return new Rectangle(
(int)position.X + collisionOffset,
(int)position.Y + collisionOffset,
frameSize.X - (collisionOffset * 2),
frameSize.Y - (collisionOffset * 2));
}
}
}
}
和userControlledSprite.cs-處理精靈的移動和位置
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Proj06
{
class userControlledSprite : Sprite
{
public userControlledSprite(Texture2D textureImage, Vector2 position,
Point frameSize, int collisionOffset, Point currentFrame, Point sheetSize,
Vector2 speed)
: base(textureImage, position, frameSize, collisionOffset, currentFrame,
sheetSize, speed)
{
}
public userControlledSprite(Texture2D textureImage, Vector2 position,
Point frameSize, int collisionOffset, Point currentFrame, Point sheetSize,
Vector2 speed, int millisecondsPerFrame)
: base(textureImage, position, frameSize, collisionOffset, currentFrame,
sheetSize, speed, millisecondsPerFrame)
{
}
public override Vector2 direction
{
get
{
Vector2 inputDirection = Vector2.Zero;
if (Keyboard.GetState().IsKeyDown(Keys.Left))
inputDirection.X -= 1;
if (Keyboard.GetState().IsKeyDown(Keys.Right))
inputDirection.X += 1;
if (Keyboard.GetState().IsKeyDown(Keys.Up))
inputDirection.Y -= 1;
if (Keyboard.GetState().IsKeyDown(Keys.Down))
inputDirection.Y += 1;
return inputDirection * speed;
}
}
public override void Update(GameTime gameTime, Rectangle clientBounds)
{
position += direction;
if (position.X < 0)
position.X = 0;
if (position.Y < 0)
position.Y = 0;
if (position.X > clientBounds.Width - frameSize.X)
position.X = clientBounds.Width - frameSize.X;
if (position.Y > clientBounds.Height - frameSize.Y)
position.X = clientBounds.Height - frameSize.Y;
base.Update(gameTime, clientBounds);
}
}
}
我將繼續在線搜索任何有用的資源,並在發現任何內容后發表修改。 謝謝你的時間。
將UserControlledSprite1的字段定義保留在此處,但不要在此處對其進行初始化:
public class Game1 : Microsoft.Xna.Framework.Game
{
userControlledSprite UserControlledSprite1;
}
然后在加載紋理后立即在LoadContent()
方法中對其進行初始化:
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
textureImage = Content.Load<Texture2D>(@"images/Picture");
UserControlledSprite1 = new userControlledSprite(textureImage, position, frameSize, collisionOffset, currentFrame, sheetSize, speed);
}
另外,請確保在Game1.Draw()
調用UserControlledSprite1.Draw()
方法。
這很簡單,永遠不會調用您的Draw
和Update
方法。
如果希望XNA自動調用它們,則您的Sprite
類需要擴展DrawableGameComponent
並在Game1
進行注冊。 為此,您需要將Game
作為參數傳遞。 您將要重寫的Draw
方法也需要一個SpriteBatch
,因此也要在構造函數中傳遞它。 這並不是真正的干凈方法,但是會起作用。 然后在您擁有的每個DrawableGameComponent
上調用Components.Add
。
一旦完成,只需在Game1中調用spriteBatch.Begin()和spriteBatch.End()(只對Begin和End進行一次調用),然后每個Sprite都會繪制自己。
我還自由using
s刪除了無用的東西,並修復了您的類名以適合C#約定(PascalCase)。
更改的重要部分是:
請注意,我沒有更改您的Update方法。 除非您將其更改為public override void Update(GameTime gameTime)
否則它不會被調用。
如果您在Draw中設置一個斷點,則XNA應該調用它。
Game1.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Proj06
{
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private Texture2D textureImage;
private Point frameSize = new Point(52, 50);
private Point currentFrame = new Point(0, 0);
private Point sheetSize = new Point(4, 1);
private Vector2 position = Vector2.Zero;
private int collisionOffset = 1;
private Vector2 speed;
private UserControlledSprite userControlledSprite1;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
textureImage = Content.Load<Texture2D>(@"images/Picture");
userControlledSprite1 = new UserControlledSprite(this, spriteBatch, textureImage, position, frameSize, collisionOffset, currentFrame, sheetSize, speed);
Components.Add(userControlledSprite1);
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);
spriteBatch.Begin();
base.Draw(gameTime);
spriteBatch.End();
}
}
}
UserControlledSprite.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Proj06
{
class UserControlledSprite : Sprite
{
public UserControlledSprite(Game game, SpriteBatch sb, Texture2D textureImage, Vector2 position,
Point frameSize, int collisionOffset, Point currentFrame, Point sheetSize,
Vector2 speed)
: base(game, sb, textureImage, position, frameSize, collisionOffset, currentFrame,
sheetSize, speed)
{
}
public UserControlledSprite(Game game, SpriteBatch sb, Texture2D textureImage, Vector2 position,
Point frameSize, int collisionOffset, Point currentFrame, Point sheetSize,
Vector2 speed, int millisecondsPerFrame)
: base(game, sb, textureImage, position, frameSize, collisionOffset, currentFrame,
sheetSize, speed, millisecondsPerFrame)
{
}
public override Vector2 direction
{
get
{
Vector2 inputDirection = Vector2.Zero;
if (Keyboard.GetState().IsKeyDown(Keys.Left))
inputDirection.X -= 1;
if (Keyboard.GetState().IsKeyDown(Keys.Right))
inputDirection.X += 1;
if (Keyboard.GetState().IsKeyDown(Keys.Up))
inputDirection.Y -= 1;
if (Keyboard.GetState().IsKeyDown(Keys.Down))
inputDirection.Y += 1;
return inputDirection * speed;
}
}
public override void Update(GameTime gameTime, Rectangle clientBounds)
{
position += direction;
if (position.X < 0)
position.X = 0;
if (position.Y < 0)
position.Y = 0;
if (position.X > clientBounds.Width - frameSize.X)
position.X = clientBounds.Width - frameSize.X;
if (position.Y > clientBounds.Height - frameSize.Y)
position.X = clientBounds.Height - frameSize.Y;
base.Update(gameTime, clientBounds);
}
}
}
Sprite.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Proj06
{
abstract class Sprite : DrawableGameComponent
{
Texture2D textureImage;
protected Point frameSize;
Point currentFrame;
Point sheetSize;
int collisionOffset;
int timeSinceLastFrame = 0;
int millisecondsPerFrame;
const int defaultMillisecondsPerFrame = 16;
protected Vector2 speed;
protected Vector2 position;
private SpriteBatch spriteBatch;
public Sprite(Game game, SpriteBatch sb, Texture2D textureImage, Vector2 position, Point frameSize,
int collisionOffset, Point currentFrame, Point sheetSize, Vector2 speed)
: this(game, sb, textureImage, position, frameSize, collisionOffset, currentFrame,
sheetSize, speed, defaultMillisecondsPerFrame)
{
}
public Sprite(Game game, SpriteBatch sb, Texture2D textureImage, Vector2 position, Point frameSize,
int collisionOffset, Point currentFrame, Point sheetSize, Vector2 speed,
int millisecondsPerFrame) : base(game)
{
this.textureImage = textureImage;
this.position = position;
this.frameSize = frameSize;
this.collisionOffset = collisionOffset;
this.currentFrame = currentFrame;
this.sheetSize = sheetSize;
this.speed = speed;
this.millisecondsPerFrame = millisecondsPerFrame;
spriteBatch = sb;
}
public virtual void Update(GameTime gameTime, Rectangle clientBounds)
{
timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
if (timeSinceLastFrame > millisecondsPerFrame)
{
timeSinceLastFrame = 0;
++currentFrame.X;
if (currentFrame.X >= sheetSize.X)
{
currentFrame.X = 0;
++currentFrame.Y;
if (currentFrame.Y >= sheetSize.Y)
{
currentFrame.Y = 0;
}
}
}
}
public override void Draw(GameTime gameTime)
{
spriteBatch.Draw(textureImage,
position,
new Rectangle(currentFrame.X * frameSize.X,
currentFrame.Y * frameSize.Y,
frameSize.X, frameSize.Y),
Color.White, 0, Vector2.Zero,
1f, SpriteEffects.None, 0);
base.Draw(gameTime);
}
public abstract Vector2 direction
{
get;
}
public Rectangle collisionRect
{
get
{
return new Rectangle(
(int)position.X + collisionOffset,
(int)position.Y + collisionOffset,
frameSize.X - (collisionOffset * 2),
frameSize.Y - (collisionOffset * 2));
}
}
}
}
作為附錄,我強烈建議您轉到MonoGame。 XNA不再受支持(很久以前它已被Microsoft淘汰),MonoGame是開源實現。 並沒有太大的改變,但是您仍然需要使用XNA的內容管道(.XNB文件)。
如果要堅持使用XNA,請使用Platformer Starter Kit啟動項目。 您將更好地了解XNA的工作原理,因為您的體系結構很奇怪。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.