1、演示物理引擎示例:
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
// 关闭菜单
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width / 2,
origin.y + closeItem->getContentSize().height / 2));
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);
// ③创建一个精灵
auto edgeSp = Sprite::create();
// 创建一个静态四边形刚体,表示屏幕四边
auto body = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3);
// 设置精灵居中
edgeSp->setPosition(visibleSize.width / 2, visibleSize.height / 2);
// 精灵设置PhysicsBody
edgeSp->setPhysicsBody(body);
// 将精灵添加为当前层的子节点,屏幕四边就有墙壁的物理效果了
this->addChild(edgeSp);
// 集合存储图片,之后随即从集合中获取
std::vector<std::string> imageNames;
imageNames.push_back("basketball.png");
imageNames.push_back("football.png");
// ④创建事件监听器
auto planeListener = EventListenerTouchOneByOne::create();
// 响应触摸事件函数
planeListener->onTouchBegan = [](Touch* touch, Event* event) {return true; };
planeListener->onTouchEnded = [=](Touch* touch, Event* event) {
// OpenGL坐标
Vec2 touchLocation = touch->getLocation();
// 将触摸点坐标转换成相对的Node坐标
Vec2 nodeLocation = this->convertToNodeSpace(touchLocation);
// 获取随机数
int rand = random() % 2;
// 随机获取一张图片资源创建精灵对象
std::string imageName = imageNames.at(rand);
Sprite* ball = Sprite::create(imageName);
// 设置精灵位置为触摸点
ball->setPosition(nodeLocation.x, nodeLocation.y);
// PhysicsBody::createCircle创建一个圆形的刚体附加在精灵上。
auto body = PhysicsBody::createCircle(ball->getContentSize().width / 2);
// 设置刚体的速度
body->setVelocity(Vect(0.0f, -100.0f));
PhysicsShape* ps = body->getShape(0);
// 设置力矩
ps->setMoment(0.2);
// 设置质量
ps->setMass(0.2f);
// 设置密度。一个对象的密度越大,那么它就有更多的质量,就会越难以移动。
ps->setDensity(0.2f);
// 设置摩擦力(Friction)。它的范围是0~1.0。
// 0代表没有摩擦,1代表最大摩擦、几乎移不动的摩擦。
ps->setFriction(0.2f);
// 设置回复力即弹力(Restitution)。它的范围也是0~1.0。
// 0代表对象碰撞之后不会反弹,1意味着完全弹性碰撞,即以同样的速度反弹。
ps->setRestitution(1.0f);
// 为球添加刚体属性
ball->setPhysicsBody(body);
// 将球添加为当前层的子节点
this->addChild(ball);
};
// ⑤添加场景优先事件监听器
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(planeListener, this);
// ⑥启用设备的加速计
Device::setAccelerometerEnabled(true);
// 创建加速度计监听器
auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(HelloWorld::onAcceleration, this));
// 添加加速度计事件监听器
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
1、编号①代码通过createWithPhysics函数创建一个带有物理效果的场景对象,DebugDraw可以将碰撞体的形状、关节等全部绘制出来,方便观察物体和整个场景的可碰撞区域
2、编号②代码设置物理世界的重力值,Vect是一个向量值,X方向表示正值方向向右,负值重力方向向左,Y方向表示正值重力方向向上,负值重力方向向下,Y值得负数越大,物体掉落越快
3、编号③代码创建一个精灵,同时使用PhysicsBody对象的createEdgeBox函数创建一个静态四边形刚体,用来表示屏幕四边,并添加为当前层的子节点,这样屏幕的四边就有墙壁的碰撞效果
4、编号④代码创建时间监听器,onTouchEnded函数首先获取触摸点并转换Node坐标,随机创建一个足球或篮球精灵,使用PhysicsBody对象的createCircle函数创建一个圆形的刚体,半径为精灵的实际宽度的一半,并设置刚体的速度。通过PhsicsShape对象设置力矩、质量、密度、摩擦力和回复弹力等属性,调用精灵的setPhysicsBody函数将刚体附加在精灵上,最后将精灵添加为当前层的子节点
5、编号⑤代码添加场景优先事件监听器
6、编号⑥代码启用设备加速度计,并添加加速度计时间监听器
运行项目,在屏幕空白处触摸屏幕,会有新的足球或篮球精灵出现,因为重力下落,碰撞到地面或者其他球会弹起来。