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一下)


附源代码




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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 零基础学Java(10)面向对象-使用LocalDate类完成日历设计

    零基础学Java(10)面向对象-使用LocalDate类完成日历设计前言在我们完成这个日历设计前,需要了解Java中的预定义类LocalDate的一些用法语法LocalDate.now()//2022-07-01会构造一个新对象,表示构造这个对象时的日期。

  • 等价类划分法三角形测试用例_三角形等价类划分

    等价类划分法三角形测试用例_三角形等价类划分测试用例实例--三角形用例设计测试一个图形是不是三角形,需考虑到三角形的性质要求。除了满足ABC均是整数且大于0,还需满足A>0,B>0,C>0,且A+B>C,B+C>A,A+C>B。如果是等腰的,还要判断A=B,或B=C,或A=C。如果是等边的,则需判断是否A=B,且B=C,且A=C。输入条件有效等价类无效等价类

    2022年10月17日
  • JavaScript中的document.cookie的使用

    JavaScript中的document.cookie的使用 我们已经知道,在document对象中有一个cookie属性。但是Cookie又是什么?“某些Web站点在您的硬盘上用很小的文本文件存储了一些信息,这些文件就称为Cookie。”——MSIE帮助。一般来说,Cookies是CGI或类似,比HTML高级的文件、程序等创建的,但是javascript也提供了对Cookies的很全面的访问权利。  我们先要学

  • 一个字节等于多少位?「建议收藏」

    一个字节等于多少位?「建议收藏」一个字节=一个byte=8位一个字=两个byte=16位,java中:byte=8位short=2byte=16位int=4byte=32位long=8byte=64位float=4byte=32位double=8byte=64位char=4byte=32位string=可占用Integer.MAX_VALUE个char=(32*Integer.MAX_VALUE)位…

  • Tomcat配置阿里云SSL证书[通俗易懂]

    Tomcat配置阿里云SSL证书[通俗易懂]记录一次令我蛋疼的tomcat配置SSL证书在阿里云平台获取到SSL证书,并下载,里面有两个文件将证书copy到tomcat下的conf文件夹下,然后配置server.xml文件修改内容如下:<Connectorport=”443″protocol=”org.apache.coyote.http11.Http11NioProtocol”maxTh…

  • 表单编号和文件编号_php制作一个表单

    表单编号和文件编号_php制作一个表单在实际的编程中,表单的HTML代码和获取表单的PHP程序可以分别写到两个文件中,也可以写到同一个PHP文件中。初学Web交互编程时,为了简便,可以使用后者,因为这样做可以减少网站内网页文件的数量。

发表回复

您的电子邮箱地址不会被公开。

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