cocos2dx虚拟摇杆制作【极力推荐】

前端之家收集整理的这篇文章主要介绍了cocos2dx虚拟摇杆制作【极力推荐】前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

wq右边写的。


项目所用图片资源下载:http://download.csdn.net/detail/jukai7/5096755

解压我们下载的图片资源,有三个图片,其中飞机图片是被控制的对象,剩下的两个我们组合起来制作摇杆,想必这个摇杆最后的样子大家已经猜到了吧,如下所示,即用圆圈作为控制按钮,滑动圆圈,根据其所在位置来设置飞机应该运行的方向。

首先我们新建一个工程,取名为JoyStick,并把刚才下载的图片资源添加进我们的项目。具体的添加方法就不说了,之前的文章都有过说明。在开始编写代码之前,我们先来分析一下摇杆实现的原理。我们是根据圆圈所在位置来判定飞机的移动方向的,我画了一个简单的示意图,来跟大家说明一下(图画的很粗糙,见谅……)。


从这个简单的示意图我们可以看到,我把这个摇杆图片用一个外切正方形框了起来,用虚线分成了九个大小相等的正方形区域,然后又把中间的圆圈所在正方形区域分成了大小相等的四个等腰直角三角形区域。于是我们得到了大小共12个区域,并进行了编号处理。接下来我们就可以根据这些区域来进行判定了。

当我们滑动圆圈时,触点移动到区域1,3,10,12时,我们分别规定飞机的飞行方向为:左上,右上,左下,右下。当触点移动到区域2或区域5时,我们规定飞机向上飞行;移动到区域6或11时,向下;区域4或7时,向左;区域9或8时,向右。

好了,基本原理已经说清楚了,我们就来说一下怎么具体判定触点是在哪块区域里面的?这里我们首先定义一些变量,我们规定大圆的半径为R,中间小圆的半径为r,九个相同大小的正方形的边长为d,即2r,大圆和小圆共同的中心点为O,触点为location。

首先左上,右上,左下,右下四个方向我们比较容易进行判定,左上方向即location.x<(O.x-r)&&location.y>(O.y+r);右上方向为location.x>(O.x+r)&&location.y>(O.y+r);左下为location.x<(O.x-r)&&location.y<(O.y-r);右下为location.x>(O.x+r)&&location.y>(O.y-r)。

然后是上下左右四个方向。每个方向上我们分为两个区域进行判断,首先是判定触点在区域2,11,4,9分别来决定飞机的方向为上,下,左,右。这四个区域都是正方形,比较好判断,例如判定方向上,只要证明触点在以区域2左下角为原点,边长d的正方形内即可。判定是区域2(上)的代码实现为CCRectMake(O.x-r,O.y+r,d,d).containsPoint(location);区域11(下)的代码实现为CCRectMake(O.x-r,O.y-radius1-d,d).containsPoint(location);区域4(左)的代码实现为CCRectMake(O.x-r-d,O.y-r,d).containsPoint(location);区域9(右)的代码实现为CCRectMake(O.x+r,d).containsPoint(location)。

最后是中间四个三角形区域5,6,7,8的判定。要想判定触点在一个三角形内,我们会模糊的记着以前高中是不是经常出这种证明题?对啦,我们就用三角形面积来做。如果一个点包含在一个三角形内,那么从三角形三个顶点中相邻两个顶点到这个点做连线形成新的三个小三角形,这三个新三角形的面积和一定等于原先的那个大三角形面积。相反,如果这个点在三角形外部则一定大于原先三角形的面积,如下图所示:


那么我们怎么求这四个三角形的面积呢?可以根据海伦公式来求。我们知道三角形三个顶点和触点的坐标,那么根据两点间直线距离公式来求得每个三角形的三条边的大小,假设为a,b,c。那么每个三角形的半周长为L=(a+b+c)/2。

于是我们根据海伦公式求得每个三角形的面积。根据求得的结果进行判断即可得知触点是否在四个三角形区域内。例如判断是否在区域5内,我们指定三角形的三个顶点坐标为p1(O.x,O.y),p2(O.x-r,O.y+r),P3(O.x+r,O.y+r)。触点坐标为p(location.x,location.y)。那么S为p1,p2,p3三点组成三角形的面积,S1为p1,p三点组成三角形面积,S2为p2,p3,p三点,S3为p3,p1,p三点。那么判断是否S=S1+S2+s3即可。向下,左,右三方向同理可证。

讲了这么多,我们是时候用代码来具体的实现了。代码我就不做详细的注释了,因为该了解的上面都讲过了。回到我们一开始创建的项目JoyStick,我们需要的图片已经导入到工程中了。我把修改后的HelloWorld.h文件和HelloWorld.cpp文件内容粘贴出来,大家看一下,具体实现的过程我就不讲了,必要的注释也都加上了,有不懂得地方再讨论交流。

HelloWorld.h文件内容如下:

  1. #ifndef__HELLOWORLD_SCENE_H__
  2. #define__HELLOWORLD_SCENE_H__
  3. #include"cocos2d.h"
  4. #include"SimpleAudioEngine.h"
  5. classHelloWorld:publiccocos2d::CCLayer
  6. {
  7. public:
  8. //Here'sadifference.Method'init'incocos2d-xreturnsbool,insteadofreturning'id'incocos2d-iphone
  9. virtualboolinit();
  10. staticcocos2d::CCScene*scene();
  11. voidmenuCloseCallback(CCObject*pSender);
  12. virtualvoidccTouchesBegan(cocos2d::CCSet*pTouches,cocos2d::CCEvent*pEvent);
  13. voidccTouchesMoved(cocos2d::CCSet*pTouches,cocos2d::CCEvent*pEvent);
  14. voidccTouchesEnded(cocos2d::CCSet*pTouches,248); line-height:18.095239639282227px; margin:0px!important; padding:0px 3px 0px 10px!important"> //求三角形面积的函数
  15. floatheronsformula(floatx1,floaty1,87); background-color:inherit; font-weight:bold">floatx2,87); background-color:inherit; font-weight:bold">floaty2,87); background-color:inherit; font-weight:bold">floatx3,87); background-color:inherit; font-weight:bold">floaty3);
  16. //判断三个新三角形面积和是否等于原先三角形面积的函数
  17. booltriangleContainPoint(floaty3,87); background-color:inherit; font-weight:bold">floatpx,87); background-color:inherit; font-weight:bold">floatpy);
  18. CREATE_FUNC(HelloWorld);
  19. private:
  20. voidflying(floatdt);
  21. cocos2d::CCSprite*joystick;
  22. //中心点O
  23. cocos2d::CCPointO;
  24. //大圆半径
  25. floatR;
  26. cocos2d::CCSprite*plane;
  27. //飞机飞行的速度分量值
  28. floatspeedX;
  29. floatspeedY;
  30. //是否飞行的标志
  31. boolisFlying;
  32. };
  33. #endif//__HELLOWORLD_SCENE_H__

HelloWorld.cpp文件内容如下:

copy

    #include"HelloWorldScene.h"
  1. usingnamespacecocos2d;
  2. CCScene*HelloWorld::scene()
  3. {
  4. CCScene*scene=NULL;
  5. do
  6. //'scene'isanautoreleaSEObject
  7. scene=CCScene::create();
  8. CC_BREAK_IF(!scene);
  9. //'layer'isanautoreleaSEObject
  10. HelloWorld*layer=HelloWorld::create();
  11. CC_BREAK_IF(!layer);
  12. //addlayerasachildtoscene
  13. scene->addChild(layer);
  14. }while(0);
  15. //returnthescene
  16. returnscene;
  17. }
  18. //on"init"youneedtoinitializeyourinstance
  19. boolHelloWorld::init()
  20. boolbRet=false;
  21. //////////////////////////////////////////////////////////////////////////
  22. //superinitfirst
  23. CC_BREAK_IF(!CCLayer::init());
  24. //addyourcodesbelow...
  25. //1.Addamenuitemwith"X"image,whichisclickedtoquittheprogram.
  26. //Createa"close"menuitemwithcloseicon,it'sanautoreleaSEObject.
  27. CCMenuItemImage*pCloseItem=CCMenuItemImage::create(
  28. "CloseNormal.png",
  29. "CloseSelected.png",
  30. this,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18.095239639282227px; margin:0px!important; padding:0px 3px 0px 10px!important"> menu_selector(HelloWorld::menuCloseCallback));
  31. CC_BREAK_IF(!pCloseItem);
  32. //Placethemenuitembottom-rightconner.
  33. pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width-20,20));
  34. //Createamenuwiththe"close"menuitem,it'sanautoreleaSEObject.
  35. CCMenu*pMenu=CCMenu::create(pCloseItem,NULL);
  36. pMenu->setPosition(CCPointZero);
  37. CC_BREAK_IF(!pMenu);
  38. //AddthemenutoHelloWorldlayerasachildlayer.
  39. this->addChild(pMenu,1);
  40. //取得屏幕大小
  41. CCSizesize=CCDirector::sharedDirector()->getWinSize();
  42. //创建飞机
  43. plane=CCSprite::create("plane.png");
  44. CC_BREAK_IF(!plane);
  45. //将飞机添加进布景并设置位置
  46. plane->setPosition(ccp(size.width/2,size.height/2));
  47. this->addChild(plane,0);
  48. //创建摇杆下面部分
  49. CCSprite*joystick1=CCSprite::create("joystick1.png");
  50. //设置透明度,锚点,位置
  51. joystick1->setOpacity(191);
  52. joystick1->setAnchorPoint(ccp(0,0));
  53. joystick1->setPosition(ccp(0,0));
  54. //大圆半径
  55. R=joystick1->getContentSize().width/2;
  56. //中心点
  57. O=ccp(R,R);
  58. //添加进布景
  59. this->addChild(joystick1,1);
  60. //创建摇杆上面圆圈部分
  61. joystick=CCSprite::create("joystick2.png");
  62. //设置位置为摇杆中心点并添加进布景
  63. joystick->setPosition(ccp(O.x,O.y));
  64. this->addChild(joystick,2);
  65. //设置可触摸
  66. this->setTouchEnabled(true);
  67. //每帧要执行的函数
  68. this->schedule(schedule_selector(HelloWorld::flying));
  69. //初始化需要的变量
  70. isFlying= speedX=speedY=0;
  71. bRet=true;
  72. }while(0);
  73. returnbRet;
  74. voidHelloWorld::menuCloseCallback(CCObject*pSender)
  75. //"close"menuitemclicked
  76. CCDirector::sharedDirector()->end();
  77. //飞机飞行函数
  78. voidHelloWorld::flying(floatdt)
  79. if(isFlying&&(speedX!=0||speedY!=0)){
  80. //飞机飞行
  81. CCPointposition=ccp(plane->getPosition().x+speedX,plane->getPosition().y+speedY);
  82. CCSizesize=CCDirector::sharedDirector()->getWinSize();
  83. CCRectrect=CCRectMake(0,size.width,size.height);
  84. //判断触摸点是否在屏幕内
  85. if(rect.containsPoint(position)){
  86. plane->setPosition(position);
  87. }
  88. //触摸开始函数,判断触摸开始点是否在圆圈内,若是,则设置isFlying标志为true
  89. voidHelloWorld::ccTouchesBegan(CCSet*pTouches,CCEvent*pEvent)
  90. CCTouch*touch=(CCTouch*)pTouches->anyObject();
  91. CCPointlocation=touch->getLocation();
  92. CCRectrect=joystick->boundingBox();
  93. if(rect.containsPoint(location))
  94. true;
  95. //触摸滑动函数
  96. voidHelloWorld::ccTouchesMoved(CCSet*pTouches,CCEvent*pEvent)
  97. CCTouch*touch=(CCTouch*)pTouches->anyObject();
  98. CCPointlocation=touch->getLocation();
  99. //判断触摸滑动点是否在摇杆范围内
  100. boolinRange=pow(O.x-location.x,2)+pow(O.y-location.y,2)<pow(R,153); background-color:inherit; font-weight:bold">if(isFlying&&inRange){
  101. CCPointposition=plane->getPosition();
  102. joystick->setPosition(location);
  103. floatr=R*2/6;
  104. floatd=R*2/3;
  105. //上,区域2或5
  106. if(triangleContainPoint(O.x,O.y,O.x-r,O.x+r,location.x,location.y)
  107. ||CCRectMake(O.x-r,d).containsPoint(location)){
  108. speedX=0;
  109. speedY=1;
  110. //下,区域6或11
  111. else speedY=-1;
  112. //左,区域4或7
  113. ||CCRectMake(O.x-r-d,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18.095239639282227px; margin:0px!important; padding:0px 3px 0px 10px!important"> speedX=-1;
  114. speedY=0;
  115. //右,区域9或8
  116. ||CCRectMake(O.x+r,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18.095239639282227px; margin:0px!important; padding:0px 3px 0px 10px!important"> speedX=1;
  117. //右上,区域3
  118. if(location.x-(O.x+r)>0&&location.y-(O.y+r)>0){
  119. speedX=0.7f;
  120. speedY=0.7f;
  121. //左上,区域1
  122. if(location.x-(O.x-r)<0&&location.y-(O.y+r)>0){
  123. speedX=-0.7f;
  124. speedY=0.7f;
  125. //左下,区域10
  126. if(location.x-(O.x-r)<0&&location.y-(O.y-r)<0){
  127. speedX=-0.7f;
  128. speedY=-0.7f;
  129. //右下,区域12
  130. if(location.x-(O.x+r)>0&&location.y-(O.y-r)<0){
  131. speedX=0.7f;
  132. speedY=-0.7f;
  133. //触摸结束函数
  134. voidHelloWorld::ccTouchesEnded(CCSet*pTouches,248); line-height:18.095239639282227px; margin:0px!important; padding:0px 3px 0px 10px!important"> isFlying=false;
  135. joystick->setPosition(O);
  136. //求三角形面积的函数的实现
  137. floatHelloWorld::heronsformula(floaty3)
  138. //求边长a
  139. floata=sqrt(pow(x1-x2,2)+pow(y1-y2,2));
  140. //求边长b
  141. floatb=sqrt(pow(x2-x3,2)+pow(y2-y3,0); background-color:inherit">//求边长c
  142. floatc=sqrt(pow(x3-x1,2)+pow(y3-y1,0); background-color:inherit">//求半周长s
  143. floats=(a+b+c)/2;
  144. //根据海伦公式返回三角形面积
  145. returnsqrt(s*(s-a)*(s-b)*(s-c));
  146. //判断三个新三角形面积和是否等于原先三角形面积的函数的实现
  147. boolHelloWorld::triangleContainPoint(floatpy)
  148. //求S1的面积
  149. floats1=heronsformula(x1,y1,x2,y2,px,py);
  150. //求S2的面积
  151. floats2=heronsformula(x2,x3,y3,0); background-color:inherit">//求S3的面积
  152. floats3=heronsformula(x3,x1,0); background-color:inherit">//求S的面积
  153. floats=heronsformula(x1,y3);
  154. //返回S是否等于S1,S2,S3的和
  155. returnabs(s-(s1+s2+s3))<0.001f;
  156. }

运行,结果如下

原文链接:https://www.f2er.com/cocos2dx/344166.html

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