1

衝突検出をテストするための簡単なゲームを作成しようとしていますが、正しく動作しません。正常にビルドされますが、実行時に「NullReferenceException: オブジェクト参照がオブジェクトのインスタンスに設定されていません」というエラーが発生します。

SpriteManager.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 Project_3
{
    public class SpriteManager : Microsoft.Xna.Framework.DrawableGameComponent
    {
        private Game1 _Game1;
        //SpriteBatch for drawing
        SpriteBatch spriteBatch;

        //A sprite for the player and a list of automated sprites
        UserControlledSprite player;
        List<Sprite> spriteList = new List<Sprite>();


        public SpriteManager(Game1 game)
            : base(game)
        {
            // TODO: Construct any child components here
            _Game1 = game;
        }

        public override void Initialize()
        {
            // TODO: Add your initialization code here

            base.Initialize();
        }

        protected override void LoadContent()
        {

            spriteBatch = new SpriteBatch(Game.GraphicsDevice);

            //Load the player sprite
            player = new UserControlledSprite(
                Game.Content.Load<Texture2D>("Images/bill"),
                Vector2.Zero, 10, new Vector2(6, 6));

            //Load several different automated sprites into the list
            spriteList.Add(new AutomatedSprite(
                Game.Content.Load<Texture2D>("Images/kit"),
                new Vector2(150, 150), 10, Vector2.Zero));
            spriteList.Add(new AutomatedSprite(
                Game.Content.Load<Texture2D>("Images/kit"),
                new Vector2(300, 150), 10, Vector2.Zero));
            spriteList.Add(new AutomatedSprite(
                Game.Content.Load<Texture2D>("Images/beast"),
                new Vector2(150, 300), 10, Vector2.Zero));
            spriteList.Add(new AutomatedSprite(
                Game.Content.Load<Texture2D>("Images/beast"),
                new Vector2(600, 400), 10, Vector2.Zero));

            base.LoadContent();
        }

        public override void Update(GameTime gameTime)
        {
            // Update player
            player.Update(gameTime, Game.Window.ClientBounds);

            // Update all sprites
            foreach (Sprite s in spriteList)
            {
                s.Update(gameTime, Game.Window.ClientBounds);
            }

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);

            // Draw the player
            player.Draw(gameTime, spriteBatch);

            // Draw all sprites
            foreach (Sprite s in spriteList)
                s.Draw(gameTime, spriteBatch);

            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}

例外をスローする行はplayer.Update(gameTime, Game.Window.ClientBounds);fromSpriteManagerです。完全な例外メッセージは、「プロジェクト 3.exe で 'System.NullReferenceException' 型の未処理の例外が発生しました。追加情報: オブジェクト参照がオブジェクトのインスタンスに設定されていません。」

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 Project_3
{
class UserControlledSprite : Sprite
{
    // Movement stuff
    MouseState prevMouseState;

    // Get direction of sprite based on player input and speed
    public override Vector2 direction
    {
        get
        {
            Vector2 inputDirection = Vector2.Zero;

            // If player pressed arrow keys, move the sprite
            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;

            // If player pressed the gamepad thumbstick, move the sprite
            GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
            if (gamepadState.ThumbSticks.Left.X != 0)
                inputDirection.X += gamepadState.ThumbSticks.Left.X;
            if (gamepadState.ThumbSticks.Left.Y != 0)
                inputDirection.Y -= gamepadState.ThumbSticks.Left.Y;

            return inputDirection * speed;
        }
    }

    public UserControlledSprite(Texture2D textureImage, Vector2 position, int collisionOffset, Vector2 speed)
    {
    }

    public override void Update(GameTime gameTime, Rectangle clientBounds)
    {
        // Move the sprite based on direction
        position += direction;

        // If player moved the mouse, move the sprite
        MouseState currMouseState = Mouse.GetState();
        if (currMouseState.X != prevMouseState.X ||
            currMouseState.Y != prevMouseState.Y)
        {
            position = new Vector2(currMouseState.X, currMouseState.Y);
        }
        prevMouseState = currMouseState;

        // If sprite is off the screen, move it back within the game window
        if (position.X < 0)
            position.X = 0;
        if (position.Y < 0)
            position.Y = 0;
        if (position.X > clientBounds.Width - 150)
            position.X = clientBounds.Width - 150;
        if (position.Y > clientBounds.Height - 150)
            position.Y = clientBounds.Height - 150;

        base.Update(gameTime, clientBounds);
    }
}
}

なぜ機能しないのかわかりません。さまざまなことを試しましたが、xna は初めてなので、単純なものが欠けている可能性があります。

どんな助けでも大歓迎です。

編集:Sprite.csを追加するのを忘れました:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Project_3
{
    abstract class Sprite
    {
    // Stuff needed to draw the sprite
    Texture2D textureImage;

    // Collision data
    int collisionOffset;

    // Movement data
    protected Vector2 speed;
    protected Vector2 position;

    // Abstract definition of direction property
    public abstract Vector2 direction
    {
        get;
    }

    public Sprite()
    {
    }

    public Sprite(Texture2D textureImage, Vector2 position, int collisionOffset, Vector2 speed)
    //: this(textureImage, position, collisionOffset, speed)
    {
    }

    public virtual void Update(GameTime gameTime, Rectangle clientBounds)
    {

    }

    public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch)
    {
        // Draw the sprite
        if (textureImage != null)
        {
            spriteBatch.Draw(textureImage, position, Color.White);
        }
    }

    // Gets the collision rect based on position, framesize and collision offset
    public Rectangle collisionRect
    {
        get
        {
            return new Rectangle(
                (int)position.X + collisionOffset,
                (int)position.Y + collisionOffset,
                150 - (collisionOffset * 2),
                150 - (collisionOffset * 2));
        }
    }


    public Game1 _Game1 { get; set; }
}
}
4

2 に答える 2

0

申し訳ありませんが、まだコメントできません。

プレーヤー (UserControlledSprite) を作成するときに、"UserControlledSprite(...parameters...)" から Sprite コンストラクターを呼び出すようには見えません。

public UserControlledSprite(Texture2D textureImage, Vector2 position, int collisionOffset, Vector2 speed)
{
}

次のようにする必要があるかもしれません:

public UserControlledSprite(Texture2D textureImage, Vector2 position, int collisionOffset, Vector2 speed) 
    : base(TextureImage, position, collisionOffset, speed)
{
}

通過するデータを設定することも役立ちます。したがって、textureImage、位置、collisionOffset、および速度を渡します。Sprite クラスに変数があることはわかりますが、コンストラクターで変数を作成するときにそれらを設定することはありません。そうでない場合は教えてください。変数と同じ名前のパラメーターを渡すと、自動的に設定されますか? そうでない場合は、スプライト クラスの position、collisionOffset、speed、および textureImage を、実際に渡されたパラメーターに実際に設定していることを確認してください。クラスの変数と同じ名前をパラメーターに付けることはできないといつも思っていました。

したがって、次のことを行う必要があります(上記が当てはまる場合):

public UserControlledSprite(Texture2D _textureImage, Vector2 _position, int _collisionOffset, Vector2 _speed) 
    : base(_textureImage, _position, _collisionOffset, _speed)
{
    //Do this either here or in Sprite. 
    this.textureImage = _textureImage;
    this.position = _position;
    this.collisionOffset = _collisionOffset;
    this.speed = _speed.
}    

上記(このすぐ上)の詳細は、現在の問題にとってそれほど重要ではないと思います。コンストラクターと関係があると思いますが、よくわかりません。私はここに VS を持っていないので、今のところあなたを助けたいと思っています。

とにかく、それが役立つことを願っています。すみません、できればコメントします。残念ながらまだできません。

于 2014-04-04T02:11:17.680 に答える
0

インスタンス化していませんpositionposition変数をコンストラクターに渡しUserControlledSpriteますが、クラスのスコープ内の変数には適用しません。コンストラクター メソッドにのみ表示される位置変数を保持するには、別の変数を宣言する必要があります。

これは、UserControlledSpriteオブジェクトが最初に を呼び出すUpdateと、position += direction;がスローされることを意味しますNullReferenceException。正直なところ、コード全体を表示しない限りposition、のコンテキストには存在しないため、コンパイル時エラーが発生しなかった理由はわかりません。Update

于 2013-03-25T09:29:50.573 に答える