Cocos2d-x 3.3 box2d测试-双轨抛物球

前端之家收集整理的这篇文章主要介绍了Cocos2d-x 3.3 box2d测试-双轨抛物球前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

上一篇的cocos2dx游戏制作,在做素材优化和想把AI的FSM改为简单的状态&行为树,还有代码的优化

从刚开始什么都不懂写了一堆自己都看不下去的代码--比如把所有控制写在一个层超级臃肿,到稍微了解了下设计,大幅优化和观察者模式的引入.先坑下.

这篇是Box2d的测试,结果是实验了类似愤怒小鸟的抛物运动,并有留下轨迹,第二次抛蓄力的时候会显示当前轨迹和前一次的轨迹.

每一次按下会把球放在当前坐标,蓄力不会移动球,这些小改下就可以用了.几乎每句都有注释,应该不需要解释了

GameLayer.h

  1. #ifndef _GAME_LAYER_H_
  2. #define _GAME_LAYER_H_
  3. #include "cocos2d.h"
  4. #include <Box2D/Box2D.h>
  5. USING_NS_CC;
  6. #define SCALE_RATIO 32.0
  7.  
  8. class GameLayer : public Layer,public b2ContactListener
  9. {
  10. public:
  11. GameLayer();
  12. ~GameLayer();
  13. virtual bool init();
  14. bool onTouchBegan(Touch* touch,Event* event);
  15. void onTouchMoved(Touch* touch,Event* event);
  16. void onTouchEnded(Touch* touch,Event* event);
  17. Sprite *ball;
  18. bool existBall;
  19. float ballX;
  20. float ballY;
  21. Vec2 dragOffsetStart;
  22. Vec2 dragOffsetEnd;
  23. Vec2 face;
  24. b2Body *ballBody;
  25. b2CircleShape ballShape;
  26. b2BodyDef ballBodyDef;
  27. void defineBall();
  28. b2World *world;
  29. float deltaTime;
  30. void addWall(float w,float h,float px,float py);
  31. CREATE_FUNC(GameLayer);
  32. void simulateTrajectory(b2Vec2 coord);
  33. private:
  34. void update(float dt);
  35. Sprite *points[10];
  36. Sprite *propoints[10];
  37. float powerMultiplier;
  38. };
  39.  
  40. #endif
GameLayer.cpp
  1. #include "GameLayer.h"
  2. GameLayer::GameLayer()
  3. {
  4. }
  5. GameLayer::~GameLayer()
  6. {
  7. }
  8. bool GameLayer::init()
  9. {
  10. bool ret = false;
  11. do {
  12. CC_BREAK_IF( !Layer::init());
  13. auto visibleSize = Director::getInstance()->getVisibleSize();
  14. auto listener = EventListenerTouchOneByOne::create();
  15. listener->setSwallowTouches(true);
  16.  
  17. listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan,this);
  18. listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved,this);
  19. listener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded,this);
  20.  
  21. _eventDispatcher->addEventListenerWithSceneGraPHPriority(listener,this);
  22.  
  23. existBall= false;
  24. ballX = 100;
  25. ballY = 100;
  26. ball =Sprite::create("ball.png");
  27. ball->setPosition(Vec2(ballX,ballY));
  28. this->addChild(ball);
  29.  
  30. b2Vec2 gravity = b2Vec2(0.0f,-10.0f);
  31. world = new b2World(gravity);
  32. addWall(visibleSize.width,10,visibleSize.width/2,visibleSize.height);//TOP
  33. addWall(visibleSize.width,(visibleSize.width / 2),0); //CEIL
  34. addWall(10,visibleSize.height,(visibleSize.height / 2) ); //LEFT
  35. addWall(10,visibleSize.width,(visibleSize.height / 2) ); //RIGHT
  36.  
  37. for (int i = 0 ; i <10; i++)
  38. {
  39. points[i] =Sprite::create("dot.png");
  40. this->addChild(points[i]);
  41. propoints[i] =Sprite::create("prodot.png");
  42. this->addChild(propoints[i]);
  43. }
  44. powerMultiplier=10;
  45.  
  46. this->scheduleUpdate();
  47.  
  48. ret = true;
  49. } while(0);
  50. return ret;
  51. }
  52.  
  53. void GameLayer::update(float dt)
  54. {
  55. int positionIterations = 10; //位置迭代
  56. int velocityIterations = 10;//速度迭代
  57. deltaTime = dt;//帧时间
  58. world->Step(dt,velocityIterations,positionIterations);
  59. for (b2Body *body = world->GetBodyList(); body != NULL; body = body->GetNext()) //所有的body实体
  60. if (body->GetUserData()) //存在绑定的精灵
  61. {
  62. Sprite *sprite = (Sprite *) body->GetUserData();
  63. sprite->setPosition(Vec2(body->GetPosition().x * SCALE_RATIO,body->GetPosition().y * SCALE_RATIO)); //将其从b2Body坐标转换至Vec2坐标
  64. sprite->setRotation(-1 * CC_RADIANS_TO_DEGREES(body->GetAngle())); //逆时针滚动
  65. }
  66. world->ClearForces();//如果不取消上一个力将继续存在,导致此次状态不作为继续滚
  67. world->DrawDebugData();
  68. }
  69. bool GameLayer::onTouchBegan(Touch* touch,Event* event)
  70. {
  71. dragOffsetStart = touch->getLocation();
  72. if (existBall)//若是存在上一个实体球,删除
  73. {
  74. world->DestroyBody(ballBody);
  75. }
  76. ball->setPosition(dragOffsetStart);//将ball这个精灵设置到当前坐标
  77. //清除原来的球的轨迹
  78. return true;
  79. }
  80.  
  81. void GameLayer::onTouchMoved(Touch* touch,Event* event)
  82. {
  83. dragOffsetEnd = touch->getLocation();
  84. float distance = dragOffsetStart.getDistance(dragOffsetEnd);
  85. Vec2 direction = (dragOffsetStart - dragOffsetEnd).getNormalized();
  86. face = (distance*direction)*powerMultiplier/SCALE_RATIO;//获得与初始坐标相反的向量,弹弓的反向力
  87. GameLayer::simulateTrajectory(b2Vec2(face.x,face.y));//模拟轨迹
  88. }
  89.  
  90. void GameLayer::onTouchEnded(Touch* touch,Event* event)
  91. {
  92. existBall = true;
  93. GameLayer::defineBall();
  94. ballBody->SetLinearVelocity(b2Vec2(face.x,face.y));
  95. //这个实体球存在,设定属性,设置线速度
  96. face = Vec2::ZERO;
  97. //不清除,下一次按下按键不移动也会飞
  98. for (int i = 0; i < 10; i++)
  99. {
  100. propoints[i]->setPosition(points[i]->getPosition());
  101. points[i]->setVisible(false);
  102. propoints[i]->setVisible(true);
  103. }
  104. }
  105. void GameLayer::defineBall() {
  106. //设置球轨迹
  107. ballShape.m_radius = 45 / SCALE_RATIO;//这个实体的半径
  108. b2FixtureDef ballFixture;//固定的设备
  109. ballFixture.density=10;//密度
  110. ballFixture.friction=0.8f;//摩擦
  111. ballFixture.restitution=0.6f;//恢复原状
  112. ballFixture.shape=&ballShape;//塑性--这个东西的形状,半径为45/像素格子大小的一个球
  113.  
  114. ballBodyDef.type= b2_dynamicBody;//刚体的类型,在这里设置为动态物体
  115. ballBodyDef.userData=ball;//映射body为ball,就是将这个物理实体绑定其那个ball精灵
  116.  
  117. ballBodyDef.position.Set(ball->getPosition().x/SCALE_RATIO,ball->getPosition().y/SCALE_RATIO);
  118. //坐标设定,由于Box2d中的单位是米,实际上是/PIXEL_TO_METER是一个比例尺,用来描述多少个像素对应1米,这里/SCALE_RATIO表示对应32个像素
  119.  
  120. ballBody = world->CreateBody(&ballBodyDef);//世界创建这个ballbody
  121. ballBody->CreateFixture(&ballFixture);//创建设备
  122. ballBody->SetGravityScale(10);//设置重力规模,这个实体受重力影响
  123. }
  124. void GameLayer::addWall(float w,float py) {
  125. //宽,高,X坐标,Y坐标
  126. b2PolygonShape floorShape;//多边形
  127. floorShape.SetAsBox(w/ SCALE_RATIO,h/ SCALE_RATIO);//设为一个Box
  128. b2FixtureDef floorFixture;
  129. floorFixture.density=0;
  130. floorFixture.friction=10;
  131. floorFixture.restitution=0.5;
  132. floorFixture.shape=&floorShape;//以上设定这个的物理属性
  133. b2BodyDef floorBodyDef;
  134. floorBodyDef.position.Set(px/ SCALE_RATIO,py/ SCALE_RATIO);//放置坐标
  135. b2Body *floorBody = world->CreateBody(&floorBodyDef);
  136. floorBody->CreateFixture(&floorFixture);
  137. //通过定义一个多边形确定了一个区域作为墙,没有绑定精灵图片所以是透明,如果绑定某燃烧火焰anmiation的话可以做成火墙等...
  138. }
  139. void GameLayer::simulateTrajectory(b2Vec2 coord)//模拟轨迹
  140. {
  141. GameLayer::defineBall();//定义球的实体
  142. ballBody->SetLinearVelocity(b2Vec2(coord.x,coord.y));//设置线速度为X
  143.  
  144. for (int i = 0; i < 10; i++)
  145. {
  146. world->Step(deltaTime,10);
  147. points[i]->setPosition(Vec2(ballBody->GetPosition().x*SCALE_RATIO,ballBody->GetPosition().y*SCALE_RATIO));
  148. //设置每一个轨迹小球应该在的地方
  149. points[i]->setVisible(true);
  150. }
  151. world->ClearForces();//清除世界的力
  152. world->DestroyBody(ballBody);//摧毁这个实体
  153. //轨迹模拟需要通过原来定义的球的实体模拟获得,每次模拟之后删除
  154. }

效果图:

资源:

猜你在找的Cocos2d-x相关文章