Chinaunix首页 | 论坛 | 博客
  • 博客访问: 581681
  • 博文数量: 208
  • 博客积分: 3286
  • 博客等级: 中校
  • 技术积分: 1780
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-24 20:38
文章分类

全部博文(208)

文章存档

2012年(7)

2011年(28)

2010年(21)

2009年(76)

2008年(65)

2007年(11)

我的朋友

分类: C/C++

2008-02-25 12:24:07

第一个XNA游戏,

Initialize 方法可以在没有初始化图形设备的时候初始化在程序中用到的资源。 LoadContent 方法用来装载程序中用到的资源。包括一些模型和纹理。

UnLoadContent 方法用来释放资源。自动的。不需要额外的代码。

Updata 重要的方法! 添加对象。处理用户输入,决定对象间的接触结果,等等。

Draw 方法用来在屏幕上绘制所有的对象和背景。即所有想给用户看到的东西。

 

添加一个精灵(Sprite)

什么是Sprite? Sprite,也称为精灵,是一个直接绘制到屏幕上的2D图形。在传统的2D游戏中,你所看到的一切几乎都是sprite。但在3D游戏中,比如Halo,sprite逐渐演变为了用于增加3D图形视觉效果的纹理。在讨论3D图形时我们会详细讲解它。现在,简单的把sprite认为是2D图形就可以了。

Soulation Explor-->Content-->右键Add-->Existing Item 找到要添加到图片,

 Texture2D myTexture;

Vector2D spritePosition = new Vector2D.zero;

protected override void LoadContent()

 { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); myTexture = Content.Load("mytexture");

}

spriteBatch.Draw(myTexture, spritePosition, Color.White);

同样的方法可以添加一个,二个,多个Sprite。

spriteBatch.Draw(myTexture2,spritePosition, Color.White);

…………

spriteBatch.Begin();

spriteBatch.End();

想解决的是Sprite之间的碰撞问题,(Collision Detection )

XNA提供几种解决方案,

一、 Bounding Sphere,一个圆形区域的碰撞检测,

圆形和圆形的碰撞检测十分迅速,只需要判断圆心和半径,如果两个Sprite的中心点距离等于各自半径的和,就判定为产生交叉,发生了碰撞。

而且存储结构比较小,存储几个向量表示中心和半径。

如果Sprite发生了旋转,不用重新绘制(改造recreate)。 移动圆形Bounding比较容易,只需要修改圆心即可。

缺点在于计算机图形中没有完美的圆形。。。。。

二、 Bouning Box,矩形区域的碰撞检测

 矩形空间是一个与x,y,z轴垂直或者平行,判断2个BoundingBox的碰撞比判断一个BoundingBox的旋转更加迅速。

旋转boundingBox导致不再与坐标轴平行,需要重新绘制(recreate),物体的所有的点都要重新绘制,慢~。

如果物体没有改变orientation,只需要平移BoundingBox即可。

物体旋转会导致BoundingBox出现很多空白区域,空白区域会导致碰撞的错误判定。

 

三、 Bounding Frustum (平截头体:切割立体的两个平面之间的立体的一部分,如圆柱体或角锥,尤指与底边平行的底边或平面间的部分)

 这个并不是用来检测碰撞,而是用来确定物体是不是在可视范围内,不在范围内的不绘制,可以节省很多工作。 根据Camera的区域来显示物体。

四、 Non-Bounding Volume Classes

a、Plane 描述空间的一个平面,定义为垂直与平面的向量和在向量上的一些点的集合,Plane支持与BoundingVolume的交集测试,返回值是Plane相对于BoundingVolume的位置,可以用来判定plane在BoundingVolume的前面还是后面。

 b、Ray 描述空间的一束光线。定义的光源位置,支持与BoundingVolume的交集测试,返回值是Ray光源与BoundingVolume的距离。null为没有与BoundingVolme相交。

 c、 model 除去绘制model的基本信息,model的部件(part)还包含一个BoundingVolume。在导入一个model的同时,content pipeline为model的每个部件(par)计算一个Bounding Sphere,可以用BoundingSphere的方式来计算model的碰撞。

 

contains and intersects methods

BoundingVolume class 指出两种测试方法,intersection test 和 containment test。

intersection test 用各种方法来检测是否有重叠,不返回交叉的度数。

containment test 用来判断是交叉还是一个被另一个包含,并且交叉的时候需要度数的时候使用containment test。

 

补充:
使用boundingbox,可以新建一个类,比如Sprite。把boundingbox当类的变量来用,方便一点。
另一个方式就需要写很长的代码来检测,
 
 boundingBox = new BoundingBox(
         new Vector3(position.X, position.Y, 0), // Left, Top, Front. For 2D, Front  = 0
         new Vector3(position.X + texture.Width, position.Y + texture.Height, 0)  // Right, Bottom, Back. Back = 0
         );
 
BoundingBox1.Intersects(BoundingBox2)

 

//下面实例

struct Cube
        {
            public Vector3 position;
            public Vector3 velocity;
            public BoundingBox bb;
            public Vector3 lastPosition;
            public void MoveForward()
            {
                lastPosition = position;
                position += velocity;
                bb.Min += velocity;
                bb.Max += velocity;
            }
            public void Backup()
            {
                //position = lastPosition;
                position -= velocity;
                bb.Min -= velocity;
                bb.Max -= velocity;
            }
            public void ReverseVelocity()
            {
                velocity.X = -velocity.X;
            }
        }

void CheckForCollisions(ref Cube c1, ref Cube c2)
        {
            bool collision = false;

            // Check whether the bounding boxes of the two cubes intersect.
            if (c1.bb.Intersects(c2.bb))
            {
                collision = true;
                c2.ReverseVelocity();
            }

            // Check whether the moving cube intersects or has passed through the right plane.
            if (c1.bb.Intersects(new Plane(new Vector3(1, 0, 0), 10)) != PlaneIntersectionType.Front)
            {
                collision = true;
            }

            // Check whether the moving cube intersects or has passed through the left plane.
            if (c1.bb.Intersects(new Plane(new Vector3(-1, 0, 0), 10)) != PlaneIntersectionType.Front)
            {
                collision = true;
            }

            if (collision)
            {
                c1.Backup();
                c1.ReverseVelocity();
            }
        }
阅读(1820) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~