30#include "ui/CocosGUI.h"
31#include "../testResource.h"
35PhysicsTests::PhysicsTests()
59 Color4F STATIC_COLOR(1.0f, 0.0f, 0.0f, 1.0f);
60 const int DRAG_BODYS_TAG = 0x80;
63void PhysicsDemo::toggleDebug()
66 _debugDraw = !_debugDraw;
67 _physicsWorld->setDebugDrawMask(_debugDraw ? PhysicsWorld::DEBUGDRAW_ALL : PhysicsWorld::DEBUGDRAW_NONE);
72PhysicsDemo::PhysicsDemo()
73: _spriteTexture(nullptr)
79bool PhysicsDemo::init()
82 return initWithPhysics();
85PhysicsDemo::~PhysicsDemo()
89std::string PhysicsDemo::title()
const
91 return "PhysicsComponentTest";
94void PhysicsDemo::onEnter()
98 _spriteTexture = SpriteBatchNode::create(
"Images/grossini_dance_atlas.png", 100)->getTexture();
101 MenuItemFont::setFontSize(18);
102 auto item = MenuItemFont::create(
"Toggle debug", CC_CALLBACK_1(PhysicsDemo::toggleDebugCallback,
this));
104 auto menu = Menu::create(item,
nullptr);
105 this->addChild(menu);
109Sprite* PhysicsDemo::addGrossiniAtPosition(Vec2 p,
float scale)
111 CCLOG(
"Add sprite %0.2f x %02.f", p.x, p.y);
115 posx = CCRANDOM_0_1() * 200.0f;
116 posy = CCRANDOM_0_1() * 200.0f;
118 posx = (posx % 4) * 85;
119 posy = (posy % 3) * 121;
121 auto sp = Sprite::createWithTexture(_spriteTexture, Rect(posx, posy, 85, 121));
125 sp->addComponent(PhysicsBody::createBox(Size(48.0f, 108.0f)));
131void PhysicsDemo::toggleDebugCallback(Ref* )
138 const int LOGO_WIDTH = 188;
139 const int LOGO_HEIGHT = 35;
140 const int LOGO_RAW_LENGTH = 24;
141 const int LOGO_IMAGE[] =
143 15, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, -64, 15, 63, -32, -2, 0, 0, 0, 0, 0, 0, 0,
144 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -64, 15, 127, -125, -1, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
145 0, 0, 0, 127, -64, 15, 127, 15, -1, -64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, -64, 15, -2,
146 31, -1, -64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, -64, 0, -4, 63, -1, -32, 0, 0, 0, 0, 0, 0,
147 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, -64, 15, -8, 127, -1, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
148 1, -1, -64, 0, -8, -15, -1, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -31, -1, -64, 15, -8, -32,
149 -1, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, -15, -1, -64, 9, -15, -32, -1, -32, 0, 0, 0, 0, 0,
150 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -15, -1, -64, 0, -15, -32, -1, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
151 0, 0, 63, -7, -1, -64, 9, -29, -32, 127, -61, -16, 63, 15, -61, -1, -8, 31, -16, 15, -8, 126, 7, -31,
152 -8, 31, -65, -7, -1, -64, 9, -29, -32, 0, 7, -8, 127, -97, -25, -1, -2, 63, -8, 31, -4, -1, 15, -13,
153 -4, 63, -1, -3, -1, -64, 9, -29, -32, 0, 7, -8, 127, -97, -25, -1, -2, 63, -8, 31, -4, -1, 15, -13,
154 -2, 63, -1, -3, -1, -64, 9, -29, -32, 0, 7, -8, 127, -97, -25, -1, -1, 63, -4, 63, -4, -1, 15, -13,
155 -2, 63, -33, -1, -1, -32, 9, -25, -32, 0, 7, -8, 127, -97, -25, -1, -1, 63, -4, 63, -4, -1, 15, -13,
156 -1, 63, -33, -1, -1, -16, 9, -25, -32, 0, 7, -8, 127, -97, -25, -1, -1, 63, -4, 63, -4, -1, 15, -13,
157 -1, 63, -49, -1, -1, -8, 9, -57, -32, 0, 7, -8, 127, -97, -25, -8, -1, 63, -2, 127, -4, -1, 15, -13,
158 -1, -65, -49, -1, -1, -4, 9, -57, -32, 0, 7, -8, 127, -97, -25, -8, -1, 63, -2, 127, -4, -1, 15, -13,
159 -1, -65, -57, -1, -1, -2, 9, -57, -32, 0, 7, -8, 127, -97, -25, -8, -1, 63, -2, 127, -4, -1, 15, -13,
160 -1, -1, -57, -1, -1, -1, 9, -57, -32, 0, 7, -1, -1, -97, -25, -8, -1, 63, -1, -1, -4, -1, 15, -13, -1,
161 -1, -61, -1, -1, -1, -119, -57, -32, 0, 7, -1, -1, -97, -25, -8, -1, 63, -1, -1, -4, -1, 15, -13, -1,
162 -1, -61, -1, -1, -1, -55, -49, -32, 0, 7, -1, -1, -97, -25, -8, -1, 63, -1, -1, -4, -1, 15, -13, -1,
163 -1, -63, -1, -1, -1, -23, -49, -32, 127, -57, -1, -1, -97, -25, -1, -1, 63, -1, -1, -4, -1, 15, -13,
164 -1, -1, -63, -1, -1, -1, -16, -49, -32, -1, -25, -1, -1, -97, -25, -1, -1, 63, -33, -5, -4, -1, 15,
165 -13, -1, -1, -64, -1, -9, -1, -7, -49, -32, -1, -25, -8, 127, -97, -25, -1, -1, 63, -33, -5, -4, -1,
166 15, -13, -1, -1, -64, -1, -13, -1, -32, -49, -32, -1, -25, -8, 127, -97, -25, -1, -2, 63, -49, -13,
167 -4, -1, 15, -13, -1, -1, -64, 127, -7, -1, -119, -17, -15, -1, -25, -8, 127, -97, -25, -1, -2, 63,
168 -49, -13, -4, -1, 15, -13, -3, -1, -64, 127, -8, -2, 15, -17, -1, -1, -25, -8, 127, -97, -25, -1,
169 -8, 63, -49, -13, -4, -1, 15, -13, -3, -1, -64, 63, -4, 120, 0, -17, -1, -1, -25, -8, 127, -97, -25,
170 -8, 0, 63, -57, -29, -4, -1, 15, -13, -4, -1, -64, 63, -4, 0, 15, -17, -1, -1, -25, -8, 127, -97,
171 -25, -8, 0, 63, -57, -29, -4, -1, -1, -13, -4, -1, -64, 31, -2, 0, 0, 103, -1, -1, -57, -8, 127, -97,
172 -25, -8, 0, 63, -57, -29, -4, -1, -1, -13, -4, 127, -64, 31, -2, 0, 15, 103, -1, -1, -57, -8, 127,
173 -97, -25, -8, 0, 63, -61, -61, -4, 127, -1, -29, -4, 127, -64, 15, -8, 0, 0, 55, -1, -1, -121, -8,
174 127, -97, -25, -8, 0, 63, -61, -61, -4, 127, -1, -29, -4, 63, -64, 15, -32, 0, 0, 23, -1, -2, 3, -16,
175 63, 15, -61, -16, 0, 31, -127, -127, -8, 31, -1, -127, -8, 31, -128, 7, -128, 0, 0
178 int getPixel(
int x,
int y)
180 return (LOGO_IMAGE[(x >> 3) + y * LOGO_RAW_LENGTH] >> (~x & 0x7)) & 1;
185 return rand() / RAND_MAX;
189Sprite* PhysicsDemo::makeBall(Vec2 point,
float radius, PhysicsMaterial material)
191 Sprite* ball =
nullptr;
192 if (_ball !=
nullptr)
193 ball = Sprite::createWithTexture(_ball->getTexture());
195 ball = Sprite::create(
"Images/ball.png");
197 ball->setScale(0.13f * radius);
199 ball->addComponent(PhysicsBody::createCircle(ball->getContentSize().width / 2, material));
200 ball->setPosition(Vec2(point.x, point.y));
205Sprite* PhysicsDemo::makeBox(Vec2 point, Size size,
int color, PhysicsMaterial material)
210 yellow = CCRANDOM_0_1() > 0.5f;
217 auto box = yellow ? Sprite::create(
"Images/YellowSquare.png") : Sprite::create(
"Images/CyanSquare.png");
218 box->setScaleX(size.width / 100.0f);
219 box->setScaleY(size.height / 100.0f);
221 box->addComponent(PhysicsBody::createBox(box->getContentSize(), material));
223 box->setPosition(Vec2(point.x, point.y));
228Sprite* PhysicsDemo::makeTriangle(Vec2 point, Size size,
int color, PhysicsMaterial material)
233 yellow = CCRANDOM_0_1() > 0.5f;
240 auto triangle = yellow ? Sprite::create(
"Images/YellowTriangle.png") : Sprite::create(
"Images/CyanTriangle.png");
242 if (size.height == 0)
244 triangle->setScale(size.width / 100.0f);
248 triangle->setScaleX(size.width / 50.0f);
249 triangle->setScaleY(size.height / 43.5f);
252 Vec2 vers[] = { Vec2(0.0f, triangle->getContentSize().height / 2), Vec2(triangle->getContentSize().width / 2, -triangle->getContentSize().height / 2), Vec2(-triangle->getContentSize().width / 2, -triangle->getContentSize().height / 2) };
254 triangle->addComponent(PhysicsBody::createPolygon(vers, 3, material));
255 triangle->setPosition(Vec2(point.x, point.y));
260bool PhysicsDemo::onTouchBegan(Touch* touch, Event* event)
262 auto location = touch->getLocation();
263 auto arr = _physicsWorld->getShapes(location);
265 PhysicsBody* body =
nullptr;
266 for (
auto& obj : arr)
268 if ((obj->getBody()->getTag() & DRAG_BODYS_TAG) != 0)
270 body = obj->getBody();
277 Node* mouse = Node::create();
278 auto physicsBody = PhysicsBody::create(PHYSICS_INFINITY, PHYSICS_INFINITY);
279 physicsBody->setDynamic(
false);
280 mouse->addComponent(physicsBody);
281 mouse->setPosition(location);
282 this->addChild(mouse);
283 PhysicsJointPin* joint = PhysicsJointPin::construct(physicsBody, body, location);
284 joint->setMaxForce(5000.0f * body->getMass());
285 _physicsWorld->addJoint(joint);
286 _mouses.insert(std::make_pair(touch->getID(), mouse));
294void PhysicsDemo::onTouchMoved(Touch* touch, Event* )
296 auto it = _mouses.find(touch->getID());
298 if (it != _mouses.end())
300 it->second->setPosition(touch->getLocation());
304void PhysicsDemo::onTouchEnded(Touch* touch, Event* )
306 auto it = _mouses.find(touch->getID());
308 if (it != _mouses.end())
310 this->removeChild(it->second);
317void PhysicsDemoLogoSmash::onEnter()
319 PhysicsDemo::onEnter();
321 _physicsWorld->setGravity(Vec2(0.0f, 0.0f));
322 _physicsWorld->setUpdateRate(5.0f);
324 _ball = SpriteBatchNode::create(
"Images/ball.png",
sizeof(LOGO_IMAGE)/
sizeof(LOGO_IMAGE[0]));
326 for (
int y = 0; y < LOGO_HEIGHT; ++y)
328 for (
int x = 0; x < LOGO_WIDTH; ++x)
332 float xJitter = 0.05 * frand();
333 float yJitter = 0.05 * frand();
337 0.95f, PhysicsMaterial(0.01f, 0.0f, 0.0f));
339 auto physicsBody = ball->getPhysicsBody();
340 physicsBody->setMass(1.0);
341 physicsBody->setMoment(PHYSICS_INFINITY);
343 _ball->addChild(ball);
349 auto bullet = makeBall(Vec2(400.0f, 0.0f), 10, PhysicsMaterial(PHYSICS_INFINITY, 0, 0));
350 bullet->getPhysicsBody()->setVelocity(Vec2(200.0f, 0.0f));
354 _ball->addChild(bullet);
357std::string PhysicsDemoLogoSmash::title()
const
364PhysicsDemoClickAdd::~PhysicsDemoClickAdd()
366 Device::setAccelerometerEnabled(
false);
369void PhysicsDemoClickAdd::onEnter()
371 PhysicsDemo::onEnter();
373 auto touchListener = EventListenerTouchAllAtOnce::create();
374 touchListener->onTouchesEnded = CC_CALLBACK_2(PhysicsDemoClickAdd::onTouchesEnded,
this);
375 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,
this);
377 Device::setAccelerometerEnabled(
true);
378 auto accListener = EventListenerAcceleration::create(CC_CALLBACK_2(PhysicsDemoClickAdd::onAcceleration,
this));
379 _eventDispatcher->addEventListenerWithSceneGraphPriority(accListener,
this);
381 auto node = Node::create();
384 this->addChild(node);
389std::string PhysicsDemoClickAdd::subtitle()
const
391 return "multi touch to add grossini";
394void PhysicsDemoClickAdd::onTouchesEnded(
const std::vector<Touch*>& touches, Event* )
398 for(
auto touch: touches)
400 auto location = touch->getLocation();
402 addGrossiniAtPosition( location );
406void PhysicsDemoClickAdd::onAcceleration(Acceleration* acc, Event* )
408 static float prevX=0, prevY=0;
410#define FILTER_FACTOR 0.05f
412 float accelX = (float) acc->x * FILTER_FACTOR + (1- FILTER_FACTOR)*prevX;
413 float accelY = (float) acc->y * FILTER_FACTOR + (1- FILTER_FACTOR)*prevY;
418 auto v = Vec2( accelX, accelY);
421 _physicsWorld->setGravity(v);
424void PhysicsDemoPyramidStack::onEnter()
426 PhysicsDemo::onEnter();
428 auto touchListener = EventListenerTouchOneByOne::create();
429 touchListener->onTouchBegan = CC_CALLBACK_2(PhysicsDemoPyramidStack::onTouchBegan,
this);
430 touchListener->onTouchMoved = CC_CALLBACK_2(PhysicsDemoPyramidStack::onTouchMoved,
this);
431 touchListener->onTouchEnded = CC_CALLBACK_2(PhysicsDemoPyramidStack::onTouchEnded,
this);
432 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,
this);
434 auto node = Node::create();
437 this->addChild(node);
439 auto ball = Sprite::create(
"Images/ball.png");
442 auto body = PhysicsBody::createCircle(10);
443 ball->addComponent(body);
444 body->setTag(DRAG_BODYS_TAG);
446 this->addChild(ball);
448 scheduleOnce(CC_SCHEDULE_SELECTOR(PhysicsDemoPyramidStack::updateOnce), 3.0);
450 for (
int i = 0; i < 14; i++)
452 for (
int j = 0; j <= i; j++)
454 auto sp = addGrossiniAtPosition(
VisibleRect::bottom() + Vec2((i / 2 - j) * 11, (14 - i) * 23 + 100), 0.2f);
455 sp->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
460void PhysicsDemoPyramidStack::updateOnce(
float )
462 auto ball = getChildByTag(100);
464 ball->setScale(ball->getScale() * 3);
467std::string PhysicsDemoPyramidStack::title()
const
469 return "Pyramid Stack";
472PhysicsDemoRayCast::PhysicsDemoRayCast()
478void PhysicsDemoRayCast::onEnter()
480 PhysicsDemo::onEnter();
482 auto listener = EventListenerTouchAllAtOnce::create();
483 listener->onTouchesEnded = CC_CALLBACK_2(PhysicsDemoRayCast::onTouchesEnded,
this);
484 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,
this);
486 _physicsWorld->setGravity(Point::ZERO);
488 auto node = DrawNode::create();
491 this->addChild(node);
493 MenuItemFont::setFontSize(18);
494 auto item = MenuItemFont::create(
"Change Mode(any)", CC_CALLBACK_1(PhysicsDemoRayCast::changeModeCallback,
this));
496 auto menu = Menu::create(item,
nullptr);
497 this->addChild(menu);
503void PhysicsDemoRayCast::changeModeCallback(Ref* sender)
505 _mode = (_mode + 1) % 3;
510 ((MenuItemFont*)sender)->setString(
"Change Mode(any)");
513 ((MenuItemFont*)sender)->setString(
"Change Mode(nearest)");
516 ((MenuItemFont*)sender)->setString(
"Change Mode(multiple)");
524bool PhysicsDemoRayCast::anyRay(PhysicsWorld& ,
const PhysicsRayCastInfo& info,
void* data)
526 *((Vec2*)data) = info.contact;
530void PhysicsDemoRayCast::update(
float )
534 Vec2 d(L * cosf(_angle), L * sinf(_angle));
535 Vec2 point2 = point1 + d;
538 _node = DrawNode::create();
543 Vec2 point3 = point2;
544 auto func = CC_CALLBACK_3(PhysicsDemoRayCast::anyRay,
this);
546 _physicsWorld->rayCast(func, point1, point2, &point3);
547 _node->drawSegment(point1, point3, 1, STATIC_COLOR);
549 if (point2 != point3)
551 _node->drawDot(point3, 2, Color4F(1.0f, 1.0f, 1.0f, 1.0f));
559 Vec2 point3 = point2;
560 float friction = 1.0f;
561 PhysicsRayCastCallbackFunc func = [&point3, &friction](PhysicsWorld& ,
const PhysicsRayCastInfo& info,
void* )->
bool
563 if (friction > info.fraction)
565 point3 = info.contact;
566 friction = info.fraction;
572 _physicsWorld->rayCast(func, point1, point2,
nullptr);
573 _node->drawSegment(point1, point3, 1, STATIC_COLOR);
575 if (point2 != point3)
577 _node->drawDot(point3, 2, Color4F(1.0f, 1.0f, 1.0f, 1.0f));
585#define MAX_MULTI_RAYCAST_NUM 5
586 Vec2 points[MAX_MULTI_RAYCAST_NUM];
589 PhysicsRayCastCallbackFunc func = [&points, &num](PhysicsWorld& ,
const PhysicsRayCastInfo& info,
void* )->
bool
591 if (num < MAX_MULTI_RAYCAST_NUM)
593 points[num++] = info.contact;
599 _physicsWorld->rayCast(func, point1, point2,
nullptr);
601 _node->drawSegment(point1, point2, 1, STATIC_COLOR);
603 for (
int i = 0; i < num; ++i)
605 _node->drawDot(points[i], 2, Color4F(1.0f, 1.0f, 1.0f, 1.0f));
617 _angle += 0.25f * (float)M_PI / 180.0f;
620void PhysicsDemoRayCast::onTouchesEnded(
const std::vector<Touch*>& touches, Event* )
624 for (
auto &touch : touches)
626 auto location = touch->getLocation();
628 float r = CCRANDOM_0_1();
632 addChild(makeBall(location, 5 + CCRANDOM_0_1() * 10));
634 else if (r < 2.0f / 3.0f)
636 addChild(makeBox(location, Size(10 + CCRANDOM_0_1() * 15, 10 + CCRANDOM_0_1() * 15)));
640 addChild(makeTriangle(location, Size(10 + CCRANDOM_0_1() * 20, 10 + CCRANDOM_0_1() * 20)));
645std::string PhysicsDemoRayCast::title()
const
650void PhysicsDemoActions::onEnter()
652 PhysicsDemo::onEnter();
653 _physicsWorld->setGravity(Vec2::ZERO);
655 auto touchListener = EventListenerTouchOneByOne::create();
656 touchListener->onTouchBegan = CC_CALLBACK_2(PhysicsDemoActions::onTouchBegan,
this);
657 touchListener->onTouchMoved = CC_CALLBACK_2(PhysicsDemoActions::onTouchMoved,
this);
658 touchListener->onTouchEnded = CC_CALLBACK_2(PhysicsDemoActions::onTouchEnded,
this);
659 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,
this);
661 auto node = Node::create();
664 this->addChild(node);
670 sp4->getPhysicsBody()->setGravityEnable(
false);
672 sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
673 sp2->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
674 sp3->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
675 sp4->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
677 auto actionTo = JumpTo::create(2, Vec2(100, 100), 50, 4);
678 auto actionBy = JumpBy::create(2, Vec2(300, 0), 50, 4);
679 auto actionUp = JumpBy::create(2, Vec2(0, 50), 80, 4);
680 auto actionByBack = actionBy->reverse();
681 auto rotateBy = RotateBy::create(2, 180);
682 auto rotateByBack = RotateBy::create(2, -180);
684 sp1->runAction(RepeatForever::create(actionUp));
685 sp2->runAction(RepeatForever::create(Sequence::create(actionBy, actionByBack,
nullptr)));
686 sp3->runAction(actionTo);
687 sp4->runAction(RepeatForever::create(Sequence::create(rotateBy, rotateByBack,
nullptr)));
690std::string PhysicsDemoActions::title()
const
698void PhysicsDemoJoints::onEnter()
700 PhysicsDemo::onEnter();
703 auto listener = EventListenerTouchOneByOne::create();
704 listener->onTouchBegan = CC_CALLBACK_2(PhysicsDemo::onTouchBegan,
this);
705 listener->onTouchMoved = CC_CALLBACK_2(PhysicsDemo::onTouchMoved,
this);
706 listener->onTouchEnded = CC_CALLBACK_2(PhysicsDemo::onTouchEnded,
this);
707 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,
this);
712 Node* node = Node::create();
713 PhysicsBody* box = PhysicsBody::create();
714 node->addComponent(box);
716 box->setDynamic(
false);
717 node->setPosition(Point::ZERO);
718 this->addChild(node);
720 for (
int i = 0; i < 4; ++i)
722 for (
int j = 0; j < 4; ++j)
725 box->addShape(PhysicsShapeEdgeBox::create(Size(width, height), PHYSICSSHAPE_MATERIAL_DEFAULT, 1, offset));
731 auto sp1 = makeBall(offset - Vec2(30, 0), 10);
732 auto sp1PhysicsBody = sp1->getPhysicsBody();
733 sp1PhysicsBody->setTag(DRAG_BODYS_TAG);
735 auto sp2 = makeBall(offset + Vec2(30, 0), 10);
736 auto sp2PhysicsBody = sp2->getPhysicsBody();
737 sp2PhysicsBody->setTag(DRAG_BODYS_TAG);
739 PhysicsJointPin* joint = PhysicsJointPin::construct(sp1PhysicsBody, sp2PhysicsBody, offset);
740 getPhysicsWorld()->addJoint(joint);
749 auto sp1 = makeBall(offset - Vec2(30.0f, 0.0f), 10);
750 auto sp1PhysicsBody = sp1->getPhysicsBody();
751 sp1PhysicsBody->setTag(DRAG_BODYS_TAG);
753 auto sp2 = makeBox(offset + Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
754 auto sp2PhysicsBody = sp2->getPhysicsBody();
755 sp2PhysicsBody->setTag(DRAG_BODYS_TAG);
757 PhysicsJointFixed* joint = PhysicsJointFixed::construct(sp1PhysicsBody, sp2PhysicsBody, offset);
758 getPhysicsWorld()->addJoint(joint);
766 auto sp1 = makeBall(offset - Vec2(30.0f, 0.0f), 10);
767 auto sp1PhysicsBody = sp1->getPhysicsBody();
768 sp1PhysicsBody->setTag(DRAG_BODYS_TAG);
770 auto sp2 = makeBox(offset + Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
771 auto sp2PhysicsBody = sp2->getPhysicsBody();
772 sp2PhysicsBody->setTag(DRAG_BODYS_TAG);
774 PhysicsJointDistance* joint = PhysicsJointDistance::construct(sp1PhysicsBody, sp2PhysicsBody, Point::ZERO, Point::ZERO);
775 getPhysicsWorld()->addJoint(joint);
783 auto sp1 = makeBall(offset - Vec2(30.0f, 0.0f), 10);
784 auto sp1PhysicsBody = sp1->getPhysicsBody();
785 sp1PhysicsBody->setTag(DRAG_BODYS_TAG);
787 auto sp2 = makeBox(offset + Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
788 auto sp2PhysicsBody = sp2->getPhysicsBody();
789 sp2PhysicsBody->setTag(DRAG_BODYS_TAG);
791 PhysicsJointLimit* joint = PhysicsJointLimit::construct(sp1PhysicsBody, sp2PhysicsBody, Point::ZERO, Point::ZERO, 30.0f, 60.0f);
792 getPhysicsWorld()->addJoint(joint);
800 auto sp1 = makeBall(offset - Vec2(30.0f, 0.0f), 10);
801 auto sp1PhysicsBody = sp1->getPhysicsBody();
802 sp1PhysicsBody->setTag(DRAG_BODYS_TAG);
804 auto sp2 = makeBox(offset + Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
805 auto sp2PhysicsBody = sp2->getPhysicsBody();
806 sp2PhysicsBody->setTag(DRAG_BODYS_TAG);
808 PhysicsJointSpring* joint = PhysicsJointSpring::construct(sp1PhysicsBody, sp2PhysicsBody, Point::ZERO, Point::ZERO, 500.0f, 0.3f);
809 getPhysicsWorld()->addJoint(joint);
817 auto sp1 = makeBall(offset - Vec2(30.0f, 0.0f), 10);
818 auto sp1PhysicsBody = sp1->getPhysicsBody();
819 sp1PhysicsBody->setTag(DRAG_BODYS_TAG);
821 auto sp2 = makeBox(offset + Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
822 auto sp2PhysicsBody = sp2->getPhysicsBody();
823 sp2PhysicsBody->setTag(DRAG_BODYS_TAG);
825 PhysicsJointGroove* joint = PhysicsJointGroove::construct(sp1PhysicsBody, sp2PhysicsBody, Vec2(30.0f, 15.0f), Vec2(30.0f, -15.0f), Vec2(-30.0f, 0.0f));
826 getPhysicsWorld()->addJoint(joint);
834 auto sp1 = makeBox(offset - Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
835 auto sp1PhysicsBody = sp1->getPhysicsBody();
836 sp1PhysicsBody->setTag(DRAG_BODYS_TAG);
838 auto sp2 = makeBox(offset + Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
839 auto sp2PhysicsBody = sp2->getPhysicsBody();
840 sp2PhysicsBody->setTag(DRAG_BODYS_TAG);
842 getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1PhysicsBody, box, sp1->getPosition()));
843 getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2PhysicsBody, box, sp2->getPosition()));
844 PhysicsJointRotarySpring* joint = PhysicsJointRotarySpring::construct(sp1PhysicsBody, sp2PhysicsBody, 3000.0f, 60.0f);
845 getPhysicsWorld()->addJoint(joint);
853 auto sp1 = makeBox(offset - Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
854 auto sp1PhysicsBody = sp1->getPhysicsBody();
855 sp1PhysicsBody->setTag(DRAG_BODYS_TAG);
857 auto sp2 = makeBox(offset + Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
858 auto sp2PhysicsBody = sp2->getPhysicsBody();
859 sp2PhysicsBody->setTag(DRAG_BODYS_TAG);
861 getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1PhysicsBody, box, sp1->getPosition()));
862 getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2PhysicsBody, box, sp2->getPosition()));
863 PhysicsJointRotaryLimit* joint = PhysicsJointRotaryLimit::construct(sp1PhysicsBody, sp2PhysicsBody, 0.0f,(
float) M_PI_2);
864 getPhysicsWorld()->addJoint(joint);
872 auto sp1 = makeBox(offset - Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
873 auto sp1PhysicsBody = sp1->getPhysicsBody();
874 sp1PhysicsBody->setTag(DRAG_BODYS_TAG);
876 auto sp2 = makeBox(offset + Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
877 auto sp2PhysicsBody = sp2->getPhysicsBody();
878 sp2PhysicsBody->setTag(DRAG_BODYS_TAG);
880 getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1PhysicsBody, box, sp1->getPosition()));
881 getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2PhysicsBody, box, sp2->getPosition()));
882 PhysicsJointRatchet* joint = PhysicsJointRatchet::construct(sp1PhysicsBody, sp2PhysicsBody, 0.0f, (
float)M_PI_2);
883 getPhysicsWorld()->addJoint(joint);
891 auto sp1 = makeBox(offset - Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
892 auto sp1PhysicsBody = sp1->getPhysicsBody();
893 sp1PhysicsBody->setTag(DRAG_BODYS_TAG);
895 auto sp2 = makeBox(offset + Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
896 auto sp2PhysicsBody = sp2->getPhysicsBody();
897 sp2PhysicsBody->setTag(DRAG_BODYS_TAG);
899 getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1PhysicsBody, box, sp1->getPosition()));
900 getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2PhysicsBody, box, sp2->getPosition()));
901 PhysicsJointGear* joint = PhysicsJointGear::construct(sp1PhysicsBody, sp2PhysicsBody, 0.0f, 2.0f);
902 getPhysicsWorld()->addJoint(joint);
910 auto sp1 = makeBox(offset - Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
911 auto sp1PhysicsBody = sp1->getPhysicsBody();
912 sp1PhysicsBody->setTag(DRAG_BODYS_TAG);
914 auto sp2 = makeBox(offset + Vec2(30.0f, 0.0f), Size(30.0f, 10.0f));
915 auto sp2PhysicsBody = sp2->getPhysicsBody();
916 sp2PhysicsBody->setTag(DRAG_BODYS_TAG);
918 getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1PhysicsBody, box, sp1->getPosition()));
919 getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2PhysicsBody, box, sp2->getPosition()));
920 PhysicsJointMotor* joint = PhysicsJointMotor::construct(sp1PhysicsBody, sp2PhysicsBody, (
float)M_PI_2);
921 getPhysicsWorld()->addJoint(joint);
934std::string PhysicsDemoJoints::title()
const
939void PhysicsDemoPump::onEnter()
941 PhysicsDemo::onEnter();
946 auto touchListener = EventListenerTouchOneByOne::create();
947 touchListener->onTouchBegan = CC_CALLBACK_2(PhysicsDemoPump::onTouchBegan,
this);
948 touchListener->onTouchMoved = CC_CALLBACK_2(PhysicsDemoPump::onTouchMoved,
this);
949 touchListener->onTouchEnded = CC_CALLBACK_2(PhysicsDemoPump::onTouchEnded,
this);
950 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,
this);
953 auto node = Node::create();
954 auto nodeBody = PhysicsBody::create();
955 node->addComponent(nodeBody);
956 nodeBody->setDynamic(
false);
958 PhysicsMaterial staticMaterial(PHYSICS_INFINITY, 0, 0.5f);
967 nodeBody->setCategoryBitmask(0x01);
968 node->setPosition(Vec2::ZERO);
969 this->addChild(node);
972 for (
int i = 0; i < 6; ++i)
974 auto ball = makeBall(
VisibleRect::leftTop() + Vec2(75 + CCRANDOM_0_1() * 90, 0.0f), 22, PhysicsMaterial(0.05f, 0.0f, 0.1f));
975 ball->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
988 auto pump = Node::create();
989 auto center = PhysicsShape::getPolygonCenter(vec, 4);
990 pump->setPosition(center);
991 auto pumpBody = PhysicsBody::createPolygon(vec, 4, PHYSICSBODY_MATERIAL_DEFAULT, -center);
992 pump->addComponent(pumpBody);
993 this->addChild(pump);
994 pumpBody->setCategoryBitmask(0x02);
995 pumpBody->setGravityEnable(
false);
998 auto sgearBody = PhysicsBody::createCircle(44);
999 sgearBody->setCategoryBitmask(0x04);
1000 sgearBody->setCollisionBitmask(0x04);
1001 sgearBody->setTag(1);
1002 auto sgear = Node::create();
1003 sgear->addComponent(sgearBody);
1005 this->addChild(sgear);
1007 _physicsWorld->addJoint(PhysicsJointPin::construct(nodeBody, sgearBody, sgear->getPosition()));
1008 _physicsWorld->addJoint(PhysicsJointDistance::construct(pumpBody, sgearBody, Vec2(0.0f, 0.0f), Vec2(0.0f, -44.0f)));
1011 auto bgearBody = PhysicsBody::createCircle(100);
1012 bgearBody->setCategoryBitmask(0x04);
1013 auto bgear = Node::create();
1014 bgear->addComponent(bgearBody);
1016 this->addChild(bgear);
1018 _physicsWorld->addJoint(PhysicsJointPin::construct(bgearBody, nodeBody, bgear->getPosition()));
1019 _physicsWorld->addJoint(PhysicsJointGear::construct(sgearBody, bgearBody, (
float)-M_PI_2, -2.0f));
1023 Vec2 segCenter = (seg[1] + seg[0]) / 2;
1024 seg[1] -= segCenter;
1025 seg[0] -= segCenter;
1027 auto pluggerBody = PhysicsBody::createEdgeSegment(seg[0], seg[1], PhysicsMaterial(0.01f, 0.0f, 0.5f), 20);
1028 pluggerBody->setDynamic(
true);
1029 pluggerBody->setMass(30);
1030 pluggerBody->setMoment(100000);
1031 pluggerBody->setCategoryBitmask(0x02);
1032 auto plugger = Node::create();
1033 plugger->addComponent(pluggerBody);
1034 plugger->setPosition(segCenter);
1035 this->addChild(plugger);
1037 sgearBody->setCollisionBitmask(0x04 | 0x01);
1038 _physicsWorld->addJoint(PhysicsJointPin::construct(nodeBody, pluggerBody,
VisibleRect::leftBottom() + Vec2(75.0f, -90.0f)));
1039 _physicsWorld->addJoint(PhysicsJointDistance::construct(pluggerBody, sgearBody, Vec2::ZERO, Vec2(44.0f, 0.0f)));
1042void PhysicsDemoPump::update(
float delta)
1044 for (
const auto& body : _physicsWorld->getAllBodies())
1046 if (body->getTag() == DRAG_BODYS_TAG && body->getPosition().y < 0.0f)
1048 if (body->getNode()!=
nullptr)
1053 body->setVelocity(Vec2(0.0f, 0.0f));
1057 PhysicsBody* gear = _physicsWorld->getBody(1);
1059 if (gear !=
nullptr)
1061 if (_distance != 0.0f)
1063 _rotationV += _distance / 2500.0f;
1065 if (_rotationV > 30) _rotationV = 30.0f;
1066 if (_rotationV < -30) _rotationV = -30.0f;
1069 gear->setAngularVelocity(_rotationV);
1070 _rotationV *= 0.995f;
1074bool PhysicsDemoPump::onTouchBegan(Touch* touch, Event* event)
1076 PhysicsDemo::onTouchBegan(touch, event);
1083void PhysicsDemoPump::onTouchMoved(Touch* touch, Event* event)
1085 PhysicsDemo::onTouchMoved(touch, event);
1090void PhysicsDemoPump::onTouchEnded(Touch* touch, Event* event)
1092 PhysicsDemo::onTouchEnded(touch, event);
1097std::string PhysicsDemoPump::title()
const
1102std::string PhysicsDemoPump::subtitle()
const
1104 return "touch screen on left or right";
1107void PhysicsDemoOneWayPlatform::onEnter()
1109 PhysicsDemo::onEnter();
1111 auto touchListener = EventListenerTouchOneByOne::create();
1112 touchListener->onTouchBegan = CC_CALLBACK_2(PhysicsDemoOneWayPlatform::onTouchBegan,
this);
1113 touchListener->onTouchMoved = CC_CALLBACK_2(PhysicsDemoOneWayPlatform::onTouchMoved,
this);
1114 touchListener->onTouchEnded = CC_CALLBACK_2(PhysicsDemoOneWayPlatform::onTouchEnded,
this);
1115 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,
this);
1117 auto ground = Node::create();
1120 this->addChild(ground);
1123 auto platformBody = platform->getPhysicsBody();
1124 platformBody->setDynamic(
false);
1125 platformBody->setContactTestBitmask(0xFFFFFFFF);
1126 this->addChild(platform);
1129 auto ballBody = ball->getPhysicsBody();
1130 ballBody->setVelocity(Vec2(0.0f, 150.0f));
1131 ballBody->setTag(DRAG_BODYS_TAG);
1132 ballBody->setMass(1.0f);
1133 ballBody->setContactTestBitmask(0xFFFFFFFF);
1134 this->addChild(ball);
1136 auto contactListener = EventListenerPhysicsContactWithBodies::create(platformBody, ballBody);
1137 contactListener->onContactBegin = CC_CALLBACK_1(PhysicsDemoOneWayPlatform::onContactBegin,
this);
1138 _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener,
this);
1141bool PhysicsDemoOneWayPlatform::onContactBegin(PhysicsContact& contact)
1143 return contact.getContactData()->normal.y < 0;
1146std::string PhysicsDemoOneWayPlatform::title()
const
1148 return "One Way Platform";
1151void PhysicsDemoSlice::onEnter()
1153 PhysicsDemo::onEnter();
1158 auto touchListener = EventListenerTouchOneByOne::create();
1159 touchListener->onTouchBegan = [](Touch* , Event* )->
bool{
return true; };
1160 touchListener->onTouchEnded = CC_CALLBACK_2(PhysicsDemoSlice::onTouchEnded,
this);
1161 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,
this);
1163 auto ground = Node::create();
1165 this->addChild(ground);
1167 auto box = Node::create();
1168 Vec2 points[4] = {Vec2(-100.0f, -100.0f), Vec2(-100.0f, 100.0f), Vec2(100.0f, 100.0f), Vec2(100.0f, -100.0f)};
1169 box->addComponent(PhysicsBody::createPolygon(points, 4));
1171 box->getPhysicsBody()->setTag(_sliceTag);
1175bool PhysicsDemoSlice::slice(PhysicsWorld &,
const PhysicsRayCastInfo& info,
void* )
1177 if (info.shape->getBody()->getTag() != _sliceTag)
1182 if (!info.shape->containsPoint(info.start) && !info.shape->containsPoint(info.end))
1184 Vec2 normal = info.end - info.start;
1185 normal = normal.getPerp().getNormalized();
1186 float dist = info.start.dot(normal);
1188 clipPoly(
dynamic_cast<PhysicsShapePolygon*
>(info.shape), normal, dist);
1189 clipPoly(
dynamic_cast<PhysicsShapePolygon*
>(info.shape), -normal, -dist);
1191 info.shape->getBody()->removeFromWorld();
1197void PhysicsDemoSlice::clipPoly(PhysicsShapePolygon* shape, Vec2 normal,
float distance)
1199 PhysicsBody* body = shape->getBody();
1200 int count = shape->getPointsCount();
1201 int pointsCount = 0;
1202 Vec2* points =
new (std::nothrow) Vec2[count + 1];
1204 for (
int i=0, j=count-1; i<count; j=i, ++i)
1206 Vec2 a = body->local2World(shape->getPoint(j));
1207 float aDist = a.dot(normal) - distance;
1211 points[pointsCount] = a;
1215 Vec2 b = body->local2World(shape->getPoint(i));
1216 float bDist = b.dot(normal) - distance;
1218 if (aDist*bDist < 0.0f)
1220 float t = std::fabs(aDist)/(std::fabs(aDist) + std::fabs(bDist));
1221 points[pointsCount] = a.lerp(b, t);
1226 Vec2 center = PhysicsShape::getPolygonCenter(points, pointsCount);
1227 Node* node = Node::create();
1228 PhysicsBody* polygon = PhysicsBody::createPolygon(points, pointsCount, PHYSICSBODY_MATERIAL_DEFAULT, -center);
1229 node->setPosition(center);
1230 node->addComponent(polygon);
1231 polygon->setVelocity(body->getVelocityAtWorldPoint(center));
1232 polygon->setAngularVelocity(body->getAngularVelocity());
1233 polygon->setTag(_sliceTag);
1239void PhysicsDemoSlice::onTouchEnded(Touch *touch, Event* )
1241 auto func = CC_CALLBACK_3(PhysicsDemoSlice::slice,
this);
1242 getPhysicsWorld()->rayCast(func, touch->getStartLocation(), touch->getLocation(),
nullptr);
1245std::string PhysicsDemoSlice::title()
const
1250std::string PhysicsDemoSlice::subtitle()
const
1252 return "click and drag to slice up the block";
1255void PhysicsDemoBug3988::onEnter()
1257 PhysicsDemo::onEnter();
1259 _physicsWorld->setGravity(Vec2::ZERO);
1261 auto ball = Sprite::create(
"Images/YellowSquare.png");
1263 ball->setRotation(30.0f);
1264 this->addChild(ball);
1266 auto physicsBall = makeBox(
VisibleRect::center() + Vec2(100.0f, 0.0f), Size(100.0f, 100.0f));
1267 physicsBall->setRotation(30.0f);
1268 this->addChild(physicsBall);
1271std::string PhysicsDemoBug3988::title()
const
1276std::string PhysicsDemoBug3988::subtitle()
const
1278 return "All the Rectangles should have same rotation angle";
1281void PhysicsContactTest::onEnter()
1283 PhysicsDemo::onEnter();
1284 _physicsWorld->setGravity(Vec2::ZERO);
1289 _yellowTriangleNum = 50;
1290 _blueTriangleNum = 50;
1293 MenuItemFont::setFontSize(65);
1294 auto decrease1 = MenuItemFont::create(
" - ", CC_CALLBACK_1(PhysicsContactTest::onDecrease,
this));
1295 decrease1->setColor(Color3B(0, 200, 20));
1296 auto increase1 = MenuItemFont::create(
" + ", CC_CALLBACK_1(PhysicsContactTest::onIncrease,
this));
1297 increase1->setColor(Color3B(0, 200, 20));
1298 decrease1->setTag(1);
1299 increase1->setTag(1);
1301 float prevMenuPos = getSubtitleLable()->getPosition().y - getSubtitleLable()->getContentSize().height;
1302 float menuStep = (getSubtitleLable()->getPosition().y -getRestartTestItem()->getPosition().y)*0.25f;
1303 auto menu1 = Menu::create(decrease1, increase1,
nullptr);
1304 menu1->alignItemsHorizontally();
1305 menu1->setPosition(Vec2(s.width / 2, prevMenuPos));
1308 auto label = Label::createWithTTF(
"yellow box",
"fonts/arial.ttf", 32);
1310 label->setPosition(Vec2(s.width / 2 - 150, prevMenuPos));
1312 auto decrease2 = MenuItemFont::create(
" - ", CC_CALLBACK_1(PhysicsContactTest::onDecrease,
this));
1313 decrease2->setColor(Color3B(0, 200, 20));
1314 auto increase2 = MenuItemFont::create(
" + ", CC_CALLBACK_1(PhysicsContactTest::onIncrease,
this));
1315 increase2->setColor(Color3B(0, 200, 20));
1316 decrease2->setTag(2);
1317 increase2->setTag(2);
1319 auto menu2 = Menu::create(decrease2, increase2,
nullptr);
1320 menu2->alignItemsHorizontally();
1321 menu2->setPosition(Vec2(s.width / 2, prevMenuPos -= menuStep));
1324 label = Label::createWithTTF(
"blue box",
"fonts/arial.ttf", 32);
1326 label->setPosition(Vec2(s.width / 2 - 150, prevMenuPos));
1328 auto decrease3 = MenuItemFont::create(
" - ", CC_CALLBACK_1(PhysicsContactTest::onDecrease,
this));
1329 decrease3->setColor(Color3B(0, 200, 20));
1330 auto increase3 = MenuItemFont::create(
" + ", CC_CALLBACK_1(PhysicsContactTest::onIncrease,
this));
1331 increase3->setColor(Color3B(0, 200, 20));
1332 decrease3->setTag(3);
1333 increase3->setTag(3);
1335 auto menu3 = Menu::create(decrease3, increase3,
nullptr);
1336 menu3->alignItemsHorizontally();
1337 menu3->setPosition(Vec2(s.width / 2, prevMenuPos -= menuStep));
1340 label = Label::createWithTTF(
"yellow triangle",
"fonts/arial.ttf", 32);
1342 label->setPosition(Vec2(s.width / 2 - 150, prevMenuPos));
1344 auto decrease4 = MenuItemFont::create(
" - ", CC_CALLBACK_1(PhysicsContactTest::onDecrease,
this));
1345 decrease4->setColor(Color3B(0, 200, 20));
1346 auto increase4 = MenuItemFont::create(
" + ", CC_CALLBACK_1(PhysicsContactTest::onIncrease,
this));
1347 increase4->setColor(Color3B(0, 200, 20));
1348 decrease4->setTag(4);
1349 increase4->setTag(4);
1351 auto menu4 = Menu::create(decrease4, increase4,
nullptr);
1352 menu4->alignItemsHorizontally();
1353 menu4->setPosition(Vec2(s.width / 2, prevMenuPos -= menuStep));
1356 label = Label::createWithTTF(
"blue triangle",
"fonts/arial.ttf", 32);
1358 label->setPosition(Vec2(s.width / 2 - 150, prevMenuPos));
1363void PhysicsContactTest::onDecrease(Ref* sender)
1365 switch (
dynamic_cast<Node*
>(sender)->getTag())
1368 if (_yellowBoxNum > 0) _yellowBoxNum -= 50;
1371 if (_blueBoxNum > 0) _blueBoxNum -= 50;
1374 if (_yellowTriangleNum > 0) _yellowTriangleNum -= 50;
1377 if (_blueTriangleNum > 0) _blueTriangleNum -= 50;
1387void PhysicsContactTest::onIncrease(Ref* sender)
1389 switch (
dynamic_cast<Node*
>(sender)->getTag())
1392 _yellowBoxNum += 50;
1398 _yellowTriangleNum += 50;
1401 _blueTriangleNum += 50;
1411void PhysicsContactTest::resetTest()
1413 removeChildByTag(10);
1414 auto root = Node::create();
1416 this->addChild(root);
1419 float prevMenuPos = getSubtitleLable()->getPosition().y - getSubtitleLable()->getContentSize().height;
1420 float menuStep = (getSubtitleLable()->getPosition().y - getRestartTestItem()->getPosition().y)*0.25f;
1424 sprintf(buffer,
"%d", _yellowBoxNum);
1425 auto label = Label::createWithTTF(buffer,
"fonts/arial.ttf", 32);
1426 root->addChild(label, 1);
1427 label->setPosition(Vec2(s.width / 2, prevMenuPos));
1429 sprintf(buffer,
"%d", _blueBoxNum);
1430 label = Label::createWithTTF(buffer,
"fonts/arial.ttf", 32);
1431 root->addChild(label, 1);
1432 label->setPosition(Vec2(s.width / 2, prevMenuPos-=menuStep));
1434 sprintf(buffer,
"%d", _yellowTriangleNum);
1435 label = Label::createWithTTF(buffer,
"fonts/arial.ttf", 32);
1436 root->addChild(label, 1);
1437 label->setPosition(Vec2(s.width / 2, prevMenuPos-=menuStep));
1439 sprintf(buffer,
"%d", _blueTriangleNum);
1440 label = Label::createWithTTF(buffer,
"fonts/arial.ttf", 32);
1441 root->addChild(label, 1);
1442 label->setPosition(Vec2(s.width / 2, prevMenuPos-=menuStep));
1444 auto wall = Node::create();
1447 root->addChild(wall);
1449 auto contactListener = EventListenerPhysicsContact::create();
1450 contactListener->onContactBegin = CC_CALLBACK_1(PhysicsContactTest::onContactBegin,
this);
1451 _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener,
this);
1454 for (
int i = 0; i < _yellowBoxNum; ++i)
1456 Size size(10 + CCRANDOM_0_1() * 10, 10 + CCRANDOM_0_1() * 10);
1458 Vec2 position = Vec2(winSize.width, winSize.height) - Vec2(size.width, size.height);
1459 position.x = position.x * CCRANDOM_0_1();
1460 position.y = position.y * CCRANDOM_0_1();
1462 Vec2 velocity((
float)(CCRANDOM_0_1() - 0.5) * 200, (
float)(CCRANDOM_0_1() - 0.5) * 200);
1463 auto box = makeBox(position, size, 1, PhysicsMaterial(0.1f, 1, 0.0f));
1464 auto boxBody = box->getPhysicsBody();
1465 boxBody->setVelocity(velocity);
1466 boxBody->setCategoryBitmask(0x01);
1467 boxBody->setContactTestBitmask(0x04);
1468 boxBody->setCollisionBitmask(0x03);
1469 root->addChild(box);
1473 for (
int i = 0; i < _blueBoxNum; ++i)
1475 Size size(10 + CCRANDOM_0_1() * 10, 10 + CCRANDOM_0_1() * 10);
1477 Vec2 position = Vec2(winSize.width, winSize.height) - Vec2(size.width, size.height);
1478 position.x = position.x * CCRANDOM_0_1();
1479 position.y = position.y * CCRANDOM_0_1();
1481 Vec2 velocity((
float)(CCRANDOM_0_1() - 0.5) * 200, (
float)(CCRANDOM_0_1() - 0.5) * 200);
1482 auto box = makeBox(position, size, 2, PhysicsMaterial(0.1f, 1, 0.0f));
1483 auto boxBody = box->getPhysicsBody();
1484 boxBody->setVelocity(velocity);
1485 boxBody->setCategoryBitmask(0x02);
1486 boxBody->setContactTestBitmask(0x08);
1487 boxBody->setCollisionBitmask(0x01);
1488 root->addChild(box);
1492 for (
int i = 0; i < _yellowTriangleNum; ++i)
1494 Size size(10 + CCRANDOM_0_1() * 10, 10 + CCRANDOM_0_1() * 10);
1496 Vec2 position = Vec2(winSize.width, winSize.height) - Vec2(size.width, size.height);
1497 position.x = position.x * CCRANDOM_0_1();
1498 position.y = position.y * CCRANDOM_0_1();
1500 Vec2 velocity((
float)(CCRANDOM_0_1() - 0.5) * 300, (
float)(CCRANDOM_0_1() - 0.5) * 300);
1501 auto triangle = makeTriangle(position, size, 1, PhysicsMaterial(0.1f, 1, 0.0f));
1502 auto triangleBody = triangle->getPhysicsBody();
1503 triangleBody->setVelocity(velocity);
1504 triangleBody->setCategoryBitmask(0x04);
1505 triangleBody->setContactTestBitmask(0x01);
1506 triangleBody->setCollisionBitmask(0x06);
1507 root->addChild(triangle);
1511 for (
int i = 0; i < _blueTriangleNum; ++i)
1513 Size size(10 + CCRANDOM_0_1() * 10, 10 + CCRANDOM_0_1() * 10);
1515 Vec2 position = Vec2(winSize.width, winSize.height) - Vec2(size.width, size.height);
1516 position.x = position.x * CCRANDOM_0_1();
1517 position.y = position.y * CCRANDOM_0_1();
1519 Vec2 velocity((
float)(CCRANDOM_0_1() - 0.5) * 300, (
float)(CCRANDOM_0_1() - 0.5) * 300);
1520 auto triangle = makeTriangle(position, size, 2, PhysicsMaterial(0.1f, 1, 0.0f));
1521 auto triangleBody = triangle->getPhysicsBody();
1522 triangleBody->setVelocity(velocity);
1523 triangleBody->setCategoryBitmask(0x08);
1524 triangleBody->setContactTestBitmask(0x02);
1525 triangleBody->setCollisionBitmask(0x01);
1526 root->addChild(triangle);
1530bool PhysicsContactTest::onContactBegin(PhysicsContact& contact)
1532 PhysicsBody* a = contact.getShapeA()->getBody();
1533 PhysicsBody* b = contact.getShapeB()->getBody();
1534 PhysicsBody* body = (a->getCategoryBitmask() == 0x04 || a->getCategoryBitmask() == 0x08) ? a : b;
1535 CC_ASSERT(body->getCategoryBitmask() == 0x04 || body->getCategoryBitmask() == 0x08);
1540std::string PhysicsContactTest::title()
const
1542 return "Contact Test";
1545std::string PhysicsContactTest::subtitle()
const
1547 return "should not crash";
1550void PhysicsPositionRotationTest::onEnter()
1552 PhysicsDemo::onEnter();
1554 _physicsWorld->setGravity(Point::ZERO);
1556 auto touchListener = EventListenerTouchOneByOne::create();
1557 touchListener->onTouchBegan = CC_CALLBACK_2(PhysicsDemo::onTouchBegan,
this);
1558 touchListener->onTouchMoved = CC_CALLBACK_2(PhysicsDemo::onTouchMoved,
this);
1559 touchListener->onTouchEnded = CC_CALLBACK_2(PhysicsDemo::onTouchEnded,
this);
1560 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,
this);
1562 auto wall = Node::create();
1568 auto anchorNode = Sprite::create(
"Images/YellowSquare.png");
1570 anchorNode->setPosition(100, 100);
1571 anchorNode->setScale(0.25);
1572 anchorNode->addComponent(PhysicsBody::createBox(anchorNode->getContentSize()));
1573 anchorNode->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
1574 addChild(anchorNode);
1577 auto parent = Sprite::create(
"Images/YellowSquare.png");
1578 parent->setPosition(200, 100);
1579 parent->setScale(0.25);
1580 parent->addComponent(PhysicsBody::createBox(parent->getContentSize()));
1581 parent->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
1584 auto leftBall = Sprite::create(
"Images/ball.png");
1585 leftBall->setPosition(-30, 0);
1586 leftBall->Node::setScale(2);
1587 leftBall->addComponent(PhysicsBody::createCircle(leftBall->getContentSize().width/2));
1588 leftBall->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
1589 parent->addChild(leftBall);
1592 auto offsetPosNode = Sprite::create(
"Images/YellowSquare.png");
1593 offsetPosNode->setPosition(100, 200);
1594 auto body = PhysicsBody::createBox(offsetPosNode->getContentSize() / 2);
1595 offsetPosNode->addComponent(body);
1596 body->setPositionOffset(-Vec2(offsetPosNode->getContentSize() / 2));
1597 body->setRotationOffset(45);
1598 body->setTag(DRAG_BODYS_TAG);
1599 addChild(offsetPosNode);
1604std::string PhysicsPositionRotationTest::title()
const
1606 return "Position/Rotation Test";
1609void PhysicsSetGravityEnableTest::onEnter()
1611 PhysicsDemo::onEnter();
1613 auto touchListener = EventListenerTouchOneByOne::create();
1614 touchListener->onTouchBegan = CC_CALLBACK_2(PhysicsDemo::onTouchBegan,
this);
1615 touchListener->onTouchMoved = CC_CALLBACK_2(PhysicsDemo::onTouchMoved,
this);
1616 touchListener->onTouchEnded = CC_CALLBACK_2(PhysicsDemo::onTouchEnded,
this);
1617 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,
this);
1620 auto wall = Node::create();
1626 auto commonBox = makeBox(Vec2(100, 100), Size(50, 50), 1);
1627 commonBox->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
1628 commonBox->getPhysicsBody()->setGravityEnable(
true);
1629 addChild(commonBox);
1631 auto box = makeBox(Vec2(200, 100), Size(50, 50), 2);
1632 auto boxBody = box->getPhysicsBody();
1633 boxBody->setMass(20);
1634 boxBody->setTag(DRAG_BODYS_TAG);
1635 boxBody->setGravityEnable(
false);
1638 auto ball = makeBall(Vec2(200, 200), 50);
1640 auto ballBody = ball->getPhysicsBody();
1641 ballBody->setTag(DRAG_BODYS_TAG);
1642 ballBody->setGravityEnable(
false);
1643 ballBody->setMass(50);
1646 scheduleOnce(CC_SCHEDULE_SELECTOR(PhysicsSetGravityEnableTest::onScheduleOnce), 1.0);
1649void PhysicsSetGravityEnableTest::onScheduleOnce(
float )
1651 auto ball = getChildByTag(2);
1652 ball->getPhysicsBody()->setMass(200);
1654 _physicsWorld->setGravity(Vec2(0, -98));
1657std::string PhysicsSetGravityEnableTest::title()
const
1659 return "Set Gravity Enable Test";
1662std::string PhysicsSetGravityEnableTest::subtitle()
const
1664 return "only yellow box drop down";
1667void PhysicsDemoBug5482::onEnter()
1669 PhysicsDemo::onEnter();
1673 auto touchListener = EventListenerTouchOneByOne::create();
1674 touchListener->onTouchBegan = CC_CALLBACK_2(PhysicsDemo::onTouchBegan,
this);
1675 touchListener->onTouchMoved = CC_CALLBACK_2(PhysicsDemo::onTouchMoved,
this);
1676 touchListener->onTouchEnded = CC_CALLBACK_2(PhysicsDemo::onTouchEnded,
this);
1677 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,
this);
1682 auto wall = Node::create();
1688 MenuItemFont::setFontSize(18);
1689 _button = MenuItemFont::create(
"Set Body To A", CC_CALLBACK_1(PhysicsDemoBug5482::changeBodyCallback,
this));
1691 auto menu = Menu::create(_button,
nullptr);
1692 this->addChild(menu);
1694 _nodeA = Sprite::create(
"Images/YellowSquare.png");
1696 this->addChild(_nodeA);
1698 _nodeB = Sprite::create(
"Images/YellowSquare.png");
1700 this->addChild(_nodeB);
1702 _body = PhysicsBody::createBox(_nodeA->getContentSize());
1703 _body->setTag(DRAG_BODYS_TAG);
1707void PhysicsDemoBug5482::onExit()
1709 PhysicsDemo::onExit();
1713void PhysicsDemoBug5482::changeBodyCallback(Ref* )
1715 Sprite* node = _bodyInA ? _nodeB : _nodeA;
1718 _button->setString(
"Set Body To A");
1722 _button->setString(
"Set Body To B");
1725 if (_body->getOwner())
1727 _body->getOwner()->removeComponent(_body);
1729 node->addComponent(_body);
1730 _bodyInA = !_bodyInA;
1733std::string PhysicsDemoBug5482::title()
const
1735 return "bug 5482: setPhysicsBodyTest";
1738std::string PhysicsDemoBug5482::subtitle()
const
1740 return "change physics body to the other.";
1743void PhysicsFixedUpdate::onEnter()
1745 PhysicsDemo::onEnter();
1748 _physicsWorld->setGravity(Point::ZERO);
1751 auto wall = Node::create();
1754 this->addChild(wall);
1758 scheduleOnce(CC_SCHEDULE_SELECTOR(PhysicsFixedUpdate::updateStart), 2);
1761void PhysicsFixedUpdate::addBall()
1763 auto ball = Sprite::create(
"Images/ball.png");
1764 ball->setPosition(100, 100);
1765 auto ballBody = PhysicsBody::createCircle(ball->getContentSize().width / 2, PhysicsMaterial(0.1f, 1, 0.0f));
1766 ball->addComponent(ballBody);
1767 ballBody->setTag(DRAG_BODYS_TAG);
1768 ballBody->setVelocity(Point(1000, 20));
1769 this->addChild(ball);
1772void PhysicsFixedUpdate::updateStart(
float )
1776 _physicsWorld->setFixedUpdateRate(180);
1779void PhysicsFixedUpdate::update(
float )
1783 for (
int i = 0; i < 3; ++i)
1785 _physicsWorld->step(1/180.0f);
1789std::string PhysicsFixedUpdate::title()
const
1791 return "Fixed Update Test";
1794std::string PhysicsFixedUpdate::subtitle()
const
1796 return "The second ball should not run across the wall";
1799bool PhysicsTransformTest::onTouchBegan(Touch *touch, Event* )
1801 _parentSprite->setPosition(_rootLayer->convertTouchToNodeSpace(touch));
1805void PhysicsTransformTest::onEnter()
1807 PhysicsDemo::onEnter();
1809 _physicsWorld->setGravity(Point::ZERO);
1811 auto touchListener = EventListenerTouchOneByOne::create();
1812 touchListener->onTouchBegan = CC_CALLBACK_2(PhysicsTransformTest::onTouchBegan,
this);
1813 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,
this);
1815 _rootLayer = Layer::create();
1816 addChild(_rootLayer);
1818 auto wall = Node::create();
1821 _rootLayer->addChild(wall);
1824 _parentSprite = Sprite::create(
"Images/YellowSquare.png");
1825 _parentSprite->setPosition(200, 100);
1826 _parentSprite->setScale(0.25);
1827 _parentSprite->addComponent(PhysicsBody::createBox(_parentSprite->getContentSize(), PhysicsMaterial(0.1f, 1.0f, 0.0f)));
1828 _parentSprite->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
1829 _parentSprite->setTag(1);
1830 _rootLayer->addChild(_parentSprite);
1832 auto leftBall = Sprite::create(
"Images/ball.png");
1833 leftBall->setPosition(-30, 0);
1834 leftBall->setScale(2);
1835 leftBall->addComponent(PhysicsBody::createCircle(leftBall->getContentSize().width/2, PhysicsMaterial(0.1f, 1.0f, 0.0f)));
1836 leftBall->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
1837 _parentSprite->addChild(leftBall);
1839 ScaleTo* scaleTo = ScaleTo::create(2.0, 0.5);
1840 ScaleTo* scaleBack = ScaleTo::create(2.0, 1.0);
1841 _parentSprite->runAction(RepeatForever::create(Sequence::create(scaleTo, scaleBack,
nullptr)));
1843 auto normal = Sprite::create(
"Images/YellowSquare.png");
1844 normal->setPosition(300, 100);
1845 normal->setScale(0.25, 0.5);
1846 normal->addComponent(PhysicsBody::createBox(normal->getContentSize(), PhysicsMaterial(0.1f, 1.0f, 0.0f)));
1847 normal->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
1848 _rootLayer->addChild(normal);
1850 auto bullet = Sprite::create(
"Images/ball.png");
1851 bullet->setPosition(200, 200);
1852 bullet->addComponent(PhysicsBody::createCircle(bullet->getContentSize().width/2, PhysicsMaterial(0.1f, 1.0f, 0.0f)));
1853 bullet->getPhysicsBody()->setVelocity(Vec2(100.0f, 100.0f));
1854 _rootLayer->addChild(bullet);
1856 MoveBy* move = MoveBy::create(2.0f, Vec2(100.0f, 100.0f));
1857 MoveBy* move2 = MoveBy::create(2.0f, Vec2(-200.0f, 0.0f));
1858 MoveBy* move3 = MoveBy::create(2.0f, Vec2(100.0f, -100.0f));
1859 ScaleTo* scale = ScaleTo::create(3.0f, 0.3f);
1860 ScaleTo* scale2 = ScaleTo::create(3.0f, 1.0f);
1862 RotateBy* rotate = RotateBy::create(6.0f, 360);
1864 _rootLayer->runAction(RepeatForever::create(Sequence::create(move, move2, move3,
nullptr)));
1865 _rootLayer->runAction(RepeatForever::create(Sequence::create(scale, scale2,
nullptr)));
1866 _rootLayer->runAction(RepeatForever::create(rotate));
1869std::string PhysicsTransformTest::title()
const
1871 return "Physics transform test";
1874void PhysicsIssue9959::onEnter()
1876 PhysicsDemo::onEnter();
1878 auto origin = Director::getInstance()->getVisibleOrigin();
1879 auto visibleSize = Director::getInstance()->getVisibleSize();
1881 auto scale9Sprite1 = ui::Scale9Sprite::create(
"Images/ball.png");
1882 scale9Sprite1->setPosition(origin + visibleSize/2);
1883 addChild(scale9Sprite1);
1884 scale9Sprite1->runAction(RepeatForever::create(Sequence::create(MoveBy::create(2.0f, Vec2(100.0f,0.0f)), MoveBy::create(2.0f, Vec2(-100.0f, 0.0f)), NULL)));
1886 auto scale9Sprite2 = ui::Scale9Sprite::create(
"Images/ball.png");
1887 scale9Sprite2->setPosition(origin + visibleSize/2 + Vec2(0.0f, 50.0f));
1888 addChild(scale9Sprite2);
1889 scale9Sprite2->runAction(RepeatForever::create(Sequence::create(ScaleTo::create(2.0f, 1.5f), ScaleTo::create(2.0f, 1.0f), NULL)));
1891 auto scale9Sprite3 = ui::Scale9Sprite::create(
"Images/ball.png");
1892 scale9Sprite3->setPosition(origin + visibleSize/2 + Vec2(0.0f, -50.0f));
1893 addChild(scale9Sprite3);
1894 scale9Sprite3->runAction(RepeatForever::create(RotateBy::create(2.0f, 360.0f)));
1897std::string PhysicsIssue9959::title()
const
1899 return "Reorder issue #9959";
1902std::string PhysicsIssue9959::subtitle()
const
1904 return "Test Scale9Sprite run scale/move/rotation action in physics scene";
1908void PhysicsIssue15932::onEnter()
1910 PhysicsDemo::onEnter();
1912 PhysicsBody *pb=PhysicsBody::createBox(Size(15,5),PhysicsMaterial(0.1f,0.0f,1.0f));
1913 this->addComponent(pb);
1914 this->removeComponent(pb);
1917std::string PhysicsIssue15932::title()
const
1919 return "Github issue #15932";
1922std::string PhysicsIssue15932::subtitle()
const
1924 return "addComponent()/removeComponent() should not crash";
#define ADD_TEST_CASE(__className__)
virtual void onEnter() override
static cocos2d::Vec2 top()
static cocos2d::Rect getVisibleRect()
static cocos2d::Vec2 leftTop()
static cocos2d::Vec2 center()
static cocos2d::Vec2 bottom()
static cocos2d::Vec2 rightTop()
static cocos2d::Vec2 left()
static cocos2d::Vec2 rightBottom()
static cocos2d::Vec2 leftBottom()
static cocos2d::Vec2 right()