跟我一起学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

posted @ 2012-10-29 09:54  爱喝可乐  阅读(1373)  评论(1编辑  收藏  举报