0

さて、私はビジュアル スタジオ 2010 c# で xna studio を使用してスペース インベーダー タイプのゲームを作成しています。bullet クラスには、Public Vector2 の起点が示されています。何にも割り当てられておらず、デフォルト値のままですが、何が原因なのかわかりません。

箇条書きのコード

   class Bullets
    {
        public Texture2D texture;

        public Vector2 position;
        public Vector2 velocity;
        public Vector2 origin;

        public bool isVisible;

        public Bullets(Texture2D newTexture)
        {
            texture = newTexture;
            isVisible = false;
        }




        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(texture, position, null, Color.White, 0f, origin, 1f, SpriteEffects.None, 1);
        }

    }

ゲームのコードは次のとおりです。

namespace Rotationgame
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Vector2 spriteVelocity;
        const float tangentialVelocity = 0f;
        float friction = 1f;

        Texture2D spriteTexture;
        Rectangle spriteRectangle;

        Rectangle screenRectangle;

        // The centre of the image
        Vector2 spriteOrigin;

        Vector2 spritePosition;
        float rotation;

        // Background
        Texture2D backgroundTexture;
        Rectangle backgroundRectangle;


        // Shield
        Texture2D shieldTexture;
        Rectangle shieldRectangle;

        // Bullets
        List<Bullets> bullets = new List<Bullets>();
        KeyboardState pastKey;



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

            graphics.PreferredBackBufferWidth = 1250;
            graphics.PreferredBackBufferHeight = 930;

            screenRectangle = new Rectangle(
                0,
                0,
                graphics.PreferredBackBufferWidth,
                graphics.PreferredBackBufferHeight);
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            shieldTexture = Content.Load<Texture2D>("Shield");
            shieldRectangle = new Rectangle(517, 345, 250, 220);

            spriteTexture = Content.Load<Texture2D>("PlayerShipup");
            spritePosition = new Vector2(640, 450);

            backgroundTexture = Content.Load<Texture2D>("Background");
            backgroundRectangle = new Rectangle(0, 0, 1250, 930);

            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                this.Exit();

            // TODO: Add your update logic here

            if (Keyboard.GetState().IsKeyDown(Keys.Space) && pastKey.IsKeyUp(Keys.Space))
                Shoot();
            pastKey = Keyboard.GetState();

            spritePosition = spriteVelocity + spritePosition;

            spriteRectangle = new Rectangle((int)spritePosition.X, (int)spritePosition.Y,
                spriteTexture.Width, spriteTexture.Height);
            spriteOrigin = new Vector2(spriteRectangle.Width / 2, spriteRectangle.Height / 2);

            if (Keyboard.GetState().IsKeyDown(Keys.Right)) rotation += 0.025f;
            if (Keyboard.GetState().IsKeyDown(Keys.Left)) rotation -= 0.025f;

            if (Keyboard.GetState().IsKeyDown(Keys.Up))
            {
                spriteVelocity.X = (float)Math.Cos(rotation) * tangentialVelocity;
                spriteVelocity.Y = (float)Math.Sin(rotation) * tangentialVelocity;
            }
            else if (Vector2.Zero != spriteVelocity)
            {
                float i = spriteVelocity.X;
                float j = spriteVelocity.Y;

                spriteVelocity.X = i -= friction * i;
                spriteVelocity.Y = j -= friction * j;


                base.Update(gameTime);

            }
        }

        public void UpdateBullets()
        {
            foreach (Bullets bullet in bullets)
            {
                bullet.position += bullet.velocity;
                if (Vector2.Distance(bullet.position, spritePosition) > 100)
                    bullet.isVisible = false;
            }
            for (int i = 0; i < bullets.Count; i++)
            {
                if(!bullets[i].isVisible)
                {
                    bullets.RemoveAt(i);
                    i--;


                }


            }
        }

        public void Shoot()
        {
            Bullets newBullet = new Bullets(Content.Load<Texture2D>("ball"));
            newBullet.velocity = new Vector2((float)Math.Cos(rotation),(float)Math.Sin(rotation)) * 5f + spriteVelocity;
            newBullet.position = spritePosition + newBullet.velocity * 5;
            newBullet.isVisible = true;

            if(bullets.Count() < 20)
                bullets.Add(newBullet);
        }



        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();
            spriteBatch.Draw(backgroundTexture, backgroundRectangle, Color.White);
            spriteBatch.Draw(shieldTexture, shieldRectangle, Color.White);
            foreach (Bullets bullet in bullets)
                bullet.Draw(spriteBatch);
            spriteBatch.Draw(spriteTexture, spritePosition, null, Color.White, rotation, spriteOrigin, 1f, SpriteEffects.None, 0);
            spriteBatch.End();


            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }

どこが間違っていますか?

4

2 に答える 2

2

箇条書きを描画するとき、原点を引数として渡しますが、値を設定することはありません。原点にしたい画像上のポイントを見つける必要があります(したがって、箇条書きを 0,0 に配置すると、画像のその部分が 0,0 になります)。

変数に値を設定せず、関数で必要な場合に関数に値を渡そうとすると、プログラムがクラッシュします。

最初に 0,0 を試すので、クラスで

Vector2 origin=new Vector2(0,0);

これにより、コードが機能し、好みに基づいてオリジンを微調整できます。

また、これらの変数を public にする代わりに、private にして get および set 関数を bullet で作成し、それらを設定または値を取得することをお勧めします。これにより、予測できないアクセスや変更のリスクが最小限に抑えられます

編集:問題は問題ではありませんでしたが、もう一度気づきました。

    protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        if (Keyboard.GetState().IsKeyDown(Keys.Escape))
            this.Exit();

        updateBullets();
        ...
    }

更新関数で updateBullets を実際に呼び出す必要があります。自動的には呼び出されません。

于 2013-05-28T19:24:52.933 に答える
0

メソッドを呼び出すようにGameクラスメソッドを変更したところ、弾丸スプライトが一定方向に移動してから消えます。UpdateUpdateBullets

Shoot()また、船の回転方向に応じて弾丸を適切に向ける方法も修正しました。

    protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        if (Keyboard.GetState().IsKeyDown(Keys.Escape))
            this.Exit();

        // TODO: Add your update logic here

        if (Keyboard.GetState().IsKeyDown(Keys.Space) && pastKey.IsKeyUp(Keys.Space))
            Shoot();
        pastKey = Keyboard.GetState();

        spritePosition = spriteVelocity + spritePosition;

        spriteRectangle = new Rectangle((int)spritePosition.X, (int)spritePosition.Y,
            spriteTexture.Width, spriteTexture.Height);
        spriteOrigin = new Vector2(spriteRectangle.Width / 2, spriteRectangle.Height / 2);

        if (Keyboard.GetState().IsKeyDown(Keys.Right)) rotation += 0.025f;
        if (Keyboard.GetState().IsKeyDown(Keys.Left)) rotation -= 0.025f;

        if (Keyboard.GetState().IsKeyDown(Keys.Up))
        {
            spriteVelocity.X = (float)Math.Cos(rotation) * tangentialVelocity;
            spriteVelocity.Y = (float)Math.Sin(rotation) * tangentialVelocity;
        }
        else if (Vector2.Zero != spriteVelocity)
        {
            float i = spriteVelocity.X;
            float j = spriteVelocity.Y;

            spriteVelocity.X = i -= friction * i;
            spriteVelocity.Y = j -= friction * j;


            base.Update(gameTime);

        }
        UpdateBullets();
    }
    public void Shoot()
    {
        Bullets newBullet = new Bullets(Content.Load<Texture2D>("ball"));
        newBullet.velocity = new Vector2((float)Math.Sin(rotation), (float)Math.Cos(rotation)) * new Vector2(5f,-5f) + spriteVelocity;
        newBullet.position = spritePosition + newBullet.velocity * 5;
        newBullet.isVisible = true;

        if (bullets.Count < 20)
            bullets.Add(newBullet);
    }
于 2013-05-29T14:08:08.403 に答える