XNA子弹命中盒不会跟随精灵,从而导致碰撞问题

本文关键字:问题 碰撞 精灵 跟随 子弹 XNA | 更新日期: 2023-09-27 18:30:27

我在XNA/Monogame中制作一个太空入侵游戏一切都很顺利,直到我遇到这个问题。几天来我一直在尝试修复子弹命中盒,但没有成功。我的问题是命中盒不会随着子弹本身而移动。碰撞检测属于 Game1 类。子弹类中的实际移动和射击扳机在坦克类中。子弹也继承给了雪碧.cs雪碧给了它一个命中框。

谁能帮我。我真的只想在开始做其他事情之前完成我开始的事情。

非常感谢

帮助。

游戏1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace IsisInvaders
{
    /// <summary>
    /// This is the main type for your game.
    /// </summary>
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Tank Tank;
        Isis Isis1;
        Isis Isis2;
        Isis Isis3;
        Isis Isis4;
        Isis Isis5;
    Isis Isis6;
    Isis Isis7;
    Isis Isis8;
    Isis Isis9;
    Isis Isis10;
    Isis Isis11;
    Bullets Bullets;
    private Song BgMusic;
    int screenWidth;
    int screenHeight;
    enum GameState
    {
        MainMenu,
        Playing,
    }
    GameState CurrentGameState = GameState.MainMenu;
    Button btnPlay;
    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
        //Bullet = new Bullets(Tank.position);
        Tank = new Tank(new Vector2 (375,425));
        Isis1 = new Isis(new Vector2(30, 0));
        Isis2 = new Isis(new Vector2(70, 0));
        Isis3 = new Isis(new Vector2(110, 0));
        Isis4 = new Isis(new Vector2(150, 0));
        Isis5 = new Isis(new Vector2(190, 0));
        Isis6 = new Isis(new Vector2(230, 0));
        Isis7 = new Isis(new Vector2(270, 0));
        Isis8 = new Isis(new Vector2(310, 0));
        Isis9 = new Isis(new Vector2(350, 0));
        Isis10 = new Isis(new Vector2(390, 0));
        Isis11 = new Isis(new Vector2(430, 0));
        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()
    {
        graphics.PreferredBackBufferHeight = 800;
        graphics.PreferredBackBufferHeight = 600;
        graphics.ApplyChanges();
        btnPlay = new Button(Content.Load<Texture2D>("Start"), graphics.GraphicsDevice);
        IsMouseVisible = true;

        spriteBatch = new SpriteBatch(GraphicsDevice);
        btnPlay.setPosition(new Vector2(350, 300));
        BgMusic = Content.Load<Song>("Music");
        Tank.LoadContent(this.Content, "Tank");
        Isis1.LoadContent(this.Content, "Isis");
        Isis2.LoadContent(this.Content, "Isis");
        Isis3.LoadContent(this.Content, "Isis");
        Isis4.LoadContent(this.Content, "Isis");
        Isis5.LoadContent(this.Content, "Isis");
        Isis6.LoadContent(this.Content, "Isis");
        Isis7.LoadContent(this.Content, "Isis");
        Isis8.LoadContent(this.Content, "Isis");
        Isis9.LoadContent(this.Content, "Isis");
        Isis10.LoadContent(this.Content, "Isis");
        Isis11.LoadContent(this.Content, "Isis");
        Sounds.BgMusic(BgMusic);
        screenWidth = GraphicsDevice.Viewport.Width;
        screenHeight = GraphicsDevice.Viewport.Height;
        // TODO: use this.Content to load your game content here
    }
    /// <summary>
    /// UnloadContent will be called once per game and is the place to unload
    /// game-specific 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)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
            Exit();
        // TODO: Add your update logic here

        //Bullet.Update(screenWidth, screenHeight, gameTime);
        MouseState mouse = Mouse.GetState();
        switch (CurrentGameState)
        {
            case GameState.MainMenu:
                if (btnPlay.isClicked == true)
                {
                    CurrentGameState = GameState.Playing;
                }
                btnPlay.Update(mouse);
                break;
            case GameState.Playing:
                Isis1.Update(screenWidth, screenHeight, gameTime);
                Isis2.Update(screenWidth, screenHeight, gameTime);
                Isis3.Update(screenWidth, screenHeight, gameTime);
                Isis4.Update(screenWidth, screenHeight, gameTime);
                Isis5.Update(screenWidth, screenHeight, gameTime);
                Isis6.Update(screenWidth, screenHeight, gameTime);
                Isis7.Update(screenWidth, screenHeight, gameTime);
                Isis8.Update(screenWidth, screenHeight, gameTime);
                Isis9.Update(screenWidth, screenHeight, gameTime);
                Isis10.Update(screenWidth, screenHeight, gameTime);
                Isis11.Update(screenWidth, screenHeight, gameTime);
                Tank.Update(screenWidth, screenHeight, gameTime);                   
                break;
        }
        //Collision
        foreach (Bullets item in Tank.bullets)
        {
            if (item.Bullethitbox.Intersects(Isis1.Box))
            {
                Isis1.LoadContent(this.Content, "DeadIsis");           
            }
        }
        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.SandyBrown);
        spriteBatch.Begin();
        switch (CurrentGameState)
        {
            case GameState.MainMenu:
                spriteBatch.Draw(Content.Load<Texture2D>("MainMenu"), new Rectangle(0, 0, 800, 600), Color.White);
                btnPlay.Draw(spriteBatch);
                break;
            case GameState.Playing:
                Tank.Draw(spriteBatch);           
                Isis1.Draw(spriteBatch);
                Isis2.Draw(spriteBatch);
                Isis3.Draw(spriteBatch);
                Isis4.Draw(spriteBatch);
                Isis5.Draw(spriteBatch);
                Isis6.Draw(spriteBatch);
                Isis7.Draw(spriteBatch);
                Isis8.Draw(spriteBatch);
                Isis9.Draw(spriteBatch);
                Isis10.Draw(spriteBatch);
                Isis11.Draw(spriteBatch);
                break;
        }
        //Bullet.Draw(spriteBatch);
        spriteBatch.End();
        // TODO: Add your drawing code here
        base.Draw(gameTime);
    }
}
}

子弹.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace IsisInvaders
{
class Bullets : Sprite
{
    private Vector2 Position;
    public Bullets(Vector2 Position) : base(Position)
    {
        this.Position = Position;
    }
    public override void Update(int screenWidth, int Screenheight, GameTime gametime)
    {
        int Pos = (int)Position.Y;
        Pos -= 10;
        Position.Y = Pos;

    }
    public override void LoadContent(ContentManager Contentman, string Spritename)
    {
        base.LoadContent(Contentman, Spritename);
        spritetext = Contentman.Load<Texture2D>("Bullet");
        //this.Box = new Rectangle((int)Position.X, (int)Position.Y, spritetext.Width, spritetext.Height);
    }
    public override void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(spritetext, Position, Color.White);
    }
    public Texture2D Bulletsprite { get { return this.spritetext; } }
    public Vector2 Bulletposition { get { return this.Position; } set { this.Position = value; } }
    public Rectangle Bullethitbox { get { return this.Box; } set { this.Box = value; } }
}
 }

坦克.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace IsisInvaders
{
class Tank : Sprite
{
    private Vector2 P;
    private KeyboardState KBS = Keyboard.GetState();
    private float bulletspeed = -400f;
    public List<Bullets> bullets = new List<Bullets>();
    private float reload = 0;
    Bullets Bullet;
    ContentManager Content;
    public Tank(Vector2 Position) : base(Position)
    {
    }
    public override void Update(int screenWidth, int Screenheight, GameTime gametime)
    {
        KBS = Keyboard.GetState();
        P = this.position;
        if (KBS.IsKeyDown(Keys.Right))
        {
            P.X += 8;
            this.position = P;
        }
        if (KBS.IsKeyDown(Keys.Left))
        {
            P.X -= 8;
            this.position = P;
        }
        reload += (float)gametime.ElapsedGameTime.TotalMilliseconds;
        if (reload >= 500 && KBS.IsKeyDown(Keys.Space))
        {
            Bullets b = new Bullets(position);
            b.LoadContent(Content, "Bullet");
            bullets.Add(b);                
            reload = 0;
        }
        foreach (Bullets item in bullets)
        {
            //item.Bullethitbox = new Rectangle((int)item.Bulletposition.X, (int)item.Bulletposition.Y, item.Bulletsprite.Width, item.Bulletsprite.Height);
            item.Update(screenWidth, Screenheight, gametime);
        }
        //for (int i = 0; i < bullets.Count; i++)
        //{
        //    float y = bullets[i].position.Y;
        //    y += bulletspeed * (float)gametime.ElapsedGameTime.TotalSeconds;
        //    bullets[i] = new Bullets(new Vector2(bullets[i].position.X, y));
        //}
    }
    public override void LoadContent(ContentManager Contentman, string Spritename)
    {
        base.LoadContent(Contentman, Spritename);
        this.Content = Contentman;
    }
    public override void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(spritetext, position, Color.White);
        foreach (Bullets b in bullets)
        {             
            b.Draw(spriteBatch);
        }
        //for (int i = 0; i < bullets.Count; i++)
        //{
        //   spriteBatch.Draw(Bullet.Bulletsprite, position, Color.White);
        //}
    }
}
}

伊希斯.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace IsisInvaders
{
class Isis : Sprite
{
    private Vector2 P;
    public Isis(Vector2 Position) : base (Position)
    {
        P = Position;
    }
    public override void Update(int screenWidth, int screenHeight, GameTime gametime)
    {
        //P.Y += (float)0.11;
        this.position = P;
        this.Box = new Rectangle((int)P.X, (int)P.Y, spritetext.Width, spritetext.Height);
    }
}
}

雪碧.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace IsisInvaders
{    
class Sprite
{
    private Texture2D SpriteTexture;
    private Rectangle Hitbox;
    private Vector2 Position;
    public Sprite(Vector2 Position)
    {
        this.Position = Position;
    }
    public virtual void Update(int screenWidth, int Screenheight, GameTime gametime)
    {
    }
    public virtual void LoadContent(ContentManager Contentman, string Spritename)
    {
        SpriteTexture = (Contentman.Load<Texture2D>(Spritename));
    }
    public virtual void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(SpriteTexture, Position, Color.White);
    }
    public Texture2D spritetext { get { return this.SpriteTexture; } set { this.SpriteTexture = value; } }
    public Vector2 position { get { return this.Position; } set { this.Position = value; } }
    public Rectangle Box { get { return new Rectangle((int)Position.X, (int)Position.Y, SpriteTexture.Width, SpriteTexture.Height); } set { this.Hitbox = value; } }
}
}

XNA子弹命中盒不会跟随精灵,从而导致碰撞问题

在你的 Bullets 类中,

你得到了一个名为 Position 的局部变量,它将在 Bullets.Update(GameTime) 中修改,但你的命中框指的是 Sprite 类中的 Position 向量。 希望有帮助。