XNA Sprite碰撞类部分无法正常工作

时间:2013-04-12 18:46:36

标签: xna-4.0 collision sprite

编辑:精灵正在努力。现在它只是遇到了一些连续碰撞的问题。

所以我有一个像素精灵碰撞类,它可以部分工作,但只能在右边工作。试图向左移动导致总是发生碰撞。这是班级本身。

  public Boolean collision(Texture2D first, Vector2 position1, Texture2D second, Vector2 position2)
    {

        //gets the bounds of the two sprites
        FirstBounds = new Rectangle((int)(position1.X),
        (int)(position1.Y), first.Width, first.Height);

        SecondBounds = new Rectangle((int)(position2.X),
        (int)(position2.Y), second.Width, second.Height);

        //if they intersect.
            if (FirstBounds.Intersects(SecondBounds))
            {

            Color[] DataA = new Color[first.Width * first.Height];
            first.GetData(DataA);

            Color[] DataB = new Color[second.Width * second.Height];
            second.GetData(DataB);

            int Top = System.Math.Max(FirstBounds.Top, SecondBounds.Top);
            int Bottom = System.Math.Min(FirstBounds.Bottom, SecondBounds.Bottom);
            int Left = System.Math.Max(FirstBounds.Left, SecondBounds.Left);
            int Right = System.Math.Min(FirstBounds.Right, SecondBounds.Right);

            for (int y = Top; y < Bottom; y++)
            {
                for (int x = Left; x < Right; x++)
                {
                    Color ColorA = DataA[(x - FirstBounds.Left) + (y - FirstBounds.Top) * FirstBounds.Width];
                    Color ColorB = DataB[(x - SecondBounds.Left) + (y - SecondBounds.Top) * SecondBounds.Width];

                    if (ColorA.A > 0 && ColorB.A > 0)
                    {
                        return true;
                    }

                }



            }

            return false;
            }








        return false;

    }

这是我正在使用的整个类的代码,是的,它是主类。

/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{

    // all graphics classes.
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    private AnimatedSprite animatedSprite;
    private AnimatedSprite background2;
    private AnimatedSprite Zero;
    private KeyboardState oldState;
    //starting place for Zero
    Vector2 lol = new Vector2(100, 200);

    Vector2 ground2 = new Vector2(0, 0);
    Vector2 ground = new Vector2(0, 0);
    Boolean jumping = false;

    Texture2D firstback;
    Texture2D texture2;
    Texture2D secondback;


   public Rectangle FirstBounds;
   public Rectangle SecondBounds;


    //Variables
    int timer = 0; //checks if it should update, helps to delay the update process.
    int jumptimer = 0;//uses as a timer for the amount of time you get to jump.
    int jumpanimation = 0;

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

    protected override void Initialize()
    {
        base.Initialize();
    }

    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);

        firstback = Content.Load<Texture2D>("Tester");
        animatedSprite = new AnimatedSprite(firstback, 1, 1);

        secondback = Content.Load<Texture2D>("Tester2");
        background2 = new AnimatedSprite(secondback, 1, 1);

        //Creates the sprite for Zero, the main character.
        texture2 = Content.Load<Texture2D>("ZeroIdle");
        Zero = new AnimatedSprite(texture2, 1, 8);

        ground2 = new Vector2(ground.X + firstback.Width, 0);



    }

    protected override void UnloadContent()
    {
    }



    //Collision, took forever to figure out.
    public Boolean collision(Texture2D first, Vector2 position1, Texture2D second, Vector2 position2)
    {

        //gets the bounds of the two sprites
        FirstBounds = new Rectangle((int)(position1.X),
        (int)(position1.Y), first.Width, first.Height);

        SecondBounds = new Rectangle((int)(position2.X),
        (int)(position2.Y), second.Width, second.Height);

        //if they intersect.
            if (FirstBounds.Intersects(SecondBounds))
            {

            Color[] DataA = new Color[first.Width * first.Height];
            first.GetData(DataA);

            Color[] DataB = new Color[second.Width * second.Height];
            second.GetData(DataB);

            int Top = System.Math.Max(FirstBounds.Top, SecondBounds.Top);
            int Bottom = System.Math.Min(FirstBounds.Bottom, SecondBounds.Bottom);
            int Left = System.Math.Max(FirstBounds.Left, SecondBounds.Left);
            int Right = System.Math.Min(FirstBounds.Right, SecondBounds.Right);

            for (int y = Top; y < Bottom; y++)
            {
                for (int x = Left; x < Right; x++)
                {
                    Color ColorA = DataA[(x - FirstBounds.Left) + (y - FirstBounds.Top) * FirstBounds.Width];
                    Color ColorB = DataB[(x - SecondBounds.Left) + (y - SecondBounds.Top) * SecondBounds.Width];

                    if (ColorA.A > 0 && ColorB.A > 0)
                    {
                        return true;
                    }

                }

            }

            return false;
            }





        return false;

    }



    protected override void Update(GameTime gameTime)
    {


        KeyboardState state = Keyboard.GetState();



        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        //checks indivdual keystates, starts with if keys are down.






        if (state.IsKeyDown(Keys.Right) && state.IsKeyUp(Keys.Left))
        {



            if (state.IsKeyDown(Keys.Up))
            {



                //Makes it impossible to double jump. You need to wait until you finished your jump to jump again.

                if (oldState.IsKeyUp(Keys.Up) && jumping == false && (collision(firstback, ground, texture2, lol) == true || collision(secondback, ground2, texture2, lol) == true))
                {
                    texture2 = Content.Load<Texture2D>("ZeroJump");
                    Zero = new AnimatedSprite(texture2, 1, 14);
                    jumping = true;

                }
        }



            //checks to see if you've released the right key. Makes the game update properly.
            if (oldState.IsKeyUp(Keys.Right) && jumping == false && (collision(firstback, ground, texture2, lol) == true || collision(secondback, ground2, texture2, lol) == true))
            {
                texture2 = Content.Load<Texture2D>("ZeroRunning");
                Zero = new AnimatedSprite(texture2, 1, 11);

            }



            oldState = state;



            //Causes a delay to make sure Zero updates properly and not at 60 times per second.
            if (timer >=3)
            {





                //moves Zero.
                Vector2 adding = new Vector2(5, 0);
                lol = Vector2.Add(lol, adding);
                Zero.Update();




                timer = 0;
            }

            else
                timer++;

            Vector2 aSpeed = new Vector2(-5, 0);
            ground = Vector2.Add(ground, aSpeed);
            ground2 = Vector2.Add(ground2, aSpeed);
        }




        else if (state.IsKeyDown(Keys.Left) && state.IsKeyUp(Keys.Right))
        {



            if (state.IsKeyDown(Keys.Up))
            {



                //Makes it impossible to double jump. You need to wait until you finished your jump to jump again.

                if (oldState.IsKeyUp(Keys.Up) && jumping == false && (collision(firstback, ground, texture2, lol) == true || collision(secondback, ground2, texture2, lol) == true))
                {
                    texture2 = Content.Load<Texture2D>("ZeroJump");
                    Zero = new AnimatedSprite(texture2, 1, 14);
                    jumping = true;

                }

            }




            //checks to see if you've released the right key. Makes the game update properly.

            if (oldState.IsKeyUp(Keys.Left) && jumping == false && (collision(firstback, ground, texture2, lol) == true || collision(secondback, ground2, texture2, lol) == true))
            {
                texture2 = Content.Load<Texture2D>("ZeroRunningLeft");
                Zero = new AnimatedSprite(texture2, 1, 11);

            }

            oldState = state;


            //causes a delay in updating so Zero animates properly.
            if (timer >= 3)
            {
                //actually moves Zero.
                Vector2 adding = new Vector2(-5, 0);
                lol = Vector2.Add(lol, adding);
                Zero.Update();




                timer = 0;
            }



            else
                timer++;

                Vector2 aSpeed = new Vector2(5, 0);
                ground = Vector2.Add(ground, aSpeed);
                ground2 = Vector2.Add(ground2, aSpeed);
        }


        //Jumping State.
        if (state.IsKeyDown(Keys.Up))
        {



            //Makes it impossible to double jump. You need to wait until you finished your jump to jump again.

            if (oldState.IsKeyUp(Keys.Up) && jumping == false && (collision(firstback, ground, texture2, lol) == true || collision(secondback, ground2, texture2, lol) == true))
            {
                texture2 = Content.Load<Texture2D>("ZeroJump");
                Zero = new AnimatedSprite(texture2, 1, 14); 
                jumping = true;

            }



            oldState = state;




        }




        //Section that checks if the keys are up.

        if (state.IsKeyUp(Keys.Left) && state.IsKeyUp(Keys.Right) && jumping == false && (collision(firstback, ground, texture2, lol) == true || collision(secondback, ground2, texture2, lol) == true))
        {
            texture2 = Content.Load<Texture2D>("ZeroIdle");
            Zero = new AnimatedSprite(texture2, 1, 8);
            timer = 0;
            oldState = (new KeyboardState());
        }





        //Gravity effects and updates.

        if (jumping == true)
        {                
                Vector2 adding = new Vector2(0, -5);
                lol = Vector2.Add(lol, adding);

                //times the animation.
                if (jumpanimation >= 5)
                {

                    Zero.Update();
                    jumpanimation = 0;

                }

                else
                    jumpanimation++;

                jumptimer++;

                if (jumptimer >= 30)
                {
                    jumping = false;
                    jumptimer = 0;

                    //whenever the timer has expired.
                    if (collision(firstback, ground, texture2, lol) == false)
                    {
                        texture2 = Content.Load<Texture2D>("ZeroFalling");
                        Zero = new AnimatedSprite(texture2, 1, 4);
                    }


                    oldState = (new KeyboardState());

                }


        }

        else
        {
            if (collision(firstback, ground, texture2, lol) == false && collision(secondback, ground2, texture2, lol) == false)
            {
                Vector2 adding = new Vector2(0, 5);
                lol = Vector2.Add(lol, adding);
            }

            else if ((collision(firstback, ground, texture2, lol) == true || collision(secondback, ground2, texture2, lol) == true) == true && texture2 == Content.Load<Texture2D>("ZeroFalling"))
                oldState = (new KeyboardState());



        }


        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);


        background2.Draw(spriteBatch, ground2);
        Zero.Draw(spriteBatch, lol);
        animatedSprite.Draw(spriteBatch, ground);

        base.Draw(gameTime);



    }

}

}

我不完全确定出了什么问题,感谢任何帮助。非常感谢你!

1 个答案:

答案 0 :(得分:0)

您拥有的所有内容看起来都是正确的,因此问题可能出在其他地方,例如,位置更新太晚或太快。还有更多要发布的代码吗?

我会推荐以下教程:

http://xbox.create.msdn.com/en-US/education/tutorial/2dgame/getting_started

它将有助于正确设置动画类,因此正在使用适当的帧进行检测。