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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Unity+Android GET和POST方式的简单实现API请求(人像动漫化)

    Unity+Android GET和POST方式的简单实现API请求(人像动漫化)Unity与Android的简单交互,Unity打开Android相册并调用

    2022年9月19日
    2
  • Wireshark分析SSL协议[通俗易懂]

    Wireshark分析SSL协议[通俗易懂]SSL:(SecureSocketLayer,安全套接字层),位于可靠的面向连接的网络层协议和应用层协议之间的一种协议层。SSL通过互相认证、使用数字签名确保完整性、使用加密确保私密性,以实现客户端和服务器之间的安全通讯。该协议由两层组成:SSL记录协议和SSL握手协议。TLS:(TransportLayerSecurity,传输层安全协议),用于两个应用程序之间提供保密性和数据完整性。该协议由两层组成:TLS记录协议和TLS握手协议。SSL/TLS位于传输层和应用层之间,应用层数据不再直接传递

    2022年6月1日
    52
  • 视频传输协议(常用的视频协议)

    SDP协议RTPRTCPSRTPRTP只负责传输数据包,需要与RTCP配合使用,由RTCP来保证RTP数据包的服务质量。每一个RTP数据报都由头部(Header)和负载(Payload)两个部分组成,其中头部前12个字节的含义是固定的,而负载则可以是音频或者视频数据。整个IP报文由IP报头、UDP报头、RTP报头、RTPPayload(音频或视频数据)组成, IP协议最大传输单元(MTU)最大为1500字节,其中包括至少20字节的IP头、8字节的UDP头、12字节的RTP头, 这样,头信息

    2022年4月17日
    103
  • CSS加JS实现网页返回顶部功能

    CSS加JS实现网页返回顶部功能最近在设计自己的博客,前端页面在内容很多的时候往下拖动会有滚动条。通常我们都需要一个返回顶部的功能来实现快速来到网页顶部。当然实现方式不止一种,这里我采用的最实用的一种。使用CSS+Jquery方式代码量相对较少,容易理解。实现原理1.我们需要再DOM中添加自己的DIV,里面包含一个a标签,a标签里面包含两个img标签用于存放返回顶部的图片。2.添加必要的CSS样式3.然后…

    2022年7月15日
    15
  • arduino连接lcd1602_1602显示摄氏度

    arduino连接lcd1602_1602显示摄氏度##Arduinouno连接LCD1602A显示测试温度面包板接线图代码#include<LiquifdCrystal.h>//引入依赖/*初始化针脚*/constintrs=3;constinten=5;constintd4=10;constintd5=11;constintd6=12;constintd7=13;constintlcdlight=9;//调节对比度LiquidCry

    2022年9月14日
    0
  • 在Android Library的Module中按渠道依赖

    在Android Library的Module中按渠道依赖

    2021年6月15日
    123

发表回复

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

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