cocos2d-x游戏摇杆开发
来源:互联网 发布:程序员 博客 编辑:程序博客网 时间:2024/05/16 00:51
1.最近想做一个横屏格斗类游戏,但当然第一步必不可少的就是开发一个摇杆来控制游戏人物的移动,本来打算在网上找个简单看看,没想到都好几个文件,很麻烦,而且版本太旧了,索性自己动手算了。看看效果图
//没什么人物素材,瞎找的
2.其实总结一下,开发个摇杆原理并不复杂,大概思路就是这样:随便继承自node,sprite,layer都行,两个sprite,一张是摇杆背景,一个是可以移动的部分,然后注册个触摸监听,根据坐标换算成方向传回来。使用的时候就是scheduleupdate中每一帧取出方向,然后对游戏对象sprite进行相应位置改变,同样道理,稍微改一下就能增加各种技能了,不多说废话,直接看代码算了。
3.使用时。
bool GameScene::init():... bg = Sprite::create("green.png"); bg>setPosition(visibleSize.width/2,visibleSize.height/2); this->addChild(bg); jr = JoyRocker::create(Vec2(100,100)); this->addChild(jr); jr->startRocker(); this->scheduleUpdate();...void GameScene::update(float ft){ switch( jr->getDirection() ) { case 1: bg->setPosition(Vec2(bg->getPosition().x+2,bg->getPosition().y)); break; case 2: bg->setPosition(Vec2(bg->getPosition().x, bg->getPosition().y+2)); break; case 3: bg->setPosition(Vec2(bg->getPosition().x-2,bg->getPosition().y)); break; case 4: bg->setPosition(Vec2(bg->getPosition().x,bg->getPosition().y-2)); break; case 5: bg->setPosition(Vec2(bg->getPosition().x-1,bg->getPosition().y+1)); ;break; case 6: bg->setPosition(Vec2(bg->getPosition().x+1,bg->getPosition().y+1)); ;break; case 7: bg->setPosition(Vec2(bg->getPosition().x-1,bg->getPosition().y-1)); ;break; case 8: bg->setPosition(Vec2(bg->getPosition().x+1,bg->getPosition().y-1)); ;break; default: break; }}
4.主要就两个文件,很容易看懂。
JoyRocker.h
#ifndef __JOY_ROCKER_H__#define __JOY_ROCKER_H__#include "cocos2d.h"USING_NS_CC;#define PI 3.1415926//用于标识摇杆方向typedef enum{ rocker_stay = 0, rocker_right, rocker_up, rocker_left, rocker_down, rocker_leftUp, rocker_rightUp, rocker_leftDown, rocker_rightDown,}rockerDirecton;// 标志 摇杆背景与中心typedef enum{ rockerBackGround = 2, rockerCenter,};class JoyRocker : public Layer{public: //创建摇杆 static JoyRocker* create(Vec2 pos); // 使用摇杆 void startRocker(void); // 停止使用摇杆 void stopRocker(void); // 获取 摇杆 方向 int getDirection(void); // 获取 人物 朝向 bool getIsLeft(void); //触屏事件 virtual bool TouchBegan(Touch* touch, Event* event); virtual void TouchMoved(Touch* touch, Event* event); virtual void TouchEnded(Touch* touch, Event* event); CREATE_FUNC(JoyRocker);private: bool initRocker(Vec2 pos); //获取当前摇杆与用户触屏点的角度 float getRad(Vec2 pos1,Vec2 pos2); // 根据角度,返回点坐标 Vec2 getAnglePosition(float r,float angle); // 摇杆 是否可以移动(是否超过摇杆背景) bool isCanMove; //摇杆 中心的坐标 Vec2 rockerCenterPos; //摇杆背景的半径 float rockerBGR; //摇杆 的半径 float rockerCenterR; //判断控制杆方向,用来判断精灵上、下、左、右、左上、右上、左下、右下 运动 int rocketDirection; // 判断人物是否朝向左面 bool isLeft; EventListenerTouchOneByOne* listener; };#endif
JoyRocker.cpp
#include "JoyRocker.h"JoyRocker* JoyRocker::create(Vec2 pos){ JoyRocker* layer = JoyRocker::create(); if ( layer ) { layer->initRocker(pos); return layer; } CC_SAFE_DELETE(layer); return NULL;}bool JoyRocker::initRocker(Vec2 pos){ // 摇杆背景 图片 Sprite* spRockerBG = Sprite::create("spi_joystickBG.png"); spRockerBG->setPosition(pos); spRockerBG->setTag(rockerBackGround); spRockerBG->setVisible(false); this->addChild(spRockerBG,0); // 摇杆中心 图片 Sprite* spRockerCenter = Sprite::create("spi_joystickCenter.png"); spRockerCenter->setPosition(pos); spRockerCenter->setTag(rockerCenter); spRockerCenter->setVisible(false); this->addChild(spRockerCenter,1); // 设置 摇杆中心 位置 rockerCenterPos = pos; // 获取 摇杆背景 半径 rockerBGR = spRockerBG->getContentSize().width*0.5; //表示摇杆方向不变 rocketDirection = 0; // 事件监听部分 listener = EventListenerTouchOneByOne::create(); // 吞掉这个触摸 listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(JoyRocker::TouchBegan,this); listener->onTouchMoved = CC_CALLBACK_2(JoyRocker::TouchMoved,this); listener->onTouchEnded = CC_CALLBACK_2(JoyRocker::TouchEnded,this); return true;}void JoyRocker::startRocker( void ){ Sprite *rocker = (Sprite*)this->getChildByTag(rockerCenter); rocker->setVisible(true); Sprite *rockerBG = (Sprite*)this->getChildByTag(rockerBackGround); rockerBG->setVisible(true); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); }//停止摇杆(隐藏摇杆,取消摇杆的触屏监听)void JoyRocker::stopRocker(void){ Sprite *rocker = (Sprite *)this->getChildByTag(rockerCenter); rocker->setVisible(false); Sprite * rockerBG = (Sprite *)this->getChildByTag(rockerBackGround); rockerBG->setVisible(false); _eventDispatcher->removeEventListener(listener);}float JoyRocker::getRad(Vec2 pos1,Vec2 pos2){ float px1 = pos1.x; float py1 = pos1.y; float px2 = pos2.x; float py2 = pos2.y; //得到两点x的距离 float x = px2 - px1; //得到两点y的距离 float y = py1 - py2; //算出斜边长度 float xie = sqrt(pow(x,2) + pow(y,2)); //得到这个角度的余弦值(通过三角函数中的点里:角度余弦值=斜边/斜边) float cosAngle = x / xie; //通过反余弦定理获取到期角度的弧度 float rad = acos(cosAngle); //注意:当触屏的位置Y坐标<摇杆的Y坐标,我们要去反值-0~-180 if (py2 < py1) { rad = -rad; } return rad;}// 根据角度,返回点坐标Vec2 JoyRocker::getAnglePosition(float r,float angle){ return Vec2(r*cos(angle),r*sin(angle));}bool JoyRocker::TouchBegan(Touch* touch, Event* event){ Sprite* sp = (Sprite*)this->getChildByTag(rockerCenter); //得到触屏点坐标 Vec2 point = touch->getLocation(); //判断是否点击到sp这个精灵:boundingBox()精灵大小之内的所有坐标 if(sp->boundingBox().containsPoint(point)) { // 可以移动了 isCanMove = true; } return true;}// 获取移动方向int JoyRocker::getDirection(void){ return rocketDirection;}// 获取正面朝向,true为向右,false向左bool JoyRocker::getIsLeft(void){ return isLeft;}void JoyRocker::TouchMoved(Touch* touch, Event* event){ // 如果不能移动,直接返回 if(!isCanMove) { return; } Sprite* sp = (Sprite*)getChildByTag(rockerCenter); Vec2 point = touch->getLocation(); //得到摇杆与触屏点所形成的角度 float angle = getRad(rockerCenterPos,point); //判断两个圆的圆心距是否大于摇杆背景的半径 if (sqrt(pow((rockerCenterPos.x - point.x),2) + pow((rockerCenterPos.y - point.y),2)) >= rockerBGR) { //保证内部小圆运动的长度限制 sp->setPosition(ccpAdd(getAnglePosition(rockerBGR,angle),Vec2(rockerCenterPos.x,rockerCenterPos.y))); } else { //当没有超过,让摇杆跟随用户触屏点移动即可 sp->setPosition(point); } //判断方向 // 右方 if( angle>=-PI/8 && angle<PI/8 ) { rocketDirection = rocker_right; isLeft = false; } // 右上方 else if( angle>=PI/8 && angle<3*PI/8 ) { rocketDirection = rocker_rightUp; isLeft = false; } // 上方 else if( angle>=3*PI/8 && angle<5*PI/8 ) { rocketDirection = rocker_up; } // 左上方 else if( angle>=5*PI/8 && angle<7*PI/8 ) { rocketDirection = rocker_leftUp; isLeft = true; } // 左方 else if( (angle>=7*PI/8&&angle<=PI) || (angle>=-PI&&angle<-7*PI/8) ) { rocketDirection = rocker_left; isLeft = true; } // 左下方 else if( angle>=-7*PI/8 && angle<-5*PI/8 ) { rocketDirection = rocker_leftDown; isLeft = true; } // 下方 else if( angle>=-5*PI/8 && angle<-3*PI/8 ) { rocketDirection = rocker_down; } // 右下方 else if( angle>=-3*PI/8 && angle<-PI/8 ) { rocketDirection = rocker_rightDown; isLeft = false; }}void JoyRocker::TouchEnded(Touch* touch, Event* event){ if(!isCanMove) { return; } // 获取 摇杆背景 与 摇杆中心 Sprite* rocker = (Sprite*)getChildByTag(rockerCenter); Sprite* rockerBG = (Sprite*)getChildByTag(rockerBackGround); // 让 摇杆中心 停止之前所有动作,然后开始 执行归位 rocker->stopAllActions(); rocker->runAction(MoveTo::create(0.08, rockerBG->getPosition())); // 设置 方向为 stay,并且 在下次触摸开始前 不可移动 rocketDirection=rocker_stay; isCanMove = false; }
5大概就这么多,可以直接用,完整游戏还在开发中,以后再写吧.
0 0
- cocos2d-x游戏摇杆开发
- cocos2d-x游戏摇杆的实现方法
- 【iOS-cocos2d-X 游戏开发之十二】自定义Cocos2dx摇杆(增强Joystick),增加摇杆跟随用户触点作为摇杆坐标,让摇杆不再死板!
- Cocos2d-x虚拟摇杆控制精灵上下左右运动----之游戏开发《赵云要格斗》(1)
- 小小菜之Cocos2d-x游戏开发旅程——Lua之摇杆实现
- cocos2d-x摇杆JoyStick
- cocos2d-x游戏实例(13)-简易摇杆控制主角
- cocos2d-x-3.3-018-游戏摇杆joystick源码分享
- cocos2d-x游戏实例(13)-简易摇杆控制主角
- cocos2d-x游戏开发
- Cocos2d-x虚拟摇杆控制精灵上下左右运动----之游戏开发《赵云要格斗》(1) cocos2dx 3.3移植版
- cocos2d-x模拟摇杆
- cocos2d-x下实现摇杆
- cocos2d-x 街机摇杆 实现
- cocos2d-x游戏开发详解
- COCOS2D-X游戏开发常用工具
- cocos2d-x游戏开发之一
- cocos2D-x游戏开发多线程
- 简单的MapReduce程序wordCount
- UIFramework之功能分析
- 初学者parseInt()和parseFloat()的理解(仅供参考,老司机笔下留情)
- 使用wxWidgets进行跨平台的C++开发
- g_2 + g_3
- cocos2d-x游戏摇杆开发
- 微痕迹简介
- onclick 点击事件
- 获取客户端IP
- jsp中几种包含页面的方式区别
- 仿京东移动端手指拨动切换轮播图效果
- (笔记)MVC模式
- rman如何在nomount模式下恢复丢失的所有控制文件
- try catch 中带返回值执行顺序