关卡数据已经能显示出来了,现在需要添加角色精灵的移动。这就需要添加触屏点击事件。在点击事件中对触屏的进行手势识别,手势识别非常简单,就是判断玩家是想让角色向上移动和是向哪移动。
思路:
两个Vec2类型的变量,记录点击开始的点和移动过程中的点。
一个RoleSprite类型的变量,记录当前选中的精灵。
float类型的变量,指定最小的判断距离,也就是说,如果,移动距离比较小是不会有反应的。
用一个二维数组来记录当前每个格子的状态,移动RoleSprite的时候判断是否可以移动。
代码:
GameLayer.h
#ifndef _GAME_LAYER_H_#define _GAME_LAYER_H_#include "cocos2d.h"class Level ;class RoleSprite ;class GameLayer : public cocos2d::Layer{public: static cocos2d::Scene* createScene(); CREATE_FUNC(GameLayer);public: GameLayer(); ~GameLayer(); virtual bool init(); //@biref 初始化地图 voID initMap() ; //@biref 更新m_mapState voID updateMapData() ; //@biref 重置m_mapState中的数据 voID resetMapData(); virtual bool ontouchBegan(cocos2d::touch *touch,cocos2d::Event *unused_event) ; virtual voID ontouchmoved(cocos2d::touch *touch,cocos2d::Event *unused_event) ; virtual voID ontouchended(cocos2d::touch *touch,cocos2d::Event *unused_event) ; //@biref 是否可以移动,参数:要移动的方向,是往加的方向移动还是往减的方向移动 bool isCanMove(bool isMoveHor,bool moveAdd);private: Level * m_pLevel;//<关卡数据的引用 cocos2d::Vector<RoleSprite*> m_pRoleSpriteVec ;//<存储角色精灵 cocos2d::Vec2 m_touchBegin ;//<开始点击的位置 cocos2d::Vec2 m_touchmove ;//<移动过程中的点 float m_mindis ;//<最小移动距离,>=他的时候才判断是否移动 RoleSprite * m_pSeleNode ;//<选中的角色 int m_mapState[5][4] ;//<5行4列,0是空,1是已填充};#endif
GameLayer.cpp
#include "GameLayer.h"#include "RoleSprite.h"#include "data/Role.h"#include "data/Level.h"USING_NS_CC ;Scene* GameLayer::createScene(){ auto scene = Scene::create() ; auto layer = GameLayer::create() ; scene->addChild(layer); return scene ;}GameLayer::GameLayer() :m_pLevel(nullptr),m_pSeleNode(nullptr),m_touchBegin(Vec2(0,0)),m_touchmove(Vec2(0,m_mindis(0){ m_pLevel = Level::s_levelVec.at(0) ; CC_SAFE_RETAIN(m_pLevel) ; m_mindis = 20.0f ;}GameLayer::~GameLayer(){ CC_SAFE_RELEASE_NulL(m_pLevel) ;}bool GameLayer::init(){ Size size = Director::getInstance()->getWinSize(); auto bgSprite = Sprite::create("main_bg0.png") ; bgSprite->setposition(size.wIDth / 2,size.height / 2) ; addChild(bgSprite); initMap() ; auto lisener = EventListenertouchOneByOne::create() ; lisener->ontouchBegan = CC_CALLBACK_2(GameLayer::ontouchBegan,this) ; lisener->ontouchmoved = CC_CALLBACK_2(GameLayer::ontouchmoved,this) ; lisener->ontouchended = CC_CALLBACK_2(GameLayer::ontouchended,this); _eventdispatcher->addEventListenerWithSceneGraPHPriority(lisener,this) ; return true ;}voID GameLayer::initMap(){ Size size = Director::getInstance()->getWinSize(); float x = 0 ; float y = 0 ; float paddingleft = 10.0f ; float paddingBottom = 53.0f ; for (unsigned i = 0 ; i < m_pLevel->getRoleID().size() ;i++) { Role * pRole = Role::s_roleVec.at(m_pLevel->getRoleID().at(i)) ; Sprite * pp = Sprite::create(pRole->getimagename()->getCString()); int col = m_pLevel->getRolePos().at(i).x ; int row = m_pLevel->getRolePos().at(i).y ; x = paddingleft + col * 1.0f * 75.0f ; y = paddingBottom + row * 1.0f * 75.0f ; RoleSprite * pRoleSprite = RoleSprite::create(pRole,row,col,Rect(x,y,pp->getContentSize().wIDth,pp->getContentSize().height),this,this->getLocalZOrder()) ; m_pRoleSpriteVec.pushBack(pRoleSprite) ; } updateMapData() ;}bool GameLayer::ontouchBegan(touch *touch,Event *unused_event){ auto loction = this->convertToNodeSpace(touch->getLocation()) ; for (unsigned int i = 0 ; i < m_pRoleSpriteVec.size() ; i++) { RoleSprite * pRoleSprite = m_pRoleSpriteVec.at(i) ; if (pRoleSprite->getBoundingBox().containsPoint(loction)) { //得到点击的位置和选中的角色 m_touchBegin = loction ; m_pSeleNode = pRoleSprite ; break; } } return true ;}voID GameLayer::ontouchmoved(touch *touch,Event *unused_event){ //角色移动过程中或者角色为null的时候不需要检测是否移动 if ((m_pSeleNode && m_pSeleNode->getNumberOfRunningActions() > 0) || !m_pSeleNode) { return ; } auto loction = this->convertToNodeSpace(touch->getLocation()) ; m_touchmove = loction ; float dis = m_touchmove.getdistance(m_touchBegin) ;//触点移动的距离 auto var = m_touchmove - m_touchBegin ; auto moveByPos = Vec2(0,0) ; auto varColRow = Vec2(0,0) ; if (dis >= m_mindis)//移动 { bool isMoveHor = abs(var.x) > abs(var.y) ;//判断是检测竖直方向的移动还是水平方向的移动 bool isMovetop ;//<如果是竖直方向上,判断是向上还是向下 bool isMoveRight ;//<如果是水平方向上,判断死向右还是向左 if (isMoveHor)//水平方向移动 { isMoveRight = var.x > 0 ; if (var.x > 0)//right { moveByPos = Vec2(75.0f,0) ; varColRow = Vec2(1,0) ; } else//left { moveByPos = Vec2(-75.0f,0) ; varColRow = Vec2(-1,0) ; } } else//竖直方向移动 { isMovetop = var.y > 0 ; if (var.y > 0)//top { moveByPos = Vec2(0,75.0f) ; varColRow = Vec2(0,1) ; } else//bottom { moveByPos = Vec2(0,-75.0f) ; varColRow = Vec2(0,-1) ; } } if (isCanMove(isMoveHor,isMoveHor ? isMoveRight : isMovetop)) { m_pSeleNode->setCol(m_pSeleNode->getCol() + (int)varColRow.x) ; m_pSeleNode->setRow(m_pSeleNode->getRow() + (int)varColRow.y) ; m_pSeleNode->runAction( MoveBy::create(0.5f,moveByPos) ) ; updateMapData() ;//更新地图的状态 } }}voID GameLayer::ontouchended(touch *touch,Event *unused_event){ //重置 m_touchBegin = Vec2(0,0) ; m_touchmove = Vec2(0,0) ; m_pSeleNode = nullptr ;}bool GameLayer::isCanMove(bool isMoveHor,bool moveAdd){ bool isMove = false; CCAssert(m_pSeleNode,"select node should not is null!!") ; int wIDth = m_pSeleNode->getWIDth() ; int height = m_pSeleNode->getHeight() ; int row = m_pSeleNode->getRow() ; int col = m_pSeleNode->getCol() ; if (isMoveHor)//水平方向 { if (moveAdd) { int colTem = col + wIDth; int rowTem = row ; int fillednum = 0 ; for (int i = 0; i < height ; i++) { rowTem += i; if (m_mapState[rowTem][colTem] == 1) { fillednum++ ; } } isMove = (fillednum == 0) ? true : false; if (m_pSeleNode->getCol() == 3) { isMove = false ; } } else { int colTem = col - 1; int rowTem = row ; int fillednum = 0 ; for (int i = 0; i < height ; i++) { rowTem += i; if (m_mapState[rowTem][colTem] == 1) { fillednum++ ; } } isMove = (fillednum == 0) ? true : false; if (m_pSeleNode->getCol() == 0) { isMove = false ; } } } else//竖直方向 { if (moveAdd) { int colTem = col ; int rowTem = row + height ; int fillednum = 0 ; for (int i = 0; i < wIDth; i++) { colTem += i; if (m_mapState[rowTem][colTem] == 1) { fillednum++ ; } } isMove = (fillednum == 0) ? true : false; if (m_pSeleNode->getHeight() == 2) { if (m_pSeleNode->getRow() == 3) { isMove = false ; } } else{ if (m_pSeleNode->getRow() == 4) { isMove = false ; } } } else { int colTem = col ; int rowTem = row - 1 ; int fillednum = 0 ; for (int i = 0; i < wIDth; i++) { colTem += i; if (m_mapState[rowTem][colTem] == 1) { fillednum++ ; } } isMove = (fillednum == 0) ? true : false; if (m_pSeleNode->getRow() == 0)//在最下层的时候,就不能再往下动了 { isMove = false ; } } } return isMove ;}voID GameLayer::updateMapData(){ resetMapData() ; if (m_pRoleSpriteVec.size() == 10)//<需要10个角色1Boss,5将军,4兵 { for (unsigned int i = 0 ;i < m_pRoleSpriteVec.size() ;i++) { RoleSprite * pRoleSprite = m_pRoleSpriteVec.at(i) ; int wIDth = pRoleSprite->getWIDth() ; int heigit = pRoleSprite->getHeight() ; int row = pRoleSprite->getRow() ; int col = pRoleSprite->getCol() ; for (int i = 0 ; i < heigit ; i++) { for (int j = 0 ; j < wIDth ; j++) { m_mapState[row + i][col + j] = 1 ; } } } } /*cclOG("================Test==========================") ; for (int i = 0; i < 5 ; i++) { const char *ppp = "" ; for (int j = 0; j < 4; j++) { ppp = CCString::createWithFormat("%s%d,",ppp,m_mapState[i][j])->getCString() ; } cclOG(ppp) ; }*/}voID GameLayer::resetMapData(){ for (int row = 0 ;row < 5 ; row++) { for (int col = 0 ; col < 4 ; coL++) { m_mapState[row][col] = 0; } }}
源码:http://download.csdn.net/detail/c_boy_lu/8594823
以上是内存溢出为你收集整理的华容道06--屏幕点击事件和角色间的碰撞全部内容,希望文章能够帮你解决华容道06--屏幕点击事件和角色间的碰撞所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)