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