XNA Sprite似乎没有更新?

时间:2014-06-22 12:06:55

标签: c# xna sprite xna-4.0

我已经查看了其他一些问题并且没有找到我的答案所以我问你可爱的人,因为你之前曾帮助过我:)

我有一个主类(RPG.cs)和一个播放器类(Player.cs),我希望Player类尽可能自包含(因为我不想要一个huuuge主类)但是这里是我的问题。

问题

我的玩家精灵画得很好,但是当我想让它移动时,它不会更新!目前我正试图让它像一个光标来测试运动,但最终我将它绑定到WASD或箭头键。所以我希望我的精灵现在跟着我的鼠标,但它只停留在50,50(它是预设的起始位置)我是否错过了一些明显的东西?我是XNA的新手,我花了半个小时来解决这个问题!

RPG.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 TestGame
{
    public class RPG : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D PlayerTex;
        Rectangle playerPos = new Rectangle(
            Convert.ToInt32(Player.Pos.X), 
            Convert.ToInt32(Player.Pos.Y), 32, 32);
        public RPG()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            IsMouseVisible = true;
        }
        protected override void Initialize() { base.Initialize(); }
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            PlayerTex = Content.Load<Texture2D>("testChar");
        }
        protected override void UnloadContent() { }
        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);
            spriteBatch.Begin();
            spriteBatch.Draw(PlayerTex, playerPos, Color.White);
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}

Player.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 TestGame
{
    /// This is a game component that implements IUpdateable.
    public class Player : Microsoft.Xna.Framework.GameComponent
    {
        public static Vector2 Pos = new Vector2(50, 50);
        MouseState ms = Mouse.GetState();
        public Player(Game game) : base(game) { }
        /// Allows the game component to perform 
        /// any initialization it needs to before 
        /// starting to run. This is where it can 
        /// query for any required services and load content.
        public override void Initialize() { base.Initialize(); }
        /// Allows the game component to update itself.
        public override void Update(GameTime gameTime)
        {
            Pos.X = ms.X;
            Pos.Y = ms.Y;
            base.Update(gameTime);
        }
    }
}

希望你能帮忙! :)

2 个答案:

答案 0 :(得分:2)

正如评论中所提到的,我不打算解决所有问题。但主要的错误。

让玩家负责其位置,而不是游戏。此外,我会让玩家负责画画,但这个答案有点太过分了。

以下代码至少应该有效。

public class Player : Microsoft.Xna.Framework.GameComponent
{
    public Vector2 Pos { get; set; }

    public Player(Game game) : base(game)
    {
        this.Pos = new Vector2(50, 50);
    }

    public override void Initialize() { base.Initialize(); }

    public override void Update(GameTime gameTime)
    {
        var ms = Mouse.GetState();
        Pos.X = ms.X;
        Pos.Y = ms.Y;
        base.Update(gameTime);
    }
}

然后在游戏中使用播放器:

public class RPG : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    Texture2D PlayerTex;

    Player player;

    public RPG()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
        IsMouseVisible = true;
        player = new Player(this);
        Components.Add(player);
    }
    protected override void Initialize() { base.Initialize(); }
    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);
        PlayerTex = Content.Load<Texture2D>("testChar");
    }
    protected override void UnloadContent() { }
    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);
        spriteBatch.Begin();
        spriteBatch.Draw(PlayerTex, player.Pos, Color.White);
        spriteBatch.End();
        base.Draw(gameTime);
    }
}

我删除了纹理的大小。不知道你是否真的需要这个。如果是这样,您可以让Player公开一个矩形,而不仅仅是Vector2

答案 1 :(得分:0)

Nico包含的关键解决方案就是您使用绘制时创建的原始矩形坐标:

Rectangle playerPos = new Rectangle(
             Convert.ToInt32(Player.Pos.X), 
             Convert.ToInt32(Player.Pos.Y), 32, 32);

这里使用玩家CURRENT开始时间位置制作矩形。 然后你总是根据你很久以前制作的这个矩形进行绘制而且从未更新:

        spriteBatch.Draw(PlayerTex, playerPos, Color.White);

Nico提到的正确方法就是将抽签改为:

 playerPos = new Rectangle(
             Convert.ToInt32(Player.Pos.X), 
             Convert.ToInt32(Player.Pos.Y), 32, 32);

    spriteBatch.Draw(PlayerTex, playerPos, Color.White);

现在你每次都会在一个新的地方画画。有更好的方法来做到这一点(就像尼科所做的那样),但这是核心理念。