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


相关推荐

  • 浅谈VMware的NAT模式「建议收藏」

    浅谈VMware的NAT模式「建议收藏」什么是NAT模式?理论化的措辞我就不说了,我将结合本人平时的经验来简单的说明一下NAT模式,以及配置NAT模式时遇到的问题。大家都知道,我们的电脑要想联网,需要与交换机连接,假设交换机的网关为192.168.1.1,那么我们的电脑的ip必定在相同的网段,比如192.168.1.101,网关必定是192.168.1.1。现在我们向通过NAT模式将主机与虚拟机连接起来,即主机可以ping的通虚拟机…

    2022年6月16日
    28
  • vs2008安装失败解决办法「建议收藏」

    vs2008安装失败解决办法「建议收藏」

    由于各种蛋疼原因,卸载了VS2010换08.比较痛恨的是VS的卸载总是卸不干净,这种问题对于微软来说很难吗??
    开始还以为装不上08是因为2010没有卸载干净,结果搜索后发现时office2007的问题。
    代码:[01/13/10,18:55:42] setup.exe: [2] ISetupComponent::Pre/Post/Install() failed in ISetupManager::InternalInstallManager() with H

    2022年9月7日
    1
  • CSS3 background-size图片自适应

    CSS3 background-size图片自适应

    2021年9月21日
    46
  • 程序员看过都说好的资源网站,你懂得![通俗易懂]

    程序员看过都说好的资源网站,你懂得![通俗易懂]身为一个程序员,有时候为了程序的界面好看,不得不去查找一些好看的图标或者图片等来装饰网站,那么问题来了,去哪里找?不用慌,程序羊为大家整理了一些常用的网站,希望能对您有帮助!后续还会不断更新。喜欢记得关注程序羊喔,不然下次您就找不到程序羊了。

    2022年6月10日
    80
  • MATLAB学习(3)

    MATLAB学习(3)

    2021年12月2日
    37
  • vue 计数器_vue实现计算器

    vue 计数器_vue实现计算器计数器的实现在页面上简单实现一个计数器<!DOCTYPEhtml><htmllang="en"><head><metach

    2022年7月30日
    4

发表回复

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

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