cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第二步---编辑器(1)--触摸加入点
/* 说明:
**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
- class PosEditorScene{
- public:
- static Scene* createScene();
- };/**/
是的,就这么简单,我们这里仅仅要获取一个Scene就可以,其它的Layer在createScene里面
.cpp
- Scene* PosEditorScene::createScene(){
- Scene* scene = Scene::create();
- //auto posEditorLayer = PosEditorLayer::create();
- //scene->addChild(posEditorLayer);
- auto getBackLayer = GetBackLayer::create();
- scene->addChild(getBackLayer);
- return scene;
- }
然后看看GetBackLayer.h
- #include "cocos2d.h"
- #include "cocos-ext.h"
- USING_NS_CC;
- USING_NS_CC_EXT;
- class GetBackLayer : public Layer{
- public:
- CREATE_FUNC(GetBackLayer);
- virtual bool init();
- private:
- void getBack(Ref* pSender, Control::EventType event);
- };/**/
CREATE_FUNC实际是一个宏定义的create函数,后面在Scene中的加入Layer的时候create,然后会调用Layer的 init 函数,这里我们仅仅须要virtual bool init 函数的实现
.cpp
- bool GetBackLayer::init(){
- auto visibleSize = Director::getInstance()->getVisibleSize();
- auto btnTitle = Label::create("Back","Arial",30);
- auto norSprite = Scale9Sprite::create("Button/public_ui_blue_btn.png");
- auto highLightSprite = Scale9Sprite::create("Button/public_ui_green_btn.png");
- auto outPutBtn = ControlButton::create(btnTitle,norSprite);
- outPutBtn->setBackgroundSpriteForState(highLightSprite,Control::State::HIGH_LIGHTED);
- outPutBtn->setPosition(
- ccp(visibleSize.width-norSprite->getContentSize().width/2,
- visibleSize.height - norSprite->getContentSize().height));
- outPutBtn->addTargetWithActionForControlEvents(
- this,
- cccontrol_selector(GetBackLayer::getBack),
- Control::EventType::TOUCH_UP_INSIDE);
- this->addChild(outPutBtn,20);
- return true;
- }
- void GetBackLayer::getBack(Ref* pSender,Control::EventType event){
- CCLOG("Back to MainScene");
- auto scene = MainScene::createScene();
- Director::getInstance()->replaceScene(scene);
- }
这里因为用到了Extension,会遇到些问题:解决方法之前提到过:
也就三步三个加入:之前也有过 图文解释
到这里,就能够測试一下Backbutton的使用,那么GetBackLayer能够加入到非常多Scene中
那么如今来看看PosEditorLayer.h
- class PosEditorLayer : public Layer{
- public:
- PosEditorLayer();
- ~PosEditorLayer();
- CREATE_FUNC(PosEditorLayer);
- virtual bool init();
- private:
- //**2**当前关卡级别
- int _curLevel;
- //------------成员&函数切割线----------------------
- //**2**预载入内容
- void preLoad();
- };
.cpp
- PosEditorLayer::PosEditorLayer(){
- _curLevel = 1;
- }
- PosEditorLayer::~PosEditorLayer(){
- }
- bool PosEditorLayer::init(){
- //**2**---------------触摸事件----------------------------
- auto listener = EventListenerTouchOneByOne::create();
- listener->setSwallowTouches(true);
- listener->onTouchBegan = [](Touch* touch, Event* event){
- return true;
- };
- listener->onTouchMoved = [](Touch* touch, Event* event){
- };
- listener->onTouchEnded = [=](Touch* touch, Event* event){
- auto touchPos = touch->getLocationInView();
- auto pos = Director::getInstance()->convertToUI(touchPos);
- CCLOG("Touch pos.X is %f, Touch pos.Y is %f",pos.x, pos.y);
- };
- _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
- //------------------------------------------------------------
- //**2**
- preLoad();
- return true;
- }
- void PosEditorLayer::preLoad(){
- //**2**add map
- auto visibleSize = Director::getInstance()->getVisibleSize();
- auto sBg = __String::createWithFormat("game/level_%d.jpg",_curLevel);
- auto mapBg = Sprite::create(sBg->getCString());
- mapBg->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));
- mapBg->setOpacity(150);
- this->addChild(mapBg);
- }
然后把这个层加入到PosEditorScene中,为了不挡住getBackLayer,你能够在GetBackLayer之前 加入scene里面
然后F5測试,输出中能够看到你触摸屏幕的位置
触摸屏幕是为了加入点,那么来看看PosBase
- enum EnumPosType{
- enTowerPos,
- enMonsterPos
- };
- class PosBase : public Node{
- public:
- PosBase();
- ~PosBase();
- //**2**
- static PosBase* create(Point pos, EnumPosType posType, bool isDebug);
- //**2**
- bool init(cocos2d::Point pos, EnumPosType posType, bool isDebug);
- //**2**
- virtual void draw(cocos2d::Renderer *renderer, const kmMat4& transform, bool transformUpdated);
- protected:
- CC_SYNTHESIZE(Point,_pos,Pos);
- //**2**
- bool _isDebug;
- EnumPosType _posType;
- };/**/
这里是根据 位置,点类型,是否调试;三个变量来创建一个PosBase的;根据_isDebug来推断是否调试,是的话,就将点画出来 ,这里的CC_SYNTHESIZE 也是一个宏,就是加入私有成员,等价于:
private:
Point _pos;
public:
void setPos(Point pos) { _pos = pos ; };
Point getPos() { return _pos; };
.cpp
- #define Tower_Radius 32
- #define Monster_Radius 10
- PosBase::PosBase(){
- _pos = CCPointMake(0,0);
- _isDebug = false;
- _posType = enTowerPos;
- }
- PosBase::~PosBase(){
- }
- PosBase* PosBase::create(Point pos, EnumPosType posType, bool isDebug){
- PosBase* tPos = new PosBase();
- if(tPos && tPos->init(pos, posType,isDebug)){
- tPos->autorelease();
- }else{
- CC_SAFE_DELETE(tPos);
- }
- return tPos;
- }
- bool PosBase::init(Point pos, EnumPosType posType, bool isDebug){
- //**2** _SYNTHESIZE(Point,_pos,Pos); 的方法
- setPos(pos);
- _posType = posType;
- _isDebug = isDebug;
- return true;
- }
- void PosBase::draw(Renderer *renderer, const kmMat4& transform, bool transformUpdated){
- if(_isDebug){
- glLineWidth(5);
- //依据posMode 设置推断的半径
- float radius;
- if(_posType == enTowerPos){
- radius = Tower_Radius;
- }
- else{
- radius = Monster_Radius;
- }
- //draw TowerPos
- if(_posType == enTowerPos){
- Point srcPos = Point(_pos.x-radius, _pos.y+radius);
- Point destPos = Point(_pos.x+radius, _pos.y-radius);
- ccDrawRect(srcPos,destPos);
- }
- else{ //draw MonsterPos
- ccDrawCircle(_pos, radius, 360, 20, false);
- }
- glLineWidth(1);
- }
- }
然后測试:在PosEditorLayer中加入成员_posType,而且在构造函数中赋值 enTowerPos 表示默认当前是编辑炮台坐标
成员函数 editorPos
- void PosEditorLayer::editPos(Point pos){
- //**2**test
- auto posBase = PosBase::create(pos, _posType, true);
- this->addChild(posBase);
- }
然后在触摸事件中加入函数,就能随意点击屏幕加入点;
四:下节知识点预览
既然要编辑,仅仅能加入点不然删除算什么?要在代码中改变PosType算什么?难道仅仅能编辑一级的关卡吗?这些点不保存?
以下解决
------------------------------------------------
资源&代码
------------------------------------------------
个人愚昧观点,欢迎指正与讨论
cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第二步---编辑器(1)--触摸加入点的更多相关文章
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》 完结篇--源代码放送
说明:这里是借鉴:晓风残月前辈的博客,他是将泰然网的跑酷教程,用cocos2d-x 2.X 版本号重写的,眼下我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记 ...
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第0步---知识点总结&效果预览&设计思路
/* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏.这里用3.0重写并做下笔记 **2.我也问过木头本人啦,他说:随便写.第一别全然照搬代码:第二能够说 ...
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第三步---编辑器(2)---更方便很多其它操作更像编辑器
/* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦.他说:随便写,第一别全然照搬代码:第二能够说 ...
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第一步---開始界面&关卡选择
/* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦.他说:随便写,第一别全然照搬代码:第二能够说 ...
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第七步---英雄要升级&属性--解析csv配置文件
/* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦.他说:随便写,第一别全然照搬代码:第二能够说 ...
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第八部---怪物出场
/* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦,他说:随便写.第一别全然照搬代码.第二能够说 ...
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第六步---炮台&点击炮台加入英雄&英雄升级
/* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏,这里用3.0重写并做下笔记 **2.我也问过木头本人啦,他说:随便写,第一别全然照搬代码:第二能够说 ...
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》移植到android手机
说明:这里是借鉴:晓风残月前辈的博客.他是将泰然网的跑酷教程.用cocos2d-x 2.X 版本号重写的,眼下我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记 ...
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》第一步--- 开始界面
说明:这里是平局:晓风残月前辈的博客.他是将泰然网的跑酷教程.用cocos2d-x 2.X 版本号重写的,眼下我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记 ...
随机推荐
- MyEclipse-6.5注冊码生成器源代码
打开MyEclipse新建一个Javaproject,然后新建类,粘贴例如以下代码,就可以生成MyEclipse的注冊码 import java.io.BufferedReader; import j ...
- 怎样使用 App Studio 高速定制你自己的 Universal Windows App
今天之所以在写一篇关于 App Studio 的文章是由于,App Studio 经过了几次升级功能得到了明显提升还能够调用系统功能了.而且能够更方便的和应用商店关联公布 Universal Wind ...
- 使用datapump 导出导入同义词(export and import synonym using datapump)
对于同义词的备份我们有多种方式来实现,如直接通过脚本生成同义词的创建脚本,或者使用dbms_metadata.get_ddl来提取同义词的定义脚本.然而在使用传统的exp或是datapump expd ...
- Servlet的学习之Session(2)
在上一篇中我们学习了Session对象默认在一个会话过程中,由服务器创建,能保存在这个会话过程中用户访问多个web资源时产生的需要保存的数据,并在访问服务器中其他web资源时可以将这些数据从Sessi ...
- FZU 1894 (双端队列)
Problem 1894 志愿者选拔 Accept: 1166 Submit: 3683 Time Limit: 1500 mSec Memory Limit : 32768 KB Pr ...
- WPF的消息机制
前言 谈起“消息机制”这个词,我们都会想到Windows的消息机制,系统将键盘鼠标的行为包装成一个Windows Message,然后系统主动将这些Windows Message派发给特定的窗口,实际 ...
- NET Platform Standard
NET Platform Standard 相关博文:ASP.NET 5 Target framework dnx451 and dnxcore50 .NET Platform Standard:ht ...
- Java的HashCode
·HashCode就是根据对象存储在内存的地址计算出的一个值.这个值可以标识这个对象的位置.也可以对比两个引用变量是否指向同一个对象. ·String重写了hashCode方法——改为根据字符序列计算 ...
- Zeroonepack coming~^.^
今天抓的四道DP做完了==三道是用背包做的,突然想起来背包知识点总结还没做~反正时间还早..把01背包和完全背包小结了吧~~福利来啦~~噶呜~ 01背包: 基本思路: 01背包问题是最广为人知的动态规 ...
- 使用CocoaPods出现 The `master` repo requires CocoaPods 0.32.1 - 问题解决
近期在使用CocoaPods为project配置第三方类库时出现了例如以下问题: [!] The `master` repo requires CocoaPods 0.32.1 - 明显是由于Coco ...