Cocos2D-X2.2.3学习笔记8(处理精灵单击、双击和三连击事件)

Cocos2D-X2.2.3学习笔记8(处理精灵单击、双击和三连击事件)

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

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

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

单击精灵跳跃一个高度,

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

三连击精灵跳跃的跟高

Cocos2D-X2.2.3学习笔记8(处理精灵单击、双击和三连击事件)

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

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

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

Cocos2D-X2.2.3学习笔记8(处理精灵单击、双击和三连击事件)

Cocos2D-X2.2.3学习笔记8(处理精灵单击、双击和三连击事件)

由于要实现精灵能接受触屏事件,所以我们不能用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 执行,点击屏幕,看输出窗体Cocos2D-X2.2.3学习笔记8(处理精灵单击、双击和三连击事件)

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

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


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坐标,然后后面两个參数都懂的

Cocos2D-X2.2.3学习笔记8(处理精灵单击、双击和三连击事件)

如果精灵是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一下)


附源代码




版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118612.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • celery启动命令_不root卸载系统软件

    celery启动命令_不root卸载系统软件这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML图表FLowchart流程图导出与导入导出导入欢迎使用Ma…

    2022年8月10日
  • 需求规格说明书是给谁看的(需求规格说明书是谁写的)

    写在前面如果你明确清晰知道需求规格说明书是什么,则可以忽略此文章。如果你不清晰,建议还是阅读一下本文,不然也许早晚会碰钉子。转载请标明出处:http://blog.csdn.net/ouyida3/article/details/46045261本文出自:【ouyida3的博客】起因最近在做项目时,根据项目计划,在用户输出了《需求书》后,需要我在2天编写出《需求规格说明书》,但是就这个说明

    2022年4月11日
  • 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法…

    台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法…有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始”菜单或者左下角的windows标志处,找到“控制面板”然后找到”windowsupdate”把这微软默认的更新程序给关闭掉,可解决!(经测试,此方法能解决大多数这种问题)如果解决…

    2022年6月15日
  • vuecli安装_离线安装vuecli

    vuecli安装_离线安装vuecli前言vue-cli是和vue进行深度组合的工具,可以快速帮我们创建vue项目,并且把一些脚手架相关的代码给我们创建好。真正使用vue开发项目,都是用vue-cli来创建项目的。vue-cli介绍

    2022年7月29日
  • R语言安装软件包[通俗易懂]

    R语言安装软件包[通俗易懂]R语言安装软件包1打开RGui.exe,执行“`install.packages(“softwarename”)“`,安装成功后会提示“`Thedownloadedbinarypackagesarein…“`,给出了程序包存放路径2选择程序包,点击“`Installpackage(s)fromlocalfiles…“`,选中路径里面下载好的程序包,会出现“`successfullyunpacked“`的提示3命令及执行结果示例1打开RGui.exe,

    2022年6月27日
  • 机器视觉光源的选择_机器视觉光源选择方法

    机器视觉光源的选择_机器视觉光源选择方法环形光源主要是为机器视觉,工业检测灯方面的LED光源,具有亮度可调,低温,均衡,无闪烁,无阴影,同时在特用的内嵌式的结构,同时可以添加偏光片加上光线的干扰应用实例电路板字符检测包装检测易拉罐罐底检测食

    2022年8月1日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号