/* 说明:

**1.本次游戏实例是《cocos2d-x游戏开发之旅》上的最后一个游戏,这里用3.0重写并做下笔记

**2.我也问过木头本人啦,他说:随便写,第一别全然照搬代码;第二能够说明是学习笔记---好人

**3.这里用cocos2d-x 3.0版本号重写,非常多地方不同,可是从重写过程中也非常好的学习了cocos2d-x

*/

***每一步相应的全部代码以及用到的资源都会打包在最后给出

***为避免代码过多,每一步的代码都做了标记--一看就晓得是第几步实现的避免出错改不回去(难不成还用Git?)

***能够依据设计思路(好吧,那名字太高大上。实际就是这一步要干啥)先自己实现---cocos2d-x本来就是如此,同样的功能有很多不同实现方法;先自己折腾是蛮不错的。

***为了方便移植到手机上,对于每一步都进行编译android測试;由于非常多时候代码在win32下能够,编译就会出错,给出的代码会是測试过后的。

本次笔记内容:

1、设计思路&问题注意

2、效果图

3、尾随设计思路看代码

4、下节知识预览

一:设计思路&问题注意

一步步来

(1)为了响应MainScene中的编辑button,须要一个PosEditorScene,然而这个Scene里面须要做的事比較多;所以这里把Scene单独抽离出来,然后在里面加入各种Layer

(2)先来一个万能的GetBackLayer;为什么是万能的呢?这个层的作用非常easy,里面有一button,Back; 通过这个button,你能够在不论什么地方回到MainScene。你Start之后进行关卡选择,发现自己要重编辑怪物路线,你就Back,游戏中你不想玩了Back,编辑场景中,编辑好了想要測试?Back。到这,你就能够測试一下了

(3)来一个PosEditorLayer,这个层我们来编辑怪物路线和炮台位置,那么通过屏幕触摸,能够加入一个Pos,就须要我们给这个Layer触摸事件,到这,你也能够在触摸事件中測试一下

(4)既然触摸是加入一个点,那么我们就须要PosBase,继承自Node,然后重写draw 函数,屏幕触摸之后,加入这个点,这个点draw出来。然而这里须要注意的就是我们分Tower和Monster两种点;木头的做法是抽离一个PosBase基类,然后分别继承。这种话是方便以后扩充,假设又有一种点,那么相同能够继承;我这里看两种点的功能差点儿相同,就偷了懒,干脆仅仅用PosBase,然后用一个枚举类来区分当前点是Tower
还是Monster

(5)须要注意的是枚举类是必要的,在编辑层中你也须要改变不同的Type 来进行编辑

(6)这里的GetBackLayer中的button用了Extension库,有一点点问题须要处理--比較简单

(7)那么这里的点重写draw函数的话,不知道为什么,会被背景挡住,N多方法都试过;最后机智的想到,把背景图片设置透明度;还果然就看到了;只是问过木头大哥啦,他測试的解决方法是:draw函数最先被画,那么PosBase就不要加入到有背景的层,能够单独抽离一个层,就能够啦;

(8)编辑器的内容比較多,这一步先到这里

二:最后效果图

点击屏幕任何位置,出现一个Tower,同一时候PosEditorLayer 中有一个枚举成员,初始化为Tower,也能够弄成Monster 測试

三:尾随设计思路看代码

首先是PosEditorScene.h

  1. class PosEditorScene{
  2. public:
  3. static Scene* createScene();
  4. };/**/

是的,就这么简单,我们这里仅仅要获取一个Scene就可以,其它的Layer在createScene里面

.cpp

  1. Scene* PosEditorScene::createScene(){
  2. Scene* scene = Scene::create();
  3.  
  4. //auto posEditorLayer = PosEditorLayer::create();
  5. //scene->addChild(posEditorLayer);
  6.  
  7. auto getBackLayer = GetBackLayer::create();
  8. scene->addChild(getBackLayer);
  9.  
  10. return scene;
  11. }

然后看看GetBackLayer.h

  1. #include "cocos2d.h"
  2. #include "cocos-ext.h"
  3. USING_NS_CC;
  4. USING_NS_CC_EXT;
  5.  
  6. class GetBackLayer : public Layer{
  7. public:
  8. CREATE_FUNC(GetBackLayer);
  9. virtual bool init();
  10.  
  11. private:
  12. void getBack(Ref* pSender, Control::EventType event);
  13. };/**/

CREATE_FUNC实际是一个宏定义的create函数,后面在Scene中的加入Layer的时候create,然后会调用Layer的 init 函数,这里我们仅仅须要virtual bool init 函数的实现

.cpp

  1. bool GetBackLayer::init(){
  2. auto visibleSize = Director::getInstance()->getVisibleSize();
  3.  
  4. auto btnTitle = Label::create("Back","Arial",30);
  5. auto norSprite = Scale9Sprite::create("Button/public_ui_blue_btn.png");
  6. auto highLightSprite = Scale9Sprite::create("Button/public_ui_green_btn.png");
  7.  
  8. auto outPutBtn = ControlButton::create(btnTitle,norSprite);
  9. outPutBtn->setBackgroundSpriteForState(highLightSprite,Control::State::HIGH_LIGHTED);
  10. outPutBtn->setPosition(
  11. ccp(visibleSize.width-norSprite->getContentSize().width/2,
  12. visibleSize.height - norSprite->getContentSize().height));
  13.  
  14. outPutBtn->addTargetWithActionForControlEvents(
  15. this,
  16. cccontrol_selector(GetBackLayer::getBack),
  17. Control::EventType::TOUCH_UP_INSIDE);
  18.  
  19. this->addChild(outPutBtn,20);
  20. return true;
  21. }
  22.  
  23. void GetBackLayer::getBack(Ref* pSender,Control::EventType event){
  24. CCLOG("Back to MainScene");
  25. auto scene = MainScene::createScene();
  26. Director::getInstance()->replaceScene(scene);
  27. }

这里因为用到了Extension,会遇到些问题:解决方法之前提到过:

也就三步三个加入:之前也有过  图文解释

到这里,就能够測试一下Backbutton的使用,那么GetBackLayer能够加入到非常多Scene中

那么如今来看看PosEditorLayer.h

  1. class PosEditorLayer : public Layer{
  2. public:
  3. PosEditorLayer();
  4. ~PosEditorLayer();
  5. CREATE_FUNC(PosEditorLayer);
  6. virtual bool init();
  7.  
  8. private:
  9. //**2**当前关卡级别
  10. int _curLevel;
  11. //------------成员&函数切割线----------------------
  12.  
  13. //**2**预载入内容
  14. void preLoad();
  15. };

.cpp

  1. PosEditorLayer::PosEditorLayer(){
  2. _curLevel = 1;
  3. }
  4. PosEditorLayer::~PosEditorLayer(){
  5. }
  6.  
  7. bool PosEditorLayer::init(){
  8. //**2**---------------触摸事件----------------------------
  9. auto listener = EventListenerTouchOneByOne::create();
  10. listener->setSwallowTouches(true);
  11.  
  12. listener->onTouchBegan = [](Touch* touch, Event* event){
  13. return true;
  14. };
  15.  
  16. listener->onTouchMoved = [](Touch* touch, Event* event){
  17. };
  18.  
  19. listener->onTouchEnded = [=](Touch* touch, Event* event){
  20. auto touchPos = touch->getLocationInView();
  21. auto pos = Director::getInstance()->convertToUI(touchPos);
  22.  
  23. CCLOG("Touch pos.X is %f, Touch pos.Y is %f",pos.x, pos.y);
  24. };
  25.  
  26. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
  27.  
  28. //------------------------------------------------------------
  29.  
  30. //**2**
  31. preLoad();
  32.  
  33. return true;
  34. }
  35.  
  36. void PosEditorLayer::preLoad(){
  37. //**2**add map
  38. auto visibleSize = Director::getInstance()->getVisibleSize();
  39. auto sBg = __String::createWithFormat("game/level_%d.jpg",_curLevel);
  40. auto mapBg = Sprite::create(sBg->getCString());
  41. mapBg->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));
  42. mapBg->setOpacity(150);
  43. this->addChild(mapBg);
  44. }

然后把这个层加入到PosEditorScene中,为了不挡住getBackLayer,你能够在GetBackLayer之前 加入scene里面

然后F5測试,输出中能够看到你触摸屏幕的位置

触摸屏幕是为了加入点,那么来看看PosBase

  1. enum EnumPosType{
  2. enTowerPos,
  3. enMonsterPos
  4. };
  5.  
  6. class PosBase : public Node{
  7. public:
  8. PosBase();
  9. ~PosBase();
  10. //**2**
  11. static PosBase* create(Point pos, EnumPosType posType, bool isDebug);
  12.  
  13. //**2**
  14. bool init(cocos2d::Point pos, EnumPosType posType, bool isDebug);
  15.  
  16. //**2**
  17. virtual void draw(cocos2d::Renderer *renderer, const kmMat4& transform, bool transformUpdated);
  18.  
  19. protected:
  20. CC_SYNTHESIZE(Point,_pos,Pos);
  21.  
  22. //**2**
  23. bool _isDebug;
  24. EnumPosType _posType;
  25. };/**/

这里是根据  位置,点类型,是否调试;三个变量来创建一个PosBase的;根据_isDebug来推断是否调试,是的话,就将点画出来 ,这里的CC_SYNTHESIZE 也是一个宏,就是加入私有成员,等价于:

private:

Point  _pos;

public:

void setPos(Point pos) { _pos = pos ; };

Point getPos() { return _pos; };

.cpp

  1. #define Tower_Radius 32
  2. #define Monster_Radius 10
  3.  
  4. PosBase::PosBase(){
  5. _pos = CCPointMake(0,0);
  6. _isDebug = false;
  7. _posType = enTowerPos;
  8. }
  9. PosBase::~PosBase(){
  10. }
  11.  
  12. PosBase* PosBase::create(Point pos, EnumPosType posType, bool isDebug){
  13. PosBase* tPos = new PosBase();
  14.  
  15. if(tPos && tPos->init(pos, posType,isDebug)){
  16. tPos->autorelease();
  17. }else{
  18. CC_SAFE_DELETE(tPos);
  19. }
  20. return tPos;
  21. }
  22.  
  23. bool PosBase::init(Point pos, EnumPosType posType, bool isDebug){
  24. //**2** _SYNTHESIZE(Point,_pos,Pos); 的方法
  25. setPos(pos);
  26. _posType = posType;
  27. _isDebug = isDebug;
  28.  
  29. return true;
  30. }
  31.  
  32. void PosBase::draw(Renderer *renderer, const kmMat4& transform, bool transformUpdated){
  33. if(_isDebug){
  34. glLineWidth(5);
  35.  
  36. //依据posMode 设置推断的半径
  37. float radius;
  38. if(_posType == enTowerPos){
  39. radius = Tower_Radius;
  40. }
  41. else{
  42. radius = Monster_Radius;
  43. }
  44.  
  45. //draw TowerPos
  46. if(_posType == enTowerPos){
  47. Point srcPos = Point(_pos.x-radius, _pos.y+radius);
  48. Point destPos = Point(_pos.x+radius, _pos.y-radius);
  49.  
  50. ccDrawRect(srcPos,destPos);
  51. }
  52. else{ //draw MonsterPos
  53. ccDrawCircle(_pos, radius, 360, 20, false);
  54. }
  55.  
  56. glLineWidth(1);
  57. }
  58. }

然后測试:在PosEditorLayer中加入成员_posType,而且在构造函数中赋值 enTowerPos 表示默认当前是编辑炮台坐标

成员函数  editorPos

  1. void PosEditorLayer::editPos(Point pos){
  2. //**2**test
  3. auto posBase = PosBase::create(pos, _posType, true);
  4. this->addChild(posBase);
  5. }

然后在触摸事件中加入函数,就能随意点击屏幕加入点;

四:下节知识点预览

既然要编辑,仅仅能加入点不然删除算什么?要在代码中改变PosType算什么?难道仅仅能编辑一级的关卡吗?这些点不保存?

以下解决

------------------------------------------------

资源&代码

------------------------------------------------

个人愚昧观点,欢迎指正与讨论

cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第二步---编辑器(1)--触摸加入点的更多相关文章

  1. cocos2d-x 3.0游戏实例学习笔记 《跑酷》 完结篇--源代码放送

    说明:这里是借鉴:晓风残月前辈的博客,他是将泰然网的跑酷教程,用cocos2d-x 2.X 版本号重写的,眼下我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记 ...

  2. cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第0步---知识点总结&效果预览&设计思路

    /* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏.这里用3.0重写并做下笔记 **2.我也问过木头本人啦,他说:随便写.第一别全然照搬代码:第二能够说 ...

  3. cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第三步---编辑器(2)---更方便很多其它操作更像编辑器

    /* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦.他说:随便写,第一别全然照搬代码:第二能够说 ...

  4. cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第一步---開始界面&amp;关卡选择

    /* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦.他说:随便写,第一别全然照搬代码:第二能够说 ...

  5. cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第七步---英雄要升级&amp;属性--解析csv配置文件

    /* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦.他说:随便写,第一别全然照搬代码:第二能够说 ...

  6. cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第八部---怪物出场

    /* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦,他说:随便写.第一别全然照搬代码.第二能够说 ...

  7. cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第六步---炮台&amp;点击炮台加入英雄&amp;英雄升级

    /* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦,他说:随便写,第一别全然照搬代码:第二能够说 ...

  8. cocos2d-x 3.0游戏实例学习笔记 《跑酷》移植到android手机

    说明:这里是借鉴:晓风残月前辈的博客.他是将泰然网的跑酷教程.用cocos2d-x 2.X 版本号重写的,眼下我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记 ...

  9. cocos2d-x 3.0游戏实例学习笔记 《跑酷》第一步--- 开始界面

    说明:这里是平局:晓风残月前辈的博客.他是将泰然网的跑酷教程.用cocos2d-x 2.X 版本号重写的,眼下我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记 ...

随机推荐

  1. <转载>使用css让大图片不超过网页宽度

    让大图片不超过网页宽度,让图片不撑破通过CSS样式设置的DIV宽度! 接下来,我们来介绍下网站在开发DIV+CSS的时候会遇到一个问题,在发布一个大图片的时候因为图片过宽会撑破自己设置的div宽度的问 ...

  2. ASP.NET - 上传图片方法(单张)

    /// <summary> /// 上传图片 /// </summary> /// <param name="fileupload">上传的控件 ...

  3. Eclipse TestNg插件

    TestNg作为一个测试框架,也有eclipse的插件: 官网给的安装插件地址是 : For Eclipse 3.4 and above, enter http://beust.com/eclipse ...

  4. HTTPS的学习

    HTTPS的学习总结   HTTPS学习总结 简述 HTTPS对比HTTP就多了一个安全层SSL/TLS,具体就是验证服务端的证书和对内容进行加密. 先来看看HTTP和HTTPS的区别 我用AFN访问 ...

  5. jd.py

    #!/usr/bin/env python #coding:utf-8 import urllib2,re,sys,os,types #from bs4 import BeautifulSoup re ...

  6. TDD测试驱动的javascript开发(3) ------ javascript的继承

    说起面向对象,人们就会想到继承,常见的继承分为2种:接口继承和实现继承.接口继承只继承方法签名,实现继承则继承实际的方法. 由于函数没有签名,在ECMAScript中无法实现接口继承,只支持实现继承. ...

  7. Android菜鸟的成长笔记(1)——Android开发环境搭建从入门到精通

    原文:Android菜鸟的成长笔记(1)--Android开发环境搭建从入门到精通 今天在博客中看到好多Android的初学者对Android的开发环境的搭建不熟悉而导致不能进行学习,所以我决定自己写 ...

  8. oracle实现远程连接超简单;枚举与剪枝();PowerDesigner生成数据库代码注意里面的双引號,应该去掉

    点击開始,查看netManager,点击面板的监听程序,默认仅仅有地址1且标记着localhost.新建一个地址,输入本机IP,又一次开启监听程序就可以 △△△ * △△ = △△△△ 某3位数乘以2 ...

  9. Android代码混淆和项目宣布步骤记录器

    原本放在一起Android项目与发布的文件相混淆.我突然想到,为什么不写博客,分享.有这篇文章的情况下,. Android代码混淆及项目公布步骤记录 一.清理代码中的调试信息,如Log.System. ...

  10. “聊天剽窃手”--ptrace进程注入型病毒

    近日,百度安全实验室发现了一款"聊天剽窃手"病毒.该病毒可以通过ptrace方式注入恶意代码至QQ.微信程序进程.恶意代码可以实时监控手机QQ.微信的聊天内容及联系人信息. 该病毒 ...