-2

パドルボールとボールのクラスを使用して、XNA / C#でPongを作成しようとしています。

Game1.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 Pong
{

    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Paddle Paddle1 = new Paddle();

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

        }

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

            Paddle1.Draw();
            base.Draw(gameTime);
        }
    }
}

Paddle.cs:

namespace Pong
{
    class Paddle
    {
        SpriteBatch spriteBatch;
        ContentManager Content;

        Texture2D paddle1;
        Texture2D paddle2;

        Vector2 Paddle1;
        Vector2 Paddle2;

        public void LoadContent()
        {
            paddle1 = Content.Load<Texture2D>("pongpaddle1");

            Paddle1 = new Vector2();
            Paddle1.X = 50;
            Paddle1.Y = 50;
        }

        public void Draw()
        {
            spriteBatch.Begin(); //Causes NullReferenceException was unhandled, Object reference not set to an instance of an object.
            spriteBatch.Draw(paddle1, Paddle1, Color.White);
            spriteBatch.End();
        }
    }
}

Ballクラスにはまだ何もありませんが、Paddle.csと同様のメソッドを使用します

コードを実行するたびに、Game1.csの次のコード行にヒットするたびにSystem.StackOverFlow例外が発生し続けます。

Paddle Paddle1 = new Paddle();

これを修正するにはどうすればよいですか?まだメモリが不足しているのかわかりません。

編集:更新されたコード。

4

2 に答える 2

0
    public class Game1 : Microsoft.Xna.Framework.Game
    {
         Paddle Paddle1 = new Paddle();
         Paddle Paddle2 = new Paddle();
    ...
     protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            Paddle1.LoadContent();
        }
    ...
    }

    class Paddle : Game1
    {
    ...
        protected override void LoadContent()
        {
            Paddle1 = new Vector2();
            Paddle1.X = 50;
            Paddle1.Y = 50;
            base.LoadContent();
        }
    ...
    }

ここでの 2 つの大きな問題は、再帰的な LoadContent 呼び出しです。パドルにはパドルがあるパドルがあることは言うまでもありません...パドルがGame1から継承されているのはなぜですか? ほぼ間違いなくそうであってはなりません。

また、パドル インスタンスは他のパドル インスタンスをインスタンス化するため、他のパドル クラスをインスタンス化するループに陥っています。一歩下がって、最初にいくつかの基本的なコードに慣れたいと思うかもしれませんか? 価値があるのは、数年前に楽しみのために xna でpong を書いたことです。少し面倒ですが、最初の助けになるかもしれません。

DrawableGameComponent クラスに基づくパドル クラスの例を次に示します (プリミティブで描画されているため、少し冗長です)。

public class Paddle : DrawableGameComponent
{
    private readonly VertexPositionColor[] _vertices = new VertexPositionColor[6];
    private readonly float _width;
    private readonly float _height;

    private IndexBuffer _indexbuffer;
    private VertexBuffer _vertexbuffer;

    public Vector3 Position { get; set; }
    public Vector3 Direction { get; set; }
    public float Speed { get; set; }

    public Paddle(Game game, float width, float height)
        : base(game)
    {
        _width = width;
        _height = height;
    }

    protected override void LoadContent()
    {
        base.LoadContent();

        _vertices[0].Position = new Vector3(0, 0, 0);
        _vertices[0].Color = Color.Red;

        _vertices[1].Position = new Vector3(_width, _height, 0);
        _vertices[1].Color = Color.Green;

        _vertices[2].Position = new Vector3(0, _height, 0);
        _vertices[2].Color = Color.Blue;

        _vertices[3].Position = new Vector3(_width, 0, 0);
        _vertices[3].Color = Color.Green;

        _vertexbuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionColor), _vertices.Length, BufferUsage.WriteOnly);
        _vertexbuffer.SetData(_vertices);

        var indices = new short[6];
        indices[0] = 0;
        indices[1] = 1;
        indices[2] = 2;
        indices[3] = 0;
        indices[4] = 3;
        indices[5] = 1;

        _indexbuffer = new IndexBuffer(GraphicsDevice, typeof(short), 6, BufferUsage.WriteOnly);
        _indexbuffer.SetData(indices);
    }

    public BoundingBox GetBoundingBox()
    {
        return new BoundingBox(Position, Position + new Vector3(_width, _height, 0));
    }

    public override void Draw(GameTime gameTime)
    {
        base.Draw(gameTime);

        GraphicsDevice.SetVertexBuffer(_vertexbuffer);
        GraphicsDevice.Indices = _indexbuffer;
        GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 4, 0, 2);
    }
}
于 2012-05-05T22:13:32.873 に答える
0

ここで起こっているのは、Paddle継承することGame1です。Game1を作成しますnew Paddle:

Paddle Paddle1 = new Paddle();
Paddle Paddle2 = new Paddle();

これらPaddleの はGame、独自の のセットを初期化する必要があるPaddleです。無限再帰!XNAがどのように機能するかはわかりませんが、それが継承の方法である場合は、初期化を次の場所に移動してくださいInitialize():

// TODO: Add your initialization logic here

base.Initialize();
this.Paddle1 = new Paddle();
this.Paddle2 = new Paddle();

ただし、ゲーム オブジェクトがゲーム自体から継承する必要があるとは思えません。それはかなり貧弱な設計上の決定のように思えます。

于 2012-05-05T22:14:32.623 に答える