跟我一起学XNA(3)让移动物体撞起来(附源码)

上一章用两种方法加载了 运动图片,图片跟随鼠标走
xna可以放到wp7 xbox上,这次简单的碰撞就用键盘的上下左右四个键控制上下左右,直到碰撞完成。
加载了两个静态图片,一个苹果和一个香蕉,是之前用wpf写消消看时候自己做的,这时候就拿来用用,香蕉自动移动,苹果用户可以用键盘控制

        SpriteBatch spriteBatch;

        //一个随意移动的物体

        Texture2D moveObject;

        //移动物体的位置

        Vector2 moveVector=Vector2.Zero;



        //自己控制的物体

        Texture2D selfControl;

        //自己控制物体的位置

        Vector2 selfVector=new Vector2(150,150);

        //移动物体的速度

        float moveSpeed = 0.5f;

        //自己的速度

        float selfSpeed = 2f;

        SpriteFont font;

        //判断是否已经碰撞上

        bool isCollide = false;

定义了几个个简单变量,两个图片,两个图片记录位置,图片背景色是白色,看起来会更清晰一些,敌人的速度要慢一些,自己的速度要快一些
然后我们新建一个Font文件夹,里面添加一个

类型的文件,我命名为FishFont,记载的时候加载上,Font是为了在界面上画图

  protected override void LoadContent()

        {

            // Create a new SpriteBatch, which can be used to draw textures.

            spriteBatch = new SpriteBatch(GraphicsDevice);

            moveObject = Content.Load<Texture2D>(@"Image/7");

            selfControl = Content.Load<Texture2D>(@"Image/3");

            font = Content.Load<SpriteFont>(@"Font/FishFont");

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

        }

Draw函数:
碰撞的原理是 用两个方框包裹住图片,判断图片是否有交集

       protected override void Draw(GameTime gameTime)

        {

            GraphicsDevice.Clear(Color.CornflowerBlue);



            // TODO: Add your drawing code here

            spriteBatch.Begin();

            spriteBatch.Draw(moveObject, moveVector, null, Color.White);

            spriteBatch.Draw(selfControl, selfVector, null, Color.White);

            if (Collide())

            {

                spriteBatch.DrawString(font, "Collided",

new Vector2(10, 10), Color.DarkBlue, 0, Vector2.Zero,

1, SpriteEffects.None, 1);

                isCollide = true;

            }

            spriteBatch.End();

            base.Draw(gameTime);

        }



        protected bool Collide()

        {

            //方框的四个坐标,64是图片的长,70是图片的高

            Rectangle ringsRect = new Rectangle((int)moveVector.X,

            (int)moveVector.Y, 64, 70);

            Rectangle skullRect = new Rectangle((int)selfVector.X,

            (int)selfVector.Y, 64, 70);

            return ringsRect.Intersects(skullRect);

        }

Update函数

   protected override void Update(GameTime gameTime)

        {

            // Allows the game to exit

            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)

                this.Exit();



            // TODO: Add your update logic here

            if (!isCollide)

            {

                //让物体移动

                moveVector.X += moveSpeed;

                moveVector.Y += moveSpeed;

                //键盘控制

                KeyboardState keyboardState = Keyboard.GetState();

                if (keyboardState.IsKeyDown(Keys.Left))

                    selfVector.X -= selfSpeed;

                if (keyboardState.IsKeyDown(Keys.Right))

                    selfVector.X += selfSpeed;

                if (keyboardState.IsKeyDown(Keys.Up))

                    selfVector.Y -= selfSpeed;

                if (keyboardState.IsKeyDown(Keys.Down))

                    selfVector.Y += selfSpeed;

            }

            base.Update(gameTime);

        }

运行,


苹果和香蕉碰撞的时候就会有提示,然后变量让update不运作了,这个时候已经达到碰撞的目的了,但是还不够!
香蕉图片只是用一个变量递增,它会一直往下走,直到走出图片我想要的是这样的东西

香蕉遇到边界自动判断方向,或者香蕉自动去找苹果去碰撞,香蕉跟随苹果,想要这样的效果,那我们继续修改,
首先第一种:
我们需要一个记录上一个位置的坐标

    //移动物体的上一个位置

        Vector2 movePreVector = Vector2.Zero;

然后增加一个函数

  private void BananaMoveFirst()

        {

            if (moveVector.X >= Window.ClientBounds.Width - 64 || moveVector.X < 0) moveXSpeed = -moveXSpeed;

            if (moveVector.Y >= Window.ClientBounds.Height - 70 || moveVector.Y < 0) moveYSpeed = -moveYSpeed;



            movePreVector.X = moveVector.X;

            movePreVector.Y = moveVector.Y;



            moveVector.X += moveXSpeed;

            moveVector.Y += moveYSpeed;

        }

通过判断来控制物体
第二种:
香蕉根据苹果的位置来移动,这个我竟然忘了给你两个坐标如何求出a,b,c三条边的长度和它们之间的夹角了,直接google了,不是数学没用,是没有用到,无法淡定了

        private void BananaMoveSecend()

        {

            float c = (float)Math.Sqrt((selfVector.X - moveVector.X) * (selfVector.X - moveVector.X) + (selfVector.Y - moveVector.Y) * (selfVector.Y - moveVector.Y));

            float x = (selfVector.X - moveVector.X);

            float y = (selfVector.Y - moveVector.Y);

            moveVector.X += moveXSpeed * (x / c);

            moveVector.Y += moveYSpeed * (y / c);

        }

好了,这样看起来还是比较靠谱的,总之看起来不会是那么山寨了,这也只是简单的碰撞,判断不精确,当然坐标判断也是极为简单的一种


源代码:files.cnblogs.com/fish124423/XNA.rar

你可能感兴趣的:(源码)