c# XNA使用数组发射子弹

本文关键字:发射 子弹 数组 XNA | 更新日期: 2023-09-27 18:07:50

显然我必须展示我的研究努力(并且更清楚)?

我一直在尝试使用XNA从头开始制作一款自上而下的太空射击游戏。我以前也这样做过几次,但是有一段时间没有编码了,这又让我犯了错误。我有一个问题,使子弹火如何我想要他们太(我想要一个最大指定数量的子弹)。

我读过很多关于使用数组的文章,但出于某种原因,我不明白为什么它们只出现在一个项目中。我已经尽我所能进行了调试,看到它们似乎都是在按下空间时被创造和"发射"的,但是它们似乎都被画在相同的位置,因此看起来像一颗子弹。有趣的是,我设置的"maxBullets"变量越高,子弹移动的速度就越快,就好像每次我创建一个新的Bullet1时,位置=速度都被应用到所有的子弹上。

有谁能帮我找到解决办法吗?如果你需要任何信息,如果我有遗漏的东西,请让我知道。感谢所有的帮助。谢谢:)

代码如下:

     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 AlienAttacks
        {
            public class Player
            {
                Texture2D texture, bulletTexture1;
                KeyboardState kbState;

                public Vector2 position;
                public int turnSpeed = 15, backSpeed = 2, forwardSpeed = 3;
                Rectangle gameScreenBounds;
                public int frameWidth, frameHeight, currentFrameX, currentFrameY;
                Rectangle drawnRect;
                Bullet[] bullets;
                Bullet bullet1;
                public int maxBullets = 3; // this will actually allow one extra bullet due to array starting at zero
                public int bulletSpeed = 4;
                public float FireTimer = 0.0f, FireRate = 0.8f;
                public Player(Texture2D Texture, int FrameWidth, int FrameHeight, Rectangle GameScreenBounds, Texture2D BulletTexture1)
                {
                    texture = Texture;
                    frameWidth = FrameWidth;
                    frameHeight = FrameHeight;
                    gameScreenBounds = GameScreenBounds;
                    bulletTexture1 = BulletTexture1;
                    bullet1 = new Bullet(bulletTexture1, bulletSpeed);
                    bullets = new Bullet[maxBullets];
                    for (int i = 0; i < maxBullets; i++)
                    {
                        bullets[i] = bullet1;  
                    }
                }
                public void Update(GameTime gameTime)
                {
                    drawnRect = new Rectangle(currentFrameX * frameWidth, currentFrameY * frameHeight, frameWidth, frameHeight);
                    kbState = Keyboard.GetState();
        // Keyboard Controls
                    if (kbState.IsKeyDown(Keys.A) && position.X > gameScreenBounds.Left)
                    {
                        position.X -= turnSpeed;
                    }
                    if (kbState.IsKeyDown(Keys.D) && position.X + frameWidth < gameScreenBounds.Right)
                    {
                        position.X += turnSpeed;
                    }
                    if (kbState.IsKeyDown(Keys.W) && position.Y > gameScreenBounds.Top)
                    {
                        currentFrameX = 1;
                        position.Y -= forwardSpeed; 
                    }
                    else
                        currentFrameX = 0;
                    if (kbState.IsKeyDown(Keys.S) && position.Y + frameHeight < gameScreenBounds.Bottom)
                    {
                        position.Y += backSpeed;
                    }
                    for (int i = 0; i < maxBullets; i++)
                    {
                        bullets[i] = bullet1;
                        bullets[i].Update(gameTime);        
                    }
                    FireTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
                    if (kbState.IsKeyDown(Keys.Space))
                    {
                        for (int i = 0; i < maxBullets; i++)
                        {
                            if (FireTimer >= FireRate)
                            {
                                if (!bullets[i].IsAlive)
                                {
                                    bullets[i].IsAlive = true;
                                    bullets[i].position = position;
                                    FireTimer = 0.0f;
                                }
                            }
                        }
                    }


                }
                public void Draw(SpriteBatch spriteBatch)
                {
                    spriteBatch.Draw(texture, position, drawnRect, Color.White);
                    for (int i = 0; i < maxBullets; i++)
                    {
                        bullets[i].Draw(spriteBatch);
                    }
                }
            }
        }

    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 AlienAttacks
    {
        public class Bullet
        {
            public Texture2D texture;
            public Vector2 position;
            public int speed;
            public bool IsAlive = false;

            public Bullet(Texture2D Texture, int Speed)
            {
                texture = Texture;
                speed = Speed;
            }
            public void Update(GameTime gameTime)
            {
                if (IsAlive)
                {
                    position.Y -= speed;
                    // if bullet goes off top of screen...
                    if (position.Y - texture.Height < 0)
                    {
                        BulletDead();
                    }
                }
            }
            public void Draw(SpriteBatch spriteBatch)
            {
                if (IsAlive)
                    spriteBatch.Draw(texture, position, Color.White);
            }
            public void BulletDead()
            {
                IsAlive = false;
            }
        }
    }

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 AlienAttacks
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Rectangle gameScreenBounds;
        Texture2D hudBGTexture;
        Rectangle hudRect;
        int hudPositionY;
        Texture2D p1Texture, p1bulletTexture1;
        Player player1;
        Vector2 player1StartPosition;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
        /// <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
            graphics.PreferredBackBufferWidth = 1600;
            graphics.PreferredBackBufferHeight = 900;
            //graphics.IsFullScreen = true;


            graphics.ApplyChanges();
            hudRect = new Rectangle(0, 0, graphics.PreferredBackBufferWidth, 100);
            hudPositionY = graphics.PreferredBackBufferHeight - hudRect.Height;
            gameScreenBounds = new Rectangle(0, 0, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight - hudRect.Height);
            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);
            hudBGTexture = Content.Load<Texture2D>("hud");
            p1bulletTexture1 = Content.Load<Texture2D>("shot");
            p1Texture = Content.Load<Texture2D>("red");
            player1 = new Player(p1Texture, 144, 104, gameScreenBounds, p1bulletTexture1);
            player1StartPosition = new Vector2(graphics.PreferredBackBufferWidth / 2 - player1.frameWidth / 2, graphics.PreferredBackBufferHeight - hudRect.Height - player1.frameHeight);
            player1.position = player1StartPosition;

        }
            /// <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 (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                    this.Exit();
                player1.Update(gameTime);
                base.Update(gameTime);
            }
        /// <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.Black);
            SpriteBatch targetBatch = new SpriteBatch(GraphicsDevice);
            RenderTarget2D target = new RenderTarget2D(GraphicsDevice, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);
            GraphicsDevice.SetRenderTarget(target);
            spriteBatch.Begin();
            player1.Draw(spriteBatch);
            spriteBatch.Draw(hudBGTexture, new Vector2(0, hudPositionY), Color.WhiteSmoke);
            spriteBatch.End();
            GraphicsDevice.SetRenderTarget(null);
            targetBatch.Begin();
            targetBatch.Draw(target, new Rectangle(0, 0, GraphicsDevice.DisplayMode.Width, GraphicsDevice.DisplayMode.Height), Color.White);
            targetBatch.End();

            base.Draw(gameTime);
        }
    }
}

c# XNA使用数组发射子弹

看起来数组中的每一项都指向一个实例。

bullet1 = new Bullet(bulletTexture1, bulletSpeed);
bullets = new Bullet[maxBullets];
for (int i = 0; i < maxBullets; i++)
{
    bullets[i] = bullet1;  
}

应该是这样的:

bullets = new Bullet[maxBullets];
for (int i = 0; i < maxBullets; i++)
{
    bullets[i] = new Bullet(bulletTexture1, bulletSpeed);  
}