基于cocos2d-x引擎的角色控制器

最近开始学习cocos2d-x引擎,用来做一些2d小游戏。在基本做完一个飞机大战游戏的情况下,感觉手机玩沙盒2d游戏需要一个控制角色移动的控制手柄,不然光靠点屏幕是不精确而又费劲的体验。于是开始写了一个角色控制器RoleController,效果如下

效果还行吧

项目地址
https://github.com/Ccapton/Cocos2d-x-RoleController
演示程序apk
https://raw.githubusercontent.com/Ccapton/Cocos2d-x-RoleController/master/Fightman-debug.apk

RoleController.h内容

#ifndef __ROLE_CONTROLLER_H__
#define __ROLE_CONTROLLER_H__

#include "cocos2d.h"
USING_NS_CC;

#include "string"


class RoleControllerListenr {
public:
    // velocity 为控制球相对于控制中心的偏移量,
    // 你可以在具体的实现方法内利用定时更新函数对此结果进行利用,进而实现对精灵的位置控制
   virtual void onControllerTouchBegan(Vec2 velocity) = 0;
   virtual void onControllerTouchMoving(Vec2 velocity) = 0;
   virtual void onControllerTouchEnded(Vec2 velocity) = 0;
};

class RoleController : public Layer {
private:
    RoleController() {}
public:
    bool touchIngInside = false;
    float radius = 0;
    float ball_d_bg = 0;
    Vec2 offset;
    Color4F bg_color = Color4F(-1.0f,-1.0f,-1.0f,-1.0f);
    Color4F ball_color = Color4F(-1.0f, -1.0f, -1.0f, -1.0f);;
    Node * tempLayer;
    Node * tempLayer2;
    std::string bg_resouce_path;
    std::string ball_resouce_path;

    static RoleController* createController(float radius,const Vec2 offset);

    RoleControllerListenr * listener;

    virtual bool init(); 

    void createBg();
    void createBall();
     
    void setPositioin(Vec2 position);
    void setOffset(Vec2 offset);
     
    void setBgResoucePath(std::string path);
    void setBallResoucePath(std::string path);

    bool touchBeganCallback(Touch* touch, Event* event);
    void touchMovedCallback(Touch* touch, Event* event);
    void touchEndedCallback(Touch* touch, Event* event);

    void setRoleControllerListenr(RoleControllerListenr * listener);

    CREATE_FUNC(RoleController);
};
#endif

本来想把它做完再发文章的,但是觉得没什么人看我的文章,也就算了,毕竟这个控制器挺简单的。

原理

主要是靠触摸事件来判断手指位置来判断是否其在控制器内,若是则使小圆的位置跟随触摸移动。若一开始触摸从控制器内,然后往外移动最后离开控制器范围,则小球则会在控制内移动然后根据手指落点的位置而在控制器的圆边界上移动。这个控制器最复杂的地方是:

计算这个小球在控制器边界移动的坐标,最后解决了这个算法,一个简单的控制器变完成了9成。.
通过高中数学的解析几何知识

求圆边界坐标

我得到了下面这个算法:

// 控制器小球在控制器边界圆上移动时,其坐标的算法
// targetX,targetY为所求圆边界上的坐标 (这是仅有的两个未知量)
// centerP.x为控制器中心横坐标,centerP.y为控制器中心纵坐标
// touchP.x为触控点横坐标,touchP.y为触控点纵坐标
// distance 为触控点距离控制器中心的距离,radius则是圆形控制器的半径
float targetX = 0, targetY = 0;
if (touchP.x > centerP.x && touchP.y > centerP.y) {
    targetX = centerP.x + radius * (touchP.x - centerP.x) / distance;
    targetY = centerP.y + radius * (touchP.y - centerP.y) / distance;
}else if (touchP.x < centerP.x && touchP.y > centerP.y) {
    targetX = centerP.x - radius * (centerP.x - touchP.x) / distance;
    targetY = centerP.y + radius * (touchP.y - centerP.y) / distance;
}else if (touchP.x < centerP.x && touchP.y < centerP.y) {
    targetX = centerP.x - radius * (centerP.x - touchP.x) / distance;
    targetY = centerP.y - radius * (centerP.y - touchP.y) / distance;
}else if (touchP.x > centerP.x && touchP.y < centerP.y) {
    targetX = centerP.x + radius * (touchP.x - centerP.x) / distance;
    targetY = centerP.y - radius * (centerP.y - touchP.y ) / distance;
}               

最后便是回调结果了,将小球相对于控制器中心的偏移量Vec2传递出去,这里用到了RoleControllerListenr这个类作为接口,你需要在合适的地方继承此接口类并实现其抽象函数

class RoleControllerListenr {
public:
    // velocity 为控制球相对于控制中心的偏移量,
    // 你可以在具体的实现方法内利用定时更新函数对此结果进行利用,进而实现对精灵的位置控制
   virtual void onControllerTouchBegan(Vec2 velocity) = 0;  // 开始触摸控制器
   virtual void onControllerTouchMoving(Vec2 velocity) = 0; // 控制器小球移动中
   virtual void onControllerTouchEnded(Vec2 velocity) = 0;  // 结束触摸控制器
};

后记

很多人估计看到这一头雾水,这里很多的代码是基于cocos2dx这个游戏开发引擎的,看不懂很正常,对游戏开发感兴趣的朋友可以去官网仔细阅读一下文档。好了,关于这个控制器就介绍到这了,希望你们会喜欢。
别忘了关注我,给我星星
https://github.com/Ccapton

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容