Cocos2D-X2.2.3学习笔记8(处理精灵单击、双击和三连击事件)
我们依据上一次介绍的触屏事件和事件队列等知识来实现触屏的单击,双击,三连击事件。
下图为我们实现的效果图:
单击精灵跳跃一个高度,
双击精灵跳跃的高度比单击的高
三连击精灵跳跃的跟高
好了,開始动手吧。新建项目,删除多余的代码
接着在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(处理精灵单击、双击和三连击事件)的更多相关文章
- Vue学习笔记-组件通信-子传父(自定义事件)
props用于父组件向子组件传递数据,还有一种比较常见的是子组件传递数据或事件到父组件中.我们应该如何处理呢?这个时候,我们需要使用自定义事件来完成.什么时候需要自定义事件呢?当子组件需要向父组件传递 ...
- STM32学习笔记(九) 外部中断,待机模式和事件唤醒
学会知识只需要不段的积累和提高,但是如何将知识系统的讲解出来就需要深入的认知和系统的了解.外部中断和事件学习难度并不高,不过涉及到STM32的电源控制部分,还是值得认真了解的,在本文中我将以实际代码为 ...
- 【Android开发学习笔记】【第十课】运动事件 之——触摸屏
概念 触摸屏 (TouchScreen) 和 滚动球(TrackBall)是Android 中除了键盘之外的主要输入设备. 而这两个事件都可以用运动事件(MotionEvent)用于接收他们的信息 直 ...
- 【MFC学习笔记-作业9-基于单击响应的计算平均成绩】【】
要求..单击出现 一个输入成绩的框,点确定后,计算平均成绩 意义很大~ 完成对话框 再写个鼠标点击的响应部分 鼠标点击的响应部分为难点.... void CWj1401_0302140107_9V ...
- 【学习笔记】锋利的jQuery(三)事件和动画
一.jQuery事件 1,加载事件 $(document).ready(function(){...}) //等同于$(function(){..}) $(window).load(function( ...
- python学习笔记(3)--IDLE双击运行后暂停
本来想找一个python的IDE什么的,用过pycharm,vs装python插件,软件都太大了,习惯了用sublime写html,js这样的简直受不了. 一直坚持用着python自带的IDLE,不过 ...
- Python3+Selenium3+webdriver学习笔记5(模拟常用键盘和鼠标事件)
#!/usr/bin/env python# -*- coding:utf-8 -*- from selenium import webdriverfrom selenium.webdriver.co ...
- web前端学习(二)html学习笔记部分(8)--服务器推送事件3
1.2.22 html5服务器推送事件 1.2.22.1 html5服务器推送事件介绍 服务器推送事件(Server-sent Events)是HTML5规范中的一个组成部分,可以用来从服务器端实 ...
- 吴裕雄--天生自然python学习笔记:python 用pygame模块检测键盘事件和鼠标事件
用户可通过键盘输入来操控游戏中角色的运动,取得键盘事件的方法有以下两种 : 常用的按键与键盘常数对应表 : 按下右箭头键,蓝色小球会 向 右移动:按住右箭头键不放 , 球体会快速 向 右移 动, 若到 ...
随机推荐
- .net Mvc Controller 接收 Json/post方式 数组 字典 类型 复杂对象
原文地址:http://www.cnblogs.com/fannyatg/archive/2012/04/16/2451611.html ------------------------------- ...
- source insight 下看不了utf-8中文字符
utf-8中文在source insight中显示为乱码,写了一个简单脚本,在linux下将代码转换为GBK格式,然后在source insight下正常查看. #!/bin/sh function ...
- 【Android Training UI】创建自定义Views(Lesson 1 - 创建一个View类)
发布在我的网站 http://kesenhoo.github.io/blog/2013/06/30/android-training-ui-creating-custom-views-lesson-1 ...
- opengl笔记—— glMultMatrixf() 区别 glLoadMatrixf()
能找到最好的解释来自:http://www.gamedev.net/topic/489879-glpushmatrixglpopmatrix--glloadmatrixf/ 原理: glPushMat ...
- Hadoop书籍下载链接
Hadoop书籍推荐1:Hadoop实战(结合经典案例全面讲解hadoop整个技术体系)http://www.db2china.net/club/thread-25148-1-1.html2:Hado ...
- 基于Mesos运行Spark
背景介绍 Spark有多种集群运行模式,例如:Standalone,Yarn,Mesos. 下面就说一下如何在Mesos上运行Spark,这也是官方推荐的一种运行方式. 在运行Sp ...
- PHP自学4——通过函数将数组数据输出到html的Table标签中(使用函数的例子)
这一节其实说实话并没有什么干货,不过为了防止PO主的懒癌的复发,还是坚持放一点东西,即使是内容和长度都令人发指.这一节通过一个函数来实现将数组中的内容输出html的Table标签当中显示. 函数文件— ...
- C++命名准则
总则:命名用英语,单词简单,明了.意义明确.过长的单词可以使用省略.一般是去掉元音字母形成省略.如果有通用的缩写,应该采用通用的缩写. 1.函数命名 1.1:全局函数:采用限定词+动词(+名词的原则) ...
- centOs下的php+mysql+apache+ftp配置
在安装服务器时做了相应的笔记,这个方法是亲身经验成功的,随着版本的不断更新,也许会有一些地方不同,但是基本原理都是一样的. 1.安装CentOS 6 ,可以选择最小安装,也可以安装桌面 2.升级系统 ...
- Android Intent传递数据
刚开始看郭大神的<>,实现以下里面的一些例子.Intent传递数据. 我们利用显示的方式进行Intent的启动. 1.启动intent并输入数据. Intent intent=new In ...