`

XNA中关于2D图形像素碰撞

 
阅读更多

下面所介绍的例子是微软官方的一个例子,这里给出下载XNA官方2D像素碰撞例子的链接。

     在这个例子中没有涉及到什么新鲜的技术,主要是利用提取图像的像素,然后根据两张图像画布相交的范围构造一个小范围的矩形框,之后遍历此矩形框中的每一个像素点,判断当前遍历到的像素点的alpha值是否为零,若两张图片同一个像素点的alpha值同时不为零,则两张图片碰撞,反之则没有进行碰撞。好了,不罗嗦了,下面就展开介绍一下这个例子吧。

     这个例子比较简单,没有自己封装类,所有功能都是在PerPixelCollisionGame类中实现的,该类继承Game类。

     首先是定义一些常用的变量,这里找了几个主要的变量列了出来:

// 将要渲染的图片,一张是小人,一张是三角块
Texture2D personTexture;
Texture2D blockTexture;

// 这两个数组像素是用来存储小人的图片像素和三角块的图片像素
Color[] personTextureData;
Color[] blockTextureData;

//小人的坐标
Vector2 personPosition;

//小人的移动速度
const int PersonMoveSpeed = 5;

//创建一个坐标链表记录每一个三角块儿的坐标
List<Vector2> blockPositions = new List<Vector2>();

// 检测是否碰撞
bool personHit = false;

     下面就是PerPixelCollisionGame类的构造函数,在这个构造函数中主要是定义了小人的初始位置,并且为了不让小人跑出我们的视线,特意定义了一个所谓的安全边框即safeBounds

protected override void Initialize()
        {
            base.Initialize();
            Viewport viewport = graphics.GraphicsDevice.Viewport;
            safeBounds = new Rectangle(
                (int)(viewport.Width * SafeAreaPortion),
                (int)(viewport.Height * SafeAreaPortion),
                (int)(viewport.Width * (1 - 2 * SafeAreaPortion)),
                (int)(viewport.Height * (1 - 2 * SafeAreaPortion)));

            personPosition.X = (safeBounds.Width - personTexture.Width) / 2;
            personPosition.Y = safeBounds.Height - personTexture.Height;
        }

     接下来是加载所用到的图像,这里没有什么好说的

       /// <summary>
       /// 加载图像资源
       /// </summary>
       protected override void LoadContent()
       {
           // 加载图片,包括小人和三角块
           blockTexture = Content.Load<Texture2D>("Block");
           personTexture = Content.Load<Texture2D>("Person");

           //初始化三角块儿的像素数组大小
           blockTextureData =
               new Color[blockTexture.Width * blockTexture.Height];
           // 提取三角块图片像素
           blockTexture.GetData(blockTextureData);

           ///初始化小人的像素数组大小
           personTextureData =
               new Color[personTexture.Width * personTexture.Height];
           //提取小人图片像素
           personTexture.GetData(personTextureData);

           // 增加一个精灵画刷来渲染图片
           spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
       }

      接下来是PerPixelCollisionGame类的Update方法,在这个方法中前半部分是对键盘输入的检测,以此来控制小人儿的左移和右移。接下来是随机生成一个三角块的初始位置,并把此位置添加到名为blockPositions的坐标链表中。其中personRectangle是定义了包含小人的一个矩形框,这个矩形框的宽度和高度是这个小人图片宽度和高度(其本质是图片画布的宽度和高度)。再接下来的这个for语句是这个例子的关键,不停的遍历整个三角块儿链表,判断是否有三角块与小人有像素碰撞,若有personHit返回true,否则返回false,这个for语句中的IntersectPixels方法实现了两个图片的像素碰撞功能,下面重点讨论一下这个方法:

                                           像素碰撞示意图

                    上图是两张图片相交构成的一个小矩形框(中间红色部分)

         static bool IntersectPixels(Rectangle rectangleA, Color[] dataA,
                                    Rectangle rectangleB, Color[] dataB)
        {
            // 根据两个矩形框相交而形成的一个小的矩形范围
            int top = Math.Max(rectangleA.Top, rectangleB.Top);
            int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
            int left = Math.Max(rectangleA.Left, rectangleB.Left);
            int right = Math.Min(rectangleA.Right, rectangleB.Right);

            // 在这个小矩形框范围内从上倒下,从左到右检查每一个像素点的值,
            //并判断每一个像素点上两张图片的alpha的值是否同时等于零,以此来判
            //断两张图片是否产生像素碰撞
           for (int y = top; y < bottom; y++)

           {
               for (int x = left; x < right; x++)
               {
                   // 在同一点上获取两张图片的像素值
                   Color colorA = dataA[(x - rectangleA.Left) +
                                        (y - rectangleA.Top) * rectangleA.Width];
                   Color colorB = dataB[(x - rectangleB.Left) +
                                        (y - rectangleB.Top) * rectangleB.Width];

                   // 判断两张图片在同一像素点上alpha值是否同时为零
                   if (colorA.A != 0 && colorB.A != 0)
                   {
                       //相碰撞,返回真
                       return true;
                   }
               }
           }
           //没有碰撞,返回假
           return false;

       }

最后剩下渲染部分了:

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice device = graphics.GraphicsDevice;

    // 若personHit为真值,则屏幕背景颜色改为红色,否则为矢车菊蓝色
    if (personHit)
    {
        device.Clear(Color.Red);
    }
    else
    {
        device.Clear(Color.CornflowerBlue);
    }

    spriteBatch.Begin();

    // 渲染小人                                                                                              spriteBatch.Draw(personTexture, personPosition, Color.White);

   // 渲染三角块的坐标链表渲染链表中的每一个三角块
    foreach (Vector2 blockPosition in blockPositions)
    spriteBatch.Draw(blockTexture, blockPosition, Color.White);

 

    spriteBatch.End();

    base.Draw(gameTime);
}

至此这个例子也就完成了,其中最重要的部分就是IntersectPixels方法了,这个方法完成了两张图片的像素碰撞的功能,这个例子的本质也就是判断两个图片相交的画布部分的alpha值,如果同时不为零就代表碰撞,反之则没有碰撞。

分享到:
评论

相关推荐

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

    此外,XNA Framework提供了SpriteBatch和SpriteFont等类,方便开发者绘制2D图形和文本,同时还有Matrix和Vector2等数学结构,帮助处理几何变换和碰撞计算。通过这个实例,你不仅能掌握像素级碰撞检测,还能加深对XNA...

    C# XnaGame2D源代码

    7. **碰撞检测**:在2D游戏中,碰撞检测是常见的功能,可以通过矩形碰撞、像素级碰撞等多种方式实现。理解如何有效地检测和处理物体间的碰撞是游戏逻辑的重要组成部分。 8. **游戏状态管理**:大型游戏往往需要管理...

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

    在“XNA游戏编程学习总结2D与3D实现-2D源码”中,我们可以深入探讨XNA在2D游戏开发中的应用。 1. **XNA框架基础** - XNA框架包含了Game类:它是所有游戏项目的基础,包含了游戏循环、渲染、更新等核心功能。 - ...

    XNA微软例子

    【XNA微软例子】是一个关于使用微软XNA框架开发游戏或图形应用的示例项目,主要涉及如何通过图像数据来创建游戏中的地形,并且自定义导入器以扩展功能。在这个项目中,我们可以深入学习以下几个关键知识点: 1. **...

    2D Pong using the Microsoft XNA Framework

    在本教程中,我们将探讨如何使用Microsoft XNA Framework Beta 1.1开发一款经典的2D乒乓球游戏(Pong)。这个框架提供了一套完整的工具和库,使得开发2D和3D游戏变得更加简单。首先,我们需要了解XNA Framework的...

    2D XNA Primitive Shapes Library-开源

    在实际应用中,2D XNA Primitive Shapes Library不仅可以用于游戏开发,还可以用于教学、实验以及各种2D图形相关的软件开发。通过这个库,开发者可以专注于创造有趣的游戏内容,而无需花费大量时间在底层图形渲染的...

    Direct 3D与XNA游戏开发源码

    在"Direct 3D与XNA游戏开发源码"这个资源中,你可能会发现以下几个关键知识点: 1. **Direct 3D基础**:源码可能包含关于Direct 3D的基本概念,如设备初始化、顶点缓冲区、索引缓冲区、纹理映射、光照和投影设置等...

    xna Game studio 小游戏源码

    2. 碰撞检测:在2D游戏中,碰撞检测通常是通过矩形或像素级别的比较实现。在3D游戏中,可能涉及到更复杂的几何形状碰撞。 3. 角色动画:XNA提供了SpriteBatch类来处理2D精灵的绘制,通过改变精灵的位置、旋转和缩放...

    PerPixelCollision

    在本教程中,你将学习到如何利用XNA的图形管线来实现像素级碰撞检测。首先,你需要理解XNA的基本概念,如SpriteBatch和Texture2D,这些是绘制游戏元素的关键类。然后,你将学习如何加载并显示纹理,这是进行碰撞检测...

    XNA高级编程:Xbox 360和Windows

    XNA是由微软推出的游戏开发框架,它简化了游戏编程的过程,尤其适合在Xbox 360和Windows平台上构建2D和3D游戏。 首先,第一章“XNA介绍”会详细阐述XNA的基本概念、发展历程以及其在游戏开发中的重要地位。读者将...

    XNA Learning

    在XNA中,可以使用HLSL语言编写顶点着色器和像素着色器。飞车游戏的源代码中可能包含自定义的着色器来增强游戏视觉效果。 **学习资源与代码分析** 飞车游戏的源代码是学习XNA的好材料,提供了实际的游戏开发经验。...

    xna program recipes

    - XNA提供了多种服务,如图形、音频、输入等。 - 通过`Game.Services`获取服务实例。 - **数据保存与读取**: - 使用`IsolatedStorageFile`类来保存和读取数据。 - 示例:`IsolatedStorageFile isoStore = ...

    Building.XNA.2.0.Games.A.Practical.for.Independent.Game.Development

    - **着色器支持**:XNA 2.0支持编写顶点和像素着色器,这为开发者提供了更多控制图形细节的机会。 3. **音频与声音效果**: - **音频处理**:XNA支持多种音频格式,并提供了强大的音频处理功能,包括音效合成、...

    Direct 3D与XNA游戏开发例子

    此外,Direct 3D中的着色器系统(包括顶点着色器和像素着色器)允许开发者自定义图形处理的计算过程,实现复杂的视觉效果。 XNA则建立在Direct 3D之上,提供了一个更高层次的抽象,让开发者可以专注于游戏逻辑而...

    XNA 俄罗斯方块

    2. **图形渲染**:XNA提供了`SpriteBatch`类来绘制2D图形,如游戏中的方块和背景。通过使用纹理和坐标系统,我们可以控制方块的显示位置和样式。 3. **几何变换**:理解如何应用旋转、平移和缩放等变换,以实现方块...

    C#二维、三维图形开发(3)

    这些API允许开发者直接在窗口上进行像素级别的操作,实现复杂的2D图形设计。 对于三维图形,C#引入了DirectX和.NET Framework的Microsoft.Xna库,以及Unity 3D这样的游戏引擎。在WPF中,`System.Windows.Media....

    Microsoft XNA Game Studio 3.0 源代码下载 part3

    - **SpriteBatch**:用于2D图形渲染,支持纹理、颜色和旋转等效果。 - **Effect和Shader**:提供对3D图形的高级控制,通过顶点着色器和像素着色器实现复杂的光照和纹理效果。 2. **C#在XNA中的应用** - **类与...

    C#实现飞机大战源码

    这涉及到C#中的图形API,如Unity中的Sprite Renderer或者XNA中的SpriteBatch,它们用于将2D图像渲染到屏幕上。 5. **碰撞检测**:为了判断飞机之间、子弹与敌机的碰撞,源码中会包含碰撞检测算法。常见的方法有矩形...

    C#做FC坦克大战

    首先,我们要明白FC坦克大战是一款基于2D图形的策略射击游戏,玩家需要控制坦克,通过障碍物,击败敌方坦克,保护基地。在C#中实现这个游戏,我们需要用到的主要技术包括Windows Forms或WPF来构建用户界面,以及使用...

Global site tag (gtag.js) - Google Analytics