cocos2d_x_05_Box2D物理引擎

一、认识Box2D

帮助文档,共69页

二、创建一个物理世界
先导入主头文件

#include <Box2D/Box2D.h>

三、物理世界一览

像素转成米 的比例因子 就是32
三、运动的物体
刚体的类型有三种:动态的、静态的、漂浮的(不受重力影响)
结构体b2BodyDef,构造刚体时,必须指定的、定义一个刚体所需的参数
cocos2d的像素和box2d的世界 长度转换
当box2d中世界长度为10米 为最佳模拟
b2FixtureDef

一个b2FixtureDef是依附在刚体身上的物理特质的属性

一个刚体 有多个 b2FixtureDef

每一个 b2FixtureDef 又有形状shape、密度、摩擦系数等成员属性

添加一个刚体的三步曲:
通过world创建一个body (参数是一个结构体b2BodyDef)
为body设置Fixture属性 (参数是一个b2FixtureDef结构体)
创建一个精灵,并将其绑定到body的UserData
glview->setDesignResolutionSize
(480,320,ResolutionPolicy::SHOW_ALL)表示:
游戏编写时,按照480*320的屏幕分辨率来的;
当运行在不同的屏幕分辨率下时,
会根据实际的屏幕分辨率 与 编写时的分辨率 的缩放比例因子,进行图像绘制
ResolutionPolicy::SHOW_ALL表示完整显示 界面上的所有元素
即:宽高等比缩放,但缩放比例取宽比和高比之中小的那一个。
四、漂浮的物体b2_kinematicBody

创建一个漂浮的物体,不受重力影响,向右漂浮动

addRectBody(1,5,b2_kinematicBody);

#pragma mark - 添加一个刚体
// 添加一个静止的或运动的Rect刚体,通过参数type指定,x和y是世界坐标中的位置
void Box2DScene::addRectBody(float x,float y,b2BodyType body_type)
{
    // 1.1 结构体b2BodyDef
    // 每个刚体都有自身的 固有的 必须的 b2BodyDef属性
    b2BodyDef def;
    // 在世界坐标中 的位置:第x米,第y米处
    def.position = b2Vec2(x,y);
    // 设置【b2BodyDef】的 类型 (运动的或静止的或漂浮的)
    def.type = body_type;
    
    // 设置【b2BodyDef】的 线速度 y = 10,表示物体向上飞
    if(body_type == b2_dynamicBody){
        // 动态物体  自由落体
        def.linearVelocity = b2Vec2(0,9.8);
    }else{
        // 漂浮物体  向右飘动
        def.linearVelocity = b2Vec2(1,0);
    }
    // 设置【b2BodyDef】的 子弹效应 (防止碰撞检测时 由于速度 太快,而失效;如本应反弹,结果陷入地板内)
    // def.bullet = true;
    
    // 1.2 通过调用world的方法,创建一个Body物体
    // 参数 是一个 b2BodyDef,它是构造一个刚体必须的、固有的小编
    // 因为,每个刚体都有自身的 b2BodyDef属性
    b2Body* body = world->CreateBody(&def);
    // *************************************************
    // 2.1 形状分为 圆和多边形
    b2PolygonShape shape;
    shape.SetAsBox(0.5,0.5);
    // 2.2 一个刚体 有多个 b2FixtureDef
    // 一个 b2FixtureDef 是依附在刚体 身上的物理物质的属性
    // 每一个 b2FixtureDef 又有形状shape、密度、摩擦系数等成员属性
    b2FixtureDef fixtureDef;
    // 每一个 b2FixtureDef都有一个成员shape
    fixtureDef.shape = &shape;
    // 密度
    fixtureDef.density = 1;
    // 摩擦系数
    fixtureDef.friction = 0.3;
    // 为刚体 添加一个 b2FixtureDef
    body->CreateFixture(&fixtureDef);
    // *************************************************
    // 3、创建并添加一个 cocos2d 的精灵
    auto s = Sprite::create();
    // 0.5是物理世界中的精灵大小 单位是 米
    // 即在物理世界中,精灵 是一个1米 * 1米的方块
    s->setTextureRect(Rect(0,0.5*2*RATIO,0.5*2*RATIO));
    // 添加到图层Layer
    addChild(s);
    // *************************************************
    // 4、绑定 cocos2d界面上的精灵
    body->SetUserData(s);
    
}


五、静止的物体 如地板
#pragma mark - 添加一个地板
void Box2DScene::addGroundBody()
{
    // 1.1 结构体b2BodyDef
    // 每个刚体都有自身的 固有的 必须的 b2BodyDef属性
    b2BodyDef def;
    // 在世界坐标中 的位置:第x米,第y米处  这个是在
    log("宽:%f",winSize.width);
    // 位置
    def.position = b2Vec2(480/RATIO,0);
    // 设置【b2BodyDef】的 类型 (运动的或静止的或漂浮的)
    def.type = b2_staticBody;
    // 1.2 通过调用world的方法,每个刚体都有自身的 b2BodyDef属性
    groundBody = world->CreateBody(&def);
    // *************************************************
    // 2.1 形状分为 圆和多边
    b2PolygonShape groundShape;
    // 尺寸: 在物理世界中的 半长和 半宽 多少米
    groundShape.SetAsBox(480/RATIO,0.5);
    // 2.2 一个刚体 有多个 b2FixtureDef
    // 一个 b2FixtureDef 是依附在刚体 身上的物理物质的属性
    // 每一个 b2FixtureDef 又有形状shape、密度、摩擦系数等成员属性
    b2FixtureDef fixureDef;
    // 形状
    fixureDef.shape = &groundShape;
    // 密度
    fixureDef.density = 1;
    // 摩擦系数
    fixureDef.friction = 0.3;
    groundBody->CreateFixture(&fixureDef);
}


六、物体间的碰撞检测

首先,设置碰撞检测 的侦听者 为当前Layer

world->SetContactListener(this);

让场景继承 b2ContactListener(实现接口)
实现接口中的方法:

virtual void BeginContact(b2Contact* contact);

b2Contact类中有一个方法,可以得到刚体:

contact->GetFixtureA()->GetBody()

接口中的方法,固定写法

完整代码
//
//  Box2DScene.h
//  01_cocos2d-x
//
//  Created by beyond on 14-10-5.
//
//

#ifndef ___1_cocos2d_x__Box2DScene__
#define ___1_cocos2d_x__Box2DScene__


#include "cocos2d.h"
// 1、导入物理世界 主头文件
#include <Box2D/Box2D.h>

USING_NS_CC;
// 注意 这儿,继承的是 Layer
// 要想进行碰撞检测,必须 实现接口
class Box2DScene : public cocos2d::Layer,public b2ContactListener
{
private:
    // 2、成员变量:物理世界,参数 指定x和y的重力方向
    b2World *world;
    // 因为 要碰撞检测,所以
    b2Body *groundBody;
    
    // 屏幕尺寸
    Size winSize;

public:
    // c++里面没有id类型,所以 返回类的实例对象的 指针
    static cocos2d::Scene* createScene();
    // 以下是 不同点:cocos2d-x的 'init' 方法 返回 bool
    // 而cocos2d-iphone 返回 'id' 类型
    virtual bool init();
    // 宏 自动实现 "静态的 create()方法"
    CREATE_FUNC(Box2DScene);
    
    // 4、在时钟方法里,模拟世界的运行 step
    virtual void update(float dt);
    
    // 5、添加一个静止的或运动的Rect刚体,通过参数type指定,x和y是世界坐标中的位置
    void addRectBody(float x,b2BodyType body_type);
    // 6、添加一个地板
    void addGroundBody();
    
    // 7、碰撞检测
    // 接口中的方法,是一个固定定法
    virtual void BeginContact(b2Contact* contact);
    
};



#endif /* defined(___1_cocos2d_x__Box2DScene__) */



//
//  Box2DScene.cpp
//  01_cocos2d-x
//
//  Created by beyond on 14-10-5.
//
//

#include "Box2DScene.h"
// cocos2d 为宽960 * 高640
// box2d世界为宽10米 * 6.67米 (因为10米是比较理想的模拟情况)
// 因此 像素转成米 的比例是 96
// 如果,要把 像素转成米  只要 像素/RATIO
// 如果,要把 米转成像素  只要 米*RATIO  (把物理世界中的刚体 在界面上更新坐标时)
#define RATIO 960.0/10.0f

USING_NS_CC;
Scene* Box2DScene::createScene()
{
    // 'scene' 自动释放
    // 创建一个scene
    auto scene = Scene::create();
    // 'layer' 自动释放
    auto layer = Box2DScene::create();
    // 将图层 添加到场景中
    scene->addChild(layer);
    // 返回 填充好图层的 场景
    return scene;
}

// 在 "init" 方法中,实例化自己要用的精灵对象
bool Box2DScene::init()
{
    // 1. 调用父类的init,cpp 没有super,直接写父类名
    if ( !Layer::init() ) return false;
    // 屏幕尺寸
    winSize = Director::getInstance()->getVisibleSize();
    
    // 2、创建一个物理世界,参数 是x y 方向的重力加速度,负数表示 重力向下
    world = new b2World(b2Vec2(0,-9.8));
    // 设置碰撞检测 的侦听者 为当前Layer
    world->SetContactListener(this);

    // 3、开启时钟方法,在时钟方法中,让世界 向前运行
    scheduleUpdate();
    
    // 4、创建并添加一个运行的物体 RectBody
    // 参数 x 5  y 3,x和y是世界坐标中的位置,类型是 b2_dynamicBody
    addRectBody(5,3,b2_dynamicBody);
    
    // 5、添加一个地板
    addGroundBody();
    
    // 6、创建一个漂浮的物体
    addRectBody(1,5,b2_kinematicBody);
    return true;
}
#pragma mark - 添加一个刚体
// 添加一个静止的或运动的Rect刚体,通过参数type指定,0.5*2*RATIO));
    // 添加到图层Layer
    addChild(s);
    // *************************************************
    // 4、绑定 cocos2d界面上的精灵
    body->SetUserData(s);
    
}
#pragma mark - 添加一个地板
void Box2DScene::addGroundBody()
{
    // 1.1 结构体b2BodyDef
    // 每个刚体都有自身的 固有的 必须的 b2BodyDef属性
    b2BodyDef def;
    // 在世界坐标中 的位置:第x米,0.5);
    // 2.2 一个刚体 有多个 b2FixtureDef
    // 一个 b2FixtureDef 是依附在刚体 身上的物理物质的属性
    // 每一个 b2FixtureDef 又有形状shape、密度、摩擦系数等成员属性
    b2FixtureDef fixureDef;
    // 形状
    fixureDef.shape = &groundShape;
    // 密度
    fixureDef.density = 1;
    // 摩擦系数
    fixureDef.friction = 0.3;
    groundBody->CreateFixture(&fixureDef);
}

#pragma mark - 时钟方法
void Box2DScene::update(float dt)
{
    // 1、让物理世界 的时间和位置向前迭代
    // 参数:时间差,速度迭代,位置迭代;官方推荐 8和3
    world->Step(dt,8,3);
    
    // 2、取出世界中的所有刚体,改变其位置
    Sprite *s;
    // 链表
    for (b2Body *b = world->GetBodyList(); b; b=b->GetNext()) {
        
        // log("y:%f米",b->GetPosition().y);
        if (b->GetUserData()) {
            // 刚体绑定的 精灵
            s = (Sprite*)b->GetUserData();
            // 更新精灵 在cocos2d中的位置  ; 单位要从米转成像素  只需  米*RATIO 即可
            s->setPosition(b->GetPosition().x*RATIO,b->GetPosition().y*RATIO);
        }
    }
    
    
}
#pragma mark - 碰撞检测
// 接口中的方法,是一个固定定法
void Box2DScene::BeginContact(b2Contact *contact){
    // 碰撞有一方 是地板,则说明 检测到了碰撞
    b2Fixture *A = contact->GetFixtureA();
    b2Body *aBody = A->GetBody();
    b2Fixture *B = contact->GetFixtureB();
    b2Body *bBody = B->GetBody();
    if (aBody == groundBody||bBody == groundBody) {
        log("有物体落在了地板上");
    }
}


















版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


    本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
 下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是