`
ijavagos
  • 浏览: 1241676 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

【WP7进阶】——XNA游戏平面矩形碰撞检测

 
阅读更多

碰撞检测在几乎任何游戏都是很关键的一个部分,而碰撞检测又决定了游戏的流畅性,它对流畅性的影响如何之大的原因,在于碰撞检测算法越是精确到位,游戏将会运行得越缓慢。在碰撞检测方面,很明显需要在准确性和性能之间进行权衡。

实现碰撞检测最简单和快速的方式是通过包围盒算法。当用一个包围盒算法时,就需要在屏幕上的每个物体(纹理图像)周围“画“一个盒子(矩形块),然后检查这些盒子是否相交,如果产生相交(怎么听起来这么耳熟?),就即可判断出是产生碰撞了。经典的碰撞游戏可以看看如今某I设备上风靡全球的小鸟

通过物理算法和碰撞检测等实现这只小鸟欺负小猪的传说,这点是很值得借鉴滴。

本篇学习文章将会有两个纹理图,一个图片做为碰撞块例如上图的小鸟,另一个图片做为需要在某一地方去检测是否与之产生碰撞的纹理,例如上图的小猪或者城墙。这两张图片分别是这样的:

我是用来检测是否有人撞到我的。。。。。

我没事喜欢撞人。。。。。。

好了。素材己经有了,下面就到了如何为这两个纹理图像添加各种出场的告白动作了。首先,还是国际惯例一把,先给出效果图:

看上图效果,天上掉下了好多尖尖的小块呀,快逃命呀,不过小人跑不够快,被一个尖尖的小块砸到了,顿时满脸是血,屏幕都被染红了。悲催咯。。。。

要实现这个功能首先我们需要得到小人的碰撞点,和每一个三角形的碰撞点。以获得小人碰撞点为例,需要得到小人所在的x 坐标和y坐标,并且得到小人的宽度和高度。当我们获取到这个数据的时候,就可以为小人添加一个包围圈也叫矩形检测块:

//获得小人的磁撞大小和碰撞的地点
//公式为:得到小人所在的x、y地点,然后在那个x、y点的区域高宽
RectanglepersonRectangle=
newRectangle((int)personPosition.X,(int)personPosition.Y,
personTexture.Width,personTexture.Height);

当得到这个矩形块时。再依次获取得到每个三角形的矩形和其位置使用矩形自带的函数Intersects来检测两个矩形之者是否产生交接:

//与上面获得小人的碰撞点类似
RectangleblockRectangle=
newRectangle((int)blockPositions[i].X,(int)blockPositions[i].Y,
blockTexture.Width,blockTexture.Height);

//如果小人与其中某一个碰撞纹理的碰撞点产生碰撞
if(personRectangle.Intersects(blockRectangle))

personHit=true;//这时的碰撞检测将生效

如上,如果产生交接即在调用Draw 的时候改变屏幕的颜色,即可产生碰撞时的效果,DEMO源码为:

///<summary>
///Thisisthemaintypeforyourgame
///</summary>
publicclassGame1:Microsoft.Xna.Framework.Game
{
GraphicsDeviceManagergraphics;
SpriteBatchspriteBatch;
Texture2DpersonTexture;//小人纹理图像
Texture2DblockTexture;//撞击点纹理图像


//Person
Vector2personPosition;//小人2D坐标
constintPersonMoveSpeed=5;//小人移动速度

//Blocks
List<Vector2>blockPositions=newList<Vector2>();//撞击点集合
floatBlockSpawnProbability=0.1f;//控制撞击点的下降个数
constintBlockFallSpeed=10;//撞击点下降速度

Randomrandom=newRandom();

boolpersonHit=false;//是否产生碰撞

RectanglesafeBounds;
constfloatSafeAreaPortion=0.05f;
Viewportviewport;//获得当前窗口的宽高对象

publicGame1()
{
graphics=newGraphicsDeviceManager(this);
Content.RootDirectory="Content";
//Framerateis30fpsbydefaultforWindowsPhone.
TargetElapsedTime=TimeSpan.FromTicks(333333);
}

///<summary>
///Allowsthegametoperformanyinitializationitneedstobeforestartingtorun.
///Thisiswhereitcanqueryforanyrequiredservicesandloadanynon-graphic
///relatedcontent.Callingbase.Initializewillenumeratethroughanycomponents
///andinitializethemaswell.
///</summary>
protectedoverridevoidInitialize()
{
//TODO:Addyourinitializationlogichere
viewport=graphics.GraphicsDevice.Viewport;
safeBounds=newRectangle(
(int)(viewport.Width*SafeAreaPortion),//40
(int)(viewport.Height*SafeAreaPortion),//24
(int)(viewport.Width*(1-2*SafeAreaPortion)),//720
(int)(viewport.Height*(1-2*SafeAreaPortion)));//432

//Starttheplayerinthecenteralongthebottomofthescreen

base.Initialize();
}

///<summary>
///LoadContentwillbecalledoncepergameandistheplacetoload
///allofyourcontent.
///</summary>
protectedoverridevoidLoadContent()
{
spriteBatch=newSpriteBatch(GraphicsDevice);
blockTexture=Content.Load<Texture2D>("Block");
personTexture=Content.Load<Texture2D>("Person");
personPosition.X=(safeBounds.Width-personTexture.Width)/2;//小人的坐标纵向在屏幕居中
personPosition.Y=safeBounds.Height-personTexture.Height;//小人的坐标竖向在屏幕底下居中

//TODO:usethis.Contenttoloadyourgamecontenthere
}

///<summary>
///UnloadContentwillbecalledoncepergameandistheplacetounload
///allcontent.
///</summary>
protectedoverridevoidUnloadContent()
{
//TODO:UnloadanynonContentManagercontenthere
}

///<summary>
///Allowsthegametorunlogicsuchasupdatingtheworld,
///checkingforcollisions,gatheringinput,andplayingaudio.
///</summary>
///<paramname="gameTime">Providesasnapshotoftimingvalues.</param>
protectedoverridevoidUpdate(GameTimegameTime)
{
//Allowsthegametoexit
if(GamePad.GetState(PlayerIndex.One).Buttons.Back==ButtonState.Pressed)
this.Exit();

TouchCollectiontouch=TouchPanel.GetState();
if(touch.Count>0)
{
if(touch[0].Position.X>viewport.Width/2)
{
personPosition.X+=PersonMoveSpeed;
}
else
{
personPosition.X-=PersonMoveSpeed;
}
}

doubleran=random.NextDouble();
//TODO:Addyourupdatelogichere
if(ran<BlockSpawnProbability)//随机循环Double型如果随机的double小于0.01f这样做是避免产生的撞击点太多
{
floatx=(float)random.NextDouble()*//在屏幕随机出现
(graphics.GraphicsDevice.Viewport.Width-blockTexture.Width);//为了不超出屏幕
Vector2v=newVector2(x,1);
blockPositions.Add(v);
}

//获得小人的磁撞大小和碰撞的地点
//公式为:得到小人所在的x、y地点,然后在那个x、y点的区域高宽
RectanglepersonRectangle=
newRectangle((int)personPosition.X,(int)personPosition.Y,
personTexture.Width,personTexture.Height);

//Updateeachblock
personHit=false;//默认为不碰撞状态
for(inti=0;i<blockPositions.Count;i++)//循环所有在集合里面的碰撞纹理
{
//使里面的所有元素全部下降
blockPositions[i]=
newVector2(blockPositions[i].X,//X坐标不变
blockPositions[i].Y+BlockFallSpeed);//竖坐标为当前的Y座标每次加上下降的速度常量

//与上面获得小人的碰撞点类似
RectangleblockRectangle=
newRectangle((int)blockPositions[i].X,(int)blockPositions[i].Y,
blockTexture.Width,blockTexture.Height);

//如果小人与其中某一个碰撞纹理的碰撞点产生碰撞
if(personRectangle.Intersects(blockRectangle))
personHit=true;//这时的碰撞检测将生效

//如果有碰撞纹理超屏幕
if(blockPositions[i].Y>graphics.GraphicsDevice.Viewport.Height)
{
//从集合里面移出该碰撞点
blockPositions.RemoveAt(i);

//当删除了其中一个碰撞点时,下一个碰撞点的索引将跟当前移除的碰撞点是一样的,所以循环变量自动减1
i--;
}
}
base.Update(gameTime);
}

///<summary>
///Thisiscalledwhenthegameshoulddrawitself.
///</summary>
///<paramname="gameTime">Providesasnapshotoftimingvalues.</param>
protectedoverridevoidDraw(GameTimegameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
GraphicsDevicedevice=graphics.GraphicsDevice;
//TODO:Addyourdrawingcodehere
if(personHit)//当产生碰撞
{
device.Clear(Color.Red);
}
else
{
device.Clear(Color.CornflowerBlue);
}


spriteBatch.Begin();

//Drawperson
spriteBatch.Draw(personTexture,personPosition,Color.White);

//Drawblocks
foreach(Vector2blockPositioninblockPositions)
spriteBatch.Draw(blockTexture,blockPosition,Color.White);

spriteBatch.End();

base.Draw(gameTime);
}

}

轻轻松松的调用几个现成的方法和利用刷新机制就可以实现这个碰撞检测功能。当然碰撞检测还不止这么简单,还可以更详细的使用逐点检测的方法检测碰撞。

分享到:
评论

相关推荐

    xna中的碰撞检测

    在XNA这个强大的游戏开发框架中,碰撞检测是游戏编程中的关键部分,它涉及到游戏对象间的交互,确保了游戏逻辑的正确性。本资源重点讲解如何在2D环境中实现碰撞检测,这对于创建像《超级玛丽》这样的平台跳跃游戏...

    XNA物理碰撞检测代码

    总之,XNA提供的物理碰撞检测工具使开发者能够轻松地在C#环境中实现游戏中的碰撞逻辑。通过理解基本原理和适当优化,我们可以创建出更加真实的互动体验。而"TransformedCollision"可能涉及到了更高级的碰撞检测技术...

    XWinForm(XNA2.0)——XNA虚拟WinForm窗体

    XNA原本是为了游戏开发设计的,它提供了高效的游戏编程工具和环境,但不直接支持传统的Windows桌面应用程序开发,尤其是复杂的图形用户界面(GUI)。XWinForm的出现填补了这一空白,使得开发者能够利用XNA的强大功能...

    XWinForm——XNA虚拟WinForm窗体

    XNA原本是一个由微软开发的游戏开发框架,主要用于构建Windows、Xbox 360和Zune平台上的2D和3D游戏。然而,XWinForm扩展了XNA的功能,使其能够处理图形用户界面(GUI)任务,这在原始的XNA框架中是不支持的。 XNA...

    wp7 xna开发最强教程

    ### wp7 XNA开发最强教程知识点详解 #### 一、XNA概述 - **XNA含义**:XNA是微软推出的一款游戏开发框架,其中X代表跨平台(Cross-platform),N代表下一代(Next-generation),A代表架构(Architecture)。XNA的...

    XNA 游戏开发资料

    **XNA游戏开发详解** 微软的XNA游戏开发框架是一个为独立游戏开发者和学生提供的一套强大工具,它简化了游戏编程的过程,让开发者能够专注于创新和艺术创作,而不是底层技术细节。XNA的全称是"Xbox Next Generation...

    WP7 XNA游戏开发声音控制编程

    本教程将深入探讨如何在WP7 XNA游戏中进行声音控制编程。 首先,我们需要了解XNA中的声音类库。XNA提供了`Microsoft.Xna.Framework.Audio`命名空间,其中包含了`SoundEffect`和`Song`两个主要的声音类。`...

    XNA 像素级碰撞侦测的实例 2.0 3.0版本

    总的来说,XNA像素级碰撞检测实例是一个很好的学习资源,对于想要提升游戏开发技能,特别是关注游戏物理和碰撞效果的开发者来说,这是一个值得深入研究的课题。通过实践和理解这个实例,你将能够创建出具有更高交互...

    XNA 游戏编程学习总结2D与3D实现

    - 简单碰撞:矩形碰撞检测可以使用Rectangle类,计算两个矩形的重叠部分判断是否碰撞。 - 复杂碰撞:对于非矩形形状,可能需要使用像素级碰撞检测或者自定义的碰撞算法。 4. **输入处理** - KeyboardState和...

    wp xna纸牌游戏源码

    《WP XNA纸牌游戏源码深度解析》 在当今的移动应用开发领域,Windows Phone (WP) 平台以其独特的魅力吸引着开发者们。XNA框架是微软为游戏开发提供的一个强大工具,它简化了游戏开发过程,使得开发者能够专注于游戏...

    Direct 3D与XNA游戏开发源码

    5. **游戏逻辑与物理**:源码可能包含游戏对象的移动、碰撞检测、角色控制和游戏规则的实现。这涉及编程逻辑和可能的物理引擎集成。 6. **声音与音频**:XNA支持音频播放,源码可能涵盖如何添加背景音乐、音效,...

    wp7 xna 投石车大战源码

    【标题】"wp7 xna 投石车大战源码"是针对Windows Phone 7平台的一个游戏开发示例,利用XNA框架构建。这个源码项目对于初学者来说是一个很好的起点,因为它涵盖了XNA框架的基本要素,可以帮助开发者快速掌握XNA编程的...

    XNA小游戏(是男人就坚持一百秒)

    【XNA小游戏——“是男人就坚持一百秒”】是一个基于微软XNA框架开发的趣味游戏,它挑战玩家的反应速度和耐力。XNA是一个为游戏开发者提供的一套工具和框架,允许开发者使用C#编程语言来创建跨平台的游戏,包括...

    XNA游戏示例代码

    7. **物理和碰撞检测**: 虽然XNA本身不包含物理引擎,但开发者可以使用第三方库(如Farseer Physics Engine)或自定义算法实现简单的物理效果和碰撞检测。 总的来说,这个XNA游戏示例代码提供了一个基础的游戏...

    xna游戏案例集合

    6. **碰撞检测和物理模拟**:在游戏开发中,四元数也可以用于优化碰撞检测算法,通过计算两个物体的旋转状态来预测它们的碰撞可能性。此外,四元数在物理引擎中也有广泛应用,帮助模拟真实的物理行为。 7. **学习...

    xna游戏快速入门框架

    - **碰撞检测**:理解基本的几何碰撞检测算法,以便在游戏中实现物体间的交互。 - **物理模拟**:简单物理规则的实现,如重力、摩擦力等。 - **游戏状态管理**:如何在不同游戏状态(如主菜单、游戏进行中、游戏结束...

    XNA游戏源代码开发(c#)

    2. 碰撞检测:在台球游戏中,球与球、球与边界之间的碰撞检测至关重要。这通常涉及到几何形状的交集测试,如圆形和直线的碰撞检测。 3. 图形渲染:每个球的2D或3D表示,以及台面、标记线等元素的绘制,都需要利用...

    6个WP7小游戏

    5. **碰撞检测**:理解如何检测游戏对象之间的碰撞,并作出相应反应。 6. **图形和动画**:掌握创建2D图形、精灵动画和粒子效果的方法。 7. **声音和音乐**:学习如何播放和控制游戏的音效和背景音乐。 8. **游戏...

    XNA 游戏实例(简单实现)

    8. **物理引擎**:虽然XNA本身并不包含内置的物理引擎,但可以集成第三方库如Farseer Physics Engine,为游戏添加物理模拟功能,如重力、碰撞检测等。 9. **网络编程**:XNA也支持网络游戏的开发,可以实现多人在线...

Global site tag (gtag.js) - Google Analytics