我们依据上一次介绍的触屏事件和事件队列等知识来实现触屏的单击,双击,三连击事件。

下图为我们实现的效果图:

单击精灵跳跃一个高度,

双击精灵跳跃的高度比单击的高

三连击精灵跳跃的跟高

好了,開始动手吧。新建项目,删除多余的代码

接着在Classes文件夹下建立两个文件,这里我就命名为Human了

(在Classes上右键加入�新建项,选择头文件,名称Human.h,位置浏览到Classes文件夹下)

由于要实现精灵能接受触屏事件,所以我们不能用CCSprite ,须要自己写个类继承CCSprite和CCTouchDelegate

还记得CCTouchDelegate类吗??

OK   我们先实现头文件

#ifndef _Human_H_
#include "cocos2d.h"
USING_NS_CC;
class Human:public CCSprite,public CCTouchDelegate
{
public:
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void onEnter();
virtual void onExit();
//创建静态方法,用于创建Human精灵
static Human* create(const char *pszFileName);
private: }; #endif // !_Human_H_

重写的这5个方法应该不用解释了,上一节介绍过的

(教大家一个小技巧,比方我不记得触屏事件的名称或參数怎么写来着,没事,不用死机硬背的,鼠标放在CCTouchDelegate上F12,就能够看到它们都在,多点,单点等等,你复制一份就哦了。)

接着我们来实现CPP文件

#include "Human.h"
bool Human::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
CCLOG("ccTouchBegan");
return true;
}
void Human::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
CCLOG("ccTouchMoved");
}
void Human::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
CCLOG("ccTouchEnded");
}
void Human::onEnter()
{
//继承,重载方法的步骤我们实现了,接下来就是注冊
//第一步:将我们须要处理触屏事件的类加入�到事件队列中dispatcher
CCSprite::onEnter();
CCTouchDispatcher *dispatcher= CCDirector::sharedDirector()->getTouchDispatcher();
dispatcher->addTargetedDelegate(this,0,true);
}
void Human::onExit()
{
//第二步:卸载
CCTouchDispatcher *dispatcher= CCDirector::sharedDirector()->getTouchDispatcher();
dispatcher->removeDelegate(this);
}
Human* Human::create(const char *pszFileName)
{
Human *pobSprite = new Human();
if (pobSprite && pobSprite->initWithFile(pszFileName))
{
pobSprite->autorelease();
return pobSprite;
}
CC_SAFE_DELETE(pobSprite);
return NULL;
}

这里凝视非常具体了,或许大家写不出create方法里面的代码吧?写不出没关系,看得懂即可了,以后熟练了就能够写出来了,我们找到CCSprite中的create方法的实现代码。照着写即可了,主要将

 CCSprite *pobSprite = new CCSprite();

改为

Human *pobSprite = new Human();

F6编译一下看看是否出错?

成功了?那接着

bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
Human *humanSprite=Human::create("Icon.png");
humanSprite->setPosition(ccp(240,30));
this->addChild(humanSprite);
return true;
}

这里不是CCSprite了,是我们自己定义的精灵,它能够接受触屏事件的响应

OK 执行,点击屏幕,看输出窗体

有个小问题,不一定点击精灵才触发事件,点击屏幕的不论什么地方都会触发事件,这不是我们想要的结果。

我们须要的是仅仅有触摸点在精灵图片的范围内才触发事件

OK,我们在新增一个方法  containsTouchLocation

//推断触摸点是否在精灵范围内
bool containsTouchLocation(CCTouch *pTouch);

实现

#ifndef _Human_H_
#include "cocos2d.h"
USING_NS_CC;
class Human:public CCSprite,public CCTouchDelegate
{
public:
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void onEnter();
virtual void onExit();
//创建静态方法,用于创建Human精灵
static Human* create(const char *pszFileName);
//推断触摸点是否在精灵范围内
bool containsTouchLocation(CCTouch *pTouch);
private: }; #endif // !_Human_H_

CPP

#include "Human.h"
bool Human::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
return true;
}
void Human::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
if (containsTouchLocation(pTouch))
{
CCLOG("ccTouchEnded");
}
} bool Human::containsTouchLocation(CCTouch *pTouch)
{
//首先须要获得精灵的大小,将它转换为一个CCRect(矩形)
CCSize spriteSize= this->getContentSize();
CCRect rect=CCRectMake(-spriteSize.width/2,-spriteSize.height/2,spriteSize.width,spriteSize.height);
//通过CCRect中的containsPoint,来推断这个矩形是否包括这个点
//这个点为我们的触摸点
if(!rect.containsPoint(this->convertTouchToNodeSpaceAR(pTouch)))
{
return false;
}
return true;
}
void Human::onEnter()
{
//继承,重载方法的步骤我们实现了,接下来就是注冊
//第一步:将我们须要处理触屏事件的类加入�到事件队列中dispatcher
CCSprite::onEnter();
CCTouchDispatcher *dispatcher= CCDirector::sharedDirector()->getTouchDispatcher();
dispatcher->addTargetedDelegate(this,0,true);
}
void Human::onExit()
{
//第二步:卸载
CCTouchDispatcher *dispatcher= CCDirector::sharedDirector()->getTouchDispatcher();
dispatcher->removeDelegate(this);
}
Human* Human::create(const char *pszFileName)
{
Human *pobSprite = new Human();
if (pobSprite && pobSprite->initWithFile(pszFileName))
{
pobSprite->autorelease();
return pobSprite;
}
CC_SAFE_DELETE(pobSprite);
return NULL;
}

这里都有凝视了,

第一,先获得精灵的大小(ContentSize)将其转换为CCRect(矩形)

第二,利用CCRect中的containsPoint方法来推断这个矩形是否包括这个点,包括返回true否则反之

(这里须要把触摸点的位置转换为相对当前精灵节点的相对位置

我们介绍坐标系统的时候貌似仅仅提到过UIKIT坐标,OPGL坐标,事实上还有个相对坐标和世界坐标

我们在讲完这个实列之后再介绍,如今先这样写着)

这里另一句

CCRect rect=CCRectMake(-spriteSize.width/2,-spriteSize.height/2,spriteSize.width,spriteSize.height);

非常纳闷为什么是 -spriteSize.width/2

刚開始我也非常郁闷,根本看不懂,后来直接盯着这段代码不眨眼盯了半小时,瞬间懂了,

我们学习坐标系统都知道默认锚点是在中心点吧?精灵也是

我们得求出左下角点的x和y坐标,然后后面两个參数都懂的

如果精灵是40X40的图片,锚点在中心,所以中心点为0,0坐标   然后四个角的坐标如上图。

如今我们要的出左下角的坐标,瞬间懂了吗??



如今我们差点儿相同完毕一半了,事实上我们在CCTouchEnded方法中完毕我们的跳跃效果,可是这仅仅是单击跳跃,多连击还是得我们自己实现

#ifndef _Human_H_
#include "cocos2d.h"
USING_NS_CC;
class Human:public CCSprite,public CCTouchDelegate
{
public:
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void onEnter();
virtual void onExit();
//创建静态方法,用于创建Human精灵
static Human* create(const char *pszFileName);
//推断触摸点是否在精灵范围内
bool containsTouchLocation(CCTouch *pTouch);
//构造方法,初始化变量
Human();
//单击调用
void SignleClicked(float dt);
//双击
void DoubleClicked(float dt);
//三连击
void ThreeClicked();
private:
//记录点击的次数
int clickedCount;
}; #endif // !_Human_H_

这里添加�了些方法

//构造方法,初始化变量
Human::Human():clickedCount(0)
{}
//单击调用
void Human::SignleClicked(float dt){
if (clickedCount==1)
{
clickedCount=0;
CCActionInterval* jumpto= CCJumpBy::create(1.4f,CCPointZero,50,1);
this->runAction(jumpto);
} }
//双击
void Human::DoubleClicked(float dt){
if (clickedCount==2)
{
clickedCount=0;
CCActionInterval* jumpto= CCJumpBy::create(1.4f,CCPointZero,120,1);
this->runAction(jumpto);
}
}
//三连击
void Human::ThreeClicked(){
clickedCount=0;
CCActionInterval* jumpto= CCJumpBy::create(1.4f,CCPointZero,220,1);
this->runAction(jumpto);
}

方法的实现大致是这样,推断变量的值,假设是1则运行单击跳跃高度为50,后面的不说了

接着我们在ccTouchEnded函数中用延迟的一个方法来实现各种点击

void  Human::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
if (!containsTouchLocation(pTouch))
{
return;
}
//假设点击在精灵上,则运行
if (clickedCount==2)
{
ThreeClicked();
}
else if (clickedCount==1)
{
//延迟0.25秒运行双击
scheduleOnce(schedule_selector(Human::DoubleClicked),0.25f);
clickedCount++;
}
else
{
//延迟0.25秒运行单击
scheduleOnce(schedule_selector(Human::SignleClicked),0.25f);
clickedCount++;
}
}

这里逻辑有点转只是来,

如果,我们点击一次,它将会运行最后的else   ,而单击的方法要在0.25秒后才运行可是此时变量的值已经为1了

然后我们在0.25秒的时间内在继续点击,它将运行第二个IF中的语句,同理,双击的方法也要在0.25秒后运行,可是此时变量的值已经是2了

这个大家多断点,自己多想想,说不清楚



OK,截止我们的多连击已经搞定了





总结一下:

首先,我们学会了怎样制定自己的精灵

怎样使自己的精灵能处理触屏事件

理解怎样完毕处理触屏事件的几个步骤

怎样推断触摸点是否是点击在指定的矩形区域中,这个非常重要哦

利用计时器延迟巧妙实现处理多连击事件

(还有哪些不懂的代码,自己能够先baidu一下)



附源代码





Cocos2D-X2.2.3学习笔记8(处理精灵单击、双击和三连击事件)的更多相关文章

  1. Vue学习笔记-组件通信-子传父(自定义事件)

    props用于父组件向子组件传递数据,还有一种比较常见的是子组件传递数据或事件到父组件中.我们应该如何处理呢?这个时候,我们需要使用自定义事件来完成.什么时候需要自定义事件呢?当子组件需要向父组件传递 ...

  2. STM32学习笔记(九) 外部中断,待机模式和事件唤醒

    学会知识只需要不段的积累和提高,但是如何将知识系统的讲解出来就需要深入的认知和系统的了解.外部中断和事件学习难度并不高,不过涉及到STM32的电源控制部分,还是值得认真了解的,在本文中我将以实际代码为 ...

  3. 【Android开发学习笔记】【第十课】运动事件 之——触摸屏

    概念 触摸屏 (TouchScreen) 和 滚动球(TrackBall)是Android 中除了键盘之外的主要输入设备. 而这两个事件都可以用运动事件(MotionEvent)用于接收他们的信息 直 ...

  4. 【MFC学习笔记-作业9-基于单击响应的计算平均成绩】【】

    要求..单击出现 一个输入成绩的框,点确定后,计算平均成绩 意义很大~ 完成对话框   再写个鼠标点击的响应部分 鼠标点击的响应部分为难点.... void CWj1401_0302140107_9V ...

  5. 【学习笔记】锋利的jQuery(三)事件和动画

    一.jQuery事件 1,加载事件 $(document).ready(function(){...}) //等同于$(function(){..}) $(window).load(function( ...

  6. python学习笔记(3)--IDLE双击运行后暂停

    本来想找一个python的IDE什么的,用过pycharm,vs装python插件,软件都太大了,习惯了用sublime写html,js这样的简直受不了. 一直坚持用着python自带的IDLE,不过 ...

  7. Python3+Selenium3+webdriver学习笔记5(模拟常用键盘和鼠标事件)

    #!/usr/bin/env python# -*- coding:utf-8 -*- from selenium import webdriverfrom selenium.webdriver.co ...

  8. web前端学习(二)html学习笔记部分(8)--服务器推送事件3

    1.2.22  html5服务器推送事件 1.2.22.1  html5服务器推送事件介绍 服务器推送事件(Server-sent Events)是HTML5规范中的一个组成部分,可以用来从服务器端实 ...

  9. 吴裕雄--天生自然python学习笔记:python 用pygame模块检测键盘事件和鼠标事件

    用户可通过键盘输入来操控游戏中角色的运动,取得键盘事件的方法有以下两种 : 常用的按键与键盘常数对应表 : 按下右箭头键,蓝色小球会 向 右移动:按住右箭头键不放 , 球体会快速 向 右移 动, 若到 ...

随机推荐

  1. 微软已于10月底停止销售预装Windows 7/8.1的电脑

    如果你想买新电脑,但是对Windows 10不感冒,你最好抓紧时间,因为这个月底是Windows7和Windows8.1的最后销售期限.10月31号是你能买到预装这两款操作系统的新电脑的最后一天,微软 ...

  2. OC基础3:一些基本概念

    "OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.关于NSLog函数中的“%2i”: ( ...

  3. Sumsets(3sum问题,枚举d,c二分a+b)

    Sumsets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9997   Accepted: 2736 Descripti ...

  4. Parallelogram Counting(平行四边形个数,思维转化)

    1058 - Parallelogram Counting    PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit ...

  5. HttpWebResponse请求状态代码

    HttpWebResponse请求状态代码标识 成员名称 说明 Continue 等效于 HTTP 状态 100.Continue指示客户端可能继续其请求. SwitchingProtocols 等效 ...

  6. iOS 三维变换

    1:平移 一个4*4的单位矩阵乘以一个P(x,y,z,1)的行向量,则表示此矩阵向x轴移动了x的单位,向Y轴移动了y个单位,向Z轴移动了z个单位,最后获得移动后的目标矩阵是 [ 1, 0, 0, 0  ...

  7. Ubuntu kylin 有可能成为未来中国的主流系统吗?

    编前语: 无意间开始研究起linux,因为目前互联网很多人,包括我都隐约感觉到,windows系统在中国乃至世界在今后的流行度会逐步降低,不为什么,其中最主要的是安全问题,Microsoft 微软公司 ...

  8. 读书笔记一 Java程序员的基本修养(数组及其内存管理)

    1.1 数组初始化 1.1.1 java数组是静态的 java数组被初始化之后,该数组所占的内存空间.数组长度都是不可变的. java程序中的数组必须经过初始化才可使用. 数组的初始化有两种方式: 1 ...

  9. asp.net mvc 生成条形码

    using System; using System.Collections; using System.Collections.Generic; using System.Drawing; usin ...

  10. Docker终极指南:为什么Docker能做这么多事

    Docker终极指南:为什么Docker能做这么多事 http://www.aboutyun.com/thread-11499-1-1.html