• Box2D教程4复杂刚体的复杂外观


    Box2D教程1-创建碰撞世界

    Box2D教程2-鼠标交互

    Box2D教程3-刚体绑定外观

    Box2D教程4-复杂刚体的复杂外观

    Box2D教程5-碰撞检测

    之前我们知道了如何创建标准几何体刚体及其外观,此教程主要解决如何创建复杂刚体的问题。Box2D使用多边形拼接形成复杂的外观。通过前面的教程我们知道使用下面两句来创建一个刚体。
    b2Body = b2World.createBody(b2BodyDef)
    b2Body.createFixture(b2FixtureDef)
    对于复杂刚体,b2Body和b2BodyDef还是一个,即始终是一个刚体,我们通过FixtureDef来实现多个多边形拼接,即创建多个b2FixtureDef,并多次执行
    b2Body.createFixture(b2FixtureDef)
    如果,鱼缸通过若干个四边形拼接而成

    而b2FixtureDef的shape属性需要提供一个多边形b2PolygonShape,此多边形可使用下面方法来创建。
    b2PolygonShape.setAsArray(veticesArray)
    此方法需要一个b2Vec2对象的数组,此数组每一个元素决定了一个顶点,数组元素的顺序按照顺时针排序(必须)。

    具体实现代码

     1 private var _container:b2Body;
    2 [Embed(source="./assets/container.png")]
    3 public var ContainerImg:Class;
    4
    5 //添加容器的外观,并对齐好
    6 private function addContainerTexture():void
    7 {
    8 var img:Bitmap = new ContainerImg();
    9 this.addChild(img);
    10
    11 //调整图片的位置
    12 img.x = 43;
    13 img.y = 3;
    14 }
    15 private function createContainer():void
    16 {
    17 //容器的所有顶点组成的三维数组
    18 //第一维度是一个多边形
    19 //第二维度是多边形中的四个顶点
    20 //第三维度是每个顶点的x,y坐标
    21 var shapeCoords:Array = [
    22 [[61,55],[77,67],[39,135],[23,124]],
    23 [[23,124],[39,135],[25,220],[6,218]],
    24 [[6,218],[25,220],[44,305],[28,312]],
    25 [[28,312],[44,305],[94,372],[82,384]],
    26 [[82,384],[94,372],[167,413],[161,425]],
    27 [[161,425],[167,413],[250,424],[250,437]],
    28 [[250,438],[250,424],[339,416],[341,429]],
    29
    30 [[341,430],[339,416],[411,383],[418,393]],
    31 [[418,393],[411,383],[464,327],[478,334]],
    32 [[478,334],[464,327],[489,254],[504,252]],
    33 [[504,252],[489,254],[488,183],[504,177]],
    34 [[504,177],[488,183],[470,112],[488,103]],
    35 [[488,103],[470,112],[443,66],[465,63]],
    36 [[77,67],[72,46],[436,43],[443,66]]
    37 ];
    38 //创建一个刚体定义
    39 var bodyDef:b2BodyDef = new b2BodyDef();
    40 bodyDef.type = b2Body.b2_staticBody;
    41 bodyDef.position.Set(20 / PIXEL_TO_METER, -10/PIXEL_TO_METER);
    42 //创建刚体
    43 _container = world.CreateBody(bodyDef);
    44 //为刚体创建修饰物
    45 //传递顶点数组作为参数
    46 createFixtrues(shapeCoords);
    47 }
    48 //创建Fixtures
    49 //根据顶点数组的第一维度,创建多个Fixture
    50 private function createFixtrues(coords:Array):void
    51 {
    52 for(var i:int = 0; i<coords.length; i++)
    53 {
    54 var shape:b2PolygonShape = new b2PolygonShape();
    55 //调用创建顶点方法,将数组的第二维度作为参数
    56 //返回一个顶点数组,用于创建shape
    57 var shapeVertices:Array = createVerticesArray(coords[i]);
    58 shape.SetAsArray(shapeVertices);
    59 var shapeFixtureDef:b2FixtureDef = new b2FixtureDef();
    60 shapeFixtureDef.shape = shape;
    61 shapeFixtureDef.density = 1;
    62 shapeFixtureDef.restitution = 1.0;
    63 _container.CreateFixture(shapeFixtureDef);
    64 }
    65 }
    66
    67 //创建顶点数组
    68 private function createVerticesArray(coords:Array):Array
    69 {
    70 //不能少于三个顶点
    71 if(coords.length < 3)
    72 {
    73 throw new Error("Shape create wrong");
    74 }
    75 var vertices:Array = new Array();
    76 //遍历顶点数组的第二维度,生成b2Vec2数组
    77 for (var i:int = 0; i<coords.length ; i++)
    78 {
    79 var vertice:b2Vec2 = new b2Vec2(coords[i][0]/PIXEL_TO_METER, coords[i][1]/PIXEL_TO_METER);
    80 vertices.push(vertice);
    81 }
    82
    83 return vertices;
    84
    85 }

    那么,为什么我们不一下子创建所有的顶点,然后按顺时针顺序连接起来,形成一个整体的多边形?
    因为Box2D边框不允许凹进去,而鱼缸内边框是弯曲的向内凹,所有无法进行正确的碰撞检测。

    那么多顶点,我们要怎么获取那么精确呢?
    我是这么做的,不确定是否最简,我用的还算方便。借助Photoshop,首先把鱼缸边缘没有用的像素全部裁切掉,然后打开信息面板,将鼠标指到相应的位置,便显示该位置的坐标,将坐标记下就可以。最后把裁切后鱼缸保存作为外观图片,这样正好能够对上。

    下载源码



  • 相关阅读:
    Oracle问题之ORA-12560TNS:协议适配器错误
    调用脚本的方式自动的创建或者是更新oracle数据库自带的Seq序列号的值
    linux在telnet情况下root登录提示login incorrect
    CentOS 7 中 Systemd详解
    CentOS7 下安装telnet服务
    linux 安装telnet命令及使用
    Linux安装telnet
    Linux系统xinetd服务启动不了
    linux服务安装与配置(二):安装xinetd服务
    Linux超级守护进程——xinetd
  • 原文地址:https://www.cnblogs.com/jinglehit/p/2313183.html
Copyright © 2020-2023  润新知