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绑定起来了
///*******************************************************************
}