//
// RockerDemo.h
// HelloworldTwo
//
// Created by student on 16-1-4.
//
//
#ifndef __HelloworldTwo__RockerDemo__
#define __HelloworldTwo__RockerDemo__
#include <stdio.h>
#include "cocos2d.h"
USING_NS_CC;
//用于标识摇杆与摇杆的背景
typedef enum{
tag_rocker,
tag_rockerBG,
}tagForHRocker;
//用于标识摇杆方向
typedef enum{
rocker_stay,
rocker_right,
rocker_up,
rocker_left,
rocker_down,
}tagDirecton;
class HRocker : public Layer
{
public:
HRocker(void);
~HRocker(void);
//创建摇杆(摇杆的操作题图片资源名,摇杆背景图片资源名,起始坐标)
static HRocker* createHRocker(const char *rockerImageName,const char *rockerBGImageName,Vec2 position);
//启动摇杆(显示摇杆、监听摇杆触屏事件)
void startRocker();
//停止摇杆(隐藏摇杆,取消摇杆的触屏监听)
void stopRocker();
//判断控制杆方向,用来判断精灵上、下、左、右运动
int rocketDirection;
//当前人物行走方向,用来判断精灵的朝向,精灵脸朝右还是朝左
bool rocketRun;
CREATE_FUNC(HRocker);
private:
//自定义初始化函数
void rockerInit(const char* rockerImageName,const char* rockerBGImageName,Vec2 position);
//是否可操作摇杆
bool isCanMove = false;
//获取当前摇杆与用户触屏点的角度
float getRad(Vec2 pos1,Vec2 pos2);
Vec2 getAngelPosition(float r,float angle);
//摇杆背景的坐标
Vec2 rockerBGPosition;
//摇杆背景的半径
float rockerBGR;
};
class Rocker : public Layer
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
CREATE_FUNC(Rocker);
private:
HRocker* rocker;
};
#endif /* defined(__HelloworldTwo__RockerDemo__) */
//
// RockerDemo.cpp
// HelloworldTwo
//
// Created by student on 16-1-4.
//
//
#include "RockerDemo.h"
Scene* Rocker::createScene()
{
auto scene = Scene::create();
auto layer = Rocker::create();
scene->addChild(layer);
return scene;
}
bool Rocker::init()
{
if ( !Layer::init() )
{
return false;
}
//添加摇杆
rocker = HRocker::createHRocker("Direction_bt.png","Direction_bc.png",Vec2(110,60));//其中第一张图片为摇杆的按钮,第二张为背景
this->addChild(rocker,2);
rocker->startRocker();
return true;
}
HRocker::HRocker()
{
rocketRun = false;
}
HRocker::~HRocker()
{
}
//创建摇杆(摇杆的操作图片资源,摇杆背景图片资源,起始坐标)
HRocker* HRocker::createHRocker(const char *rockerImageName, const char *rockerBGImageName, Vec2 position)
{
HRocker* layer = HRocker::create();
if(layer)
{
layer->rockerInit(rockerImageName,rockerBGImageName,position);
return layer;
}
CC_SAFE_RELEASE_NULL(layer);
return layer;
}
void HRocker::rockerInit(const char *rockerImageName, const char *rockerBGImageName, cocos2d::Vec2 position)
{
Sprite* spRockerBG = Sprite::create(rockerBGImageName);
spRockerBG->setPosition(position);
spRockerBG->setVisible(true);
addChild(spRockerBG,0,tag_rockerBG);
Sprite* spRocker = Sprite::create(rockerImageName);
spRocker->setPosition(position);
spRocker->setVisible(true);
addChild(spRocker,0,tag_rocker);
rockerBGPosition = position;
rockerBGR = spRockerBG->getContentSize().width*0.5;
rocketDirection = -1;
}
//监听摇杆触摸事件
void HRocker::startRocker()
{
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->setSwallowTouches(true);
touchListener->onTouchBegan = [=](Touch* touch, Event* event){
Vec2 point = touch->getLocation();
Sprite* rocker = (Sprite*)this->getChildByTag(tag_rocker);
if(rocker->getBoundingBox().containsPoint(point))
{
isCanMove = true;
}
return true;};
touchListener->onTouchMoved = [=](Touch* touch, Event* event){
if(!isCanMove)
{
return;
}
Vec2 point = touch->getLocation();
Sprite* rocker = (Sprite*)this->getChildByTag(tag_rocker);
//得到摇杆与触摸点所形成的角度
float angle = getRad(rockerBGPosition, point);
if(point.distance(rockerBGPosition) >= rockerBGR)
{
if (point.x < rockerBGPosition.x) {
if (point.y > rockerBGPosition.y) {
rocker->setPosition(-getAngelPosition(rockerBGR , angle).x+rockerBGPosition.x,getAngelPosition(rockerBGR , angle).y+rockerBGPosition.y);
}else
{
rocker->setPosition(-getAngelPosition(rockerBGR , angle).x+rockerBGPosition.x,-getAngelPosition(rockerBGR , angle).y+rockerBGPosition.y);
}
}else
{
if (point.y > rockerBGPosition.y) {
rocker->setPosition(getAngelPosition(rockerBGR , angle).x+rockerBGPosition.x,getAngelPosition(rockerBGR , angle).y+rockerBGPosition.y);
}else
{
rocker->setPosition(getAngelPosition(rockerBGR , angle).x+rockerBGPosition.x,-getAngelPosition(rockerBGR , angle).y+rockerBGPosition.y);
}
}
}else
{
rocker->setPosition(point);
}
//判断方向
if(point.x > rockerBGPosition.x && angle <= M_PI_4)
{
// log("右边");
rocketDirection = rocker_right;
rocketRun = false;
}
if(point.x < rockerBGPosition.x && angle <= M_PI_4)
{
// log("左边");
rocketDirection = rocker_left;
rocketRun = true;
}
if (point.y > rockerBGPosition.y && angle > M_PI_4) {
// log("上边");
rocketDirection = rocker_up;
}
if (point.y < rockerBGPosition.y && angle > M_PI_4) {
// log("下边");
rocketDirection = rocker_down;
}
};
touchListener->onTouchEnded = [=](Touch*, Event*){
Sprite *rocker = (Sprite*)this->getChildByTag(tag_rocker);
rocker->setPosition(rockerBGPosition);
rocketDirection = rocker_stay;
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
}
float HRocker::getRad(cocos2d::Vec2 pos1, cocos2d::Vec2 pos2)
{
float offsetX = pos1.x - pos2.x;
float offsetY = pos1.y - pos2.y;
float distance = sqrtf(powf(offsetX, 2)+powf(offsetY, 2));
float cosAngle = sqrtf(powf(offsetX, 2))/distance;
float rad = acosf(cosAngle);
// log("cosAngle = %f,rad = %f",cosAngle,CC_RADIANS_TO_DEGREES(rad));
// if(pos2.y < pos1.y)
// {
// rad = -rad;
// }
return rad;
}
Vec2 HRocker::getAngelPosition(float r, float angle)
{
auto point = Vec2(r*cosf(angle),r*sinf(angle));
// log("x = %f,y = %f",point.x,point.y);
return Vec2(r*cosf(angle),r*sinf(angle));
}