Cocos2d-x之物理世界(创建运动的物体)

Cocos2d-x之物理世界(创建运动的物体)

 

 

在AppDelegate。cpp中配置glview的属性

//配置glview的属性,屏幕的最高处是600,最右边是800

glview->setDesignResolutionSize(800, 600, ResolutionPolicy::SHOW_ALL);

 

 

AppDelegate。cpp中的内容如下

#include "AppDelegate.h"

#include "HelloWorldScene.h"

 

USING_NS_CC;

 

AppDelegate::AppDelegate() {

 

}

 

AppDelegate::~AppDelegate() 

{

}

 

//if you want a different context,just modify the value of glContextAttrs

//it will takes effect on all platforms

void AppDelegate::initGLContextAttrs()

{

    //set OpenGL context attributions,now can only set six attributions:

    //red,green,blue,alpha,depth,stencil

    GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};

 

    GLView::setGLContextAttrs(glContextAttrs);

}

 

bool AppDelegate::applicationDidFinishLaunching() {

    // initialize director

    auto director = Director::getInstance();

    auto glview = director->getOpenGLView();

    if(!glview) {

        glview = GLViewImpl::createWithRect("Box2dLesson", Rect(0, 0, 960, 640));

        director->setOpenGLView(glview);

        

        //配置glview的属性,屏幕的最高处是600,最右边是800

        glview->setDesignResolutionSize(800, 600, ResolutionPolicy::SHOW_ALL);

        

        

    }

 

    director->getOpenGLView()->setDesignResolutionSize(960, 640, ResolutionPolicy::SHOW_ALL);

 

    // turn on display FPS

    director->setDisplayStats(true);

 

    // set FPS. the default value is 1.0/60 if you don't call this

    director->setAnimationInterval(1.0 / 60);

 

    FileUtils::getInstance()->addSearchPath("res");

 

    // create a scene. it's an autorelease object

    auto scene = HelloWorld::createScene();

 

    // run

    director->runWithScene(scene);

 

    return true;

}

 

// This function will be called when the app is inactive. When comes a phone call,it's be invoked too

void AppDelegate::applicationDidEnterBackground() {

    Director::getInstance()->stopAnimation();

 

    // if you use SimpleAudioEngine, it must be pause

    // SimpleAudioEngine::getInstance()->pauseBackgroundMusic();

}

 

// this function will be called when the app is active again

void AppDelegate::applicationWillEnterForeground() {

    Director::getInstance()->startAnimation();

 

    // if you use SimpleAudioEngine, it must resume here

    // SimpleAudioEngine::getInstance()->resumeBackgroundMusic();

}

 

 

 

 

HelloWorld。h中的内容如下

#ifndef __HELLOWORLD_SCENE_H__

#define __HELLOWORLD_SCENE_H__

 

#include "cocos2d.h"

#include <Box2D/Box2D.h>

 

class HelloWorld : public cocos2d::Layer

{

    

private:

    b2World *world;//创建一个私有的变量,即物理世界

    

public:

    // there's no 'id' in cpp, so we recommend returning the class instance pointer

    static cocos2d::Scene* createScene();

 

    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone

    virtual bool init();

 

    //为了模拟世界的运行,重写update方法,他会没隔一帧执行一次,

    //我们的世界也要每隔一帧就重新计算一下世界中的物体所处的位置

    virtual void update(float dt);

    

    //创建一个运动的物体,运动的矩形

    void addRect();

    

    // implement the "static create()" method manually

    CREATE_FUNC(HelloWorld);

};

 

#endif // __HELLOWORLD_SCENE_H__

 

 

 

HelloWorld。cpp中的内容如下

#include "HelloWorldScene.h"

#include "cocostudio/CocoStudio.h"

#include "ui/CocosGUI.h"

 

USING_NS_CC;

 

using namespace cocostudio::timeline;

 

//定义中间的比例为80(box2d和cocos2d的转换比例)

#define RATIO 80.0f

 

Scene* HelloWorld::createScene()

{

    // 'scene' is an autorelease object

    auto scene = Scene::create();

    

    // 'layer' is an autorelease object

    auto layer = HelloWorld::create();

 

    // add layer as a child to scene

    scene->addChild(layer);

 

    // return the scene

    return scene;

}

 

// on "init" you need to initialize your instance

bool HelloWorld::init()

{

    //////////////////////////////

    // 1. super init first

    if ( !Layer::init() )

    {

        return false;

    }

    //创建一个世界,b2world(二维矢量类型的,指定世界的加速度的方向

    //b2Vec2(加速度的方向,向下的,所以x轴没有为0,y轴为-10))这样才能往下落

    world = new b2World(b2Vec2(0, -10));

    

    

    //添加一个矩形,然后调用scheduleUpdate方法,实现矩形的下落,随着重力加速向下运动

    addRect();

    

    

    //调用update方法,实现每帧都改变物理世界中的物体

    scheduleUpdate();

 

    return true;

}

 

 

//实现模拟物理世界的方法(当前一帧与上一帧的时间差)

void HelloWorld::update(float dt){

    

    //使用这个step方法来一步一步的模拟我们的物理世界

    //(时间差(当前一步与最后一步的时间差,即当前一帧与上一帧的时间差),

    //速度迭代,模拟物理世界的过程中难免会有误差,所以就用速度迭代的次数来避免误差,官方建议8次,

    //位置的迭代,官方建议3次)

    world->Step(dt, 8, 3);

    

    //为了获取矩形,所以在这里定义一个Sprite

    Sprite *s;

    

    //获取移动的矩形

    //在这里获取到所有的子集的对象

    //遍历所有的子集对象,

    for (b2Body *b = world->GetBodyList(); b; b = b->GetNext()) {

        //判断,因为只有一个动态的物体,所以可以这么判断,否则,要用别的方法

        if (b->GetType() == b2_dynamicBody) {

            //获取到移动的物体的y 位置

            log("%f",b->GetPosition().y);

            

            if (b->GetUserData()) {

                s = (Sprite*)b->GetUserData();

                

                //让Sprite与body同步

                s->setPosition(b->GetPosition().x * RATIO, b->GetPosition().y * RATIO);

            }

        }

    }

    

    

    

}

 

 

//创建矩形,并且让其随着重力开始运动,有加速度的向下移动

void HelloWorld::addRect(){

    

    //config box2d

    ///*******************************************************************

    //定义一个b2BodyDef物体

    b2BodyDef def;

    

//    //指定def的初始化的position,x轴是0,y轴是10,代表着从10往下落

//    def.position = b2Vec2(0, 10);

    //定义完比例后开始修改位置,因为最高为6米,所以y轴定义为5,x轴最大为10米

    def.position = b2Vec2(3, 5);

    

    //配置物体的属性

    //b2_dynamicBody是枚举类型的,代表运动的物体,

    //还有b2_staticBody  代表静态的物体

//还有b2_kinematicBody  代表悬浮的物体

    def.type = b2_dynamicBody;//此时这是个运动的物体

    

    //创建一个物体(物体的相关的定义)

    b2Body *body = world->CreateBody(&def);

    ///*******************************************************************

    

    

    

    //config cocos shape

    ///*******************************************************************

    //定义一个图形

    auto s = Sprite::create();

    //指定他的Texture图形区域

    s->setTextureRect(Rect(0, 0, 80, 80));

    //将其添加到层中

    addChild(s);

    

    //配置位置

    //cocos2d的图形区域的位置是(800 x 600)

    //box2d的范围单位是米,官方文档上的比较精确的范围是10米之内

    //意味着800px的位置当成10米是比较合理的,所以中间的比例是80

    

//    //因为每一帧都同步了,所以此处可以不要了,

//    //因为update中的s->setPosition(b->GetPosition().x * RATIO,

//    //b->GetPosition().y * RATIO);所以就不要了

//    //配置s的位置

//    s->setPosition(Point(def.position.x * RATIO, def.position.y * RATIO));

    

    //将图形和body相关起来

    body->SetUserData(s);//这样就将图形和body绑定起来了

    

    ///*******************************************************************

    

}

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/dudu580231/p/4388620.html