您的位置:首页 > 理论基础 > 计算机网络

cocos2d-x TestCpp中的 多点触控MutiTouchTest、两点手势缩放算法---cocos2d-x学习之路[1]

2013-11-03 21:32 465 查看
准备好好看看testCpp,自己c++基础不行。

本文注释了一下TestCpp中的MutiTouchTest用于多点触控的测试。顺便实现一下两手指缩放一个CCsprite大小的功能,不完善,但基本实现了。

上代码:

TouchScale.h

#ifndef _TOUCHSCALE_SCENE_H_
#define _TOUCHSCALE_SCENE_H_
#include "cocos2d.h"
USING_NS_CC;
class TouchScale: public cocos2d::CCLayer
{
public:
	virtual bool init();
	static cocos2d::CCScene*  scene();
	void menuCloseCallback(CCObject* pSender);
	virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);
	virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
	virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);
	/*ccTouchesCancelled和ccTouchCancelled函数很少用,
	在接到系统中断通知,需要取消触摸事件的时候才会调用此方法。
	如:应用长时间无响应、当前view从window上移除、
	触摸的时候来电话了等。*/
	virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent);

	void FollowMove(CCSet *pTouches, CCEvent *pEvent);
	void DoScale(CCSet *pTouches, CCEvent *pEvent);
	CREATE_FUNC(TouchScale);

public:
	float distance;
	float moveDistance;
	CCPoint mPoint1;
	CCPoint mPoint2;

	CCPoint movePoint1;
	CCPoint movePoint2;
	float beforeScale;
	

};

#endif//_TOUCHSCALE_SCENE_H_


TouchScale.cpp

#include "TouchScale.h"

USING_NS_CC;
//创建个保存颜色的数组,最多5点触控,
static ccColor3B s_TouchColors[CC_MAX_TOUCHES] = {
	ccYELLOW,
	ccBLUE,
	ccGREEN,
	ccRED,
	ccMAGENTA
};//注意加;
//创建一个继承于CCNode的类
class TouchPoint : public CCNode{
public:
	//此类构造函数
	TouchPoint(){
		//使用OPGL的着色器渲染
		setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureColor));

	}
	//类的draw方法。
	virtual void draw(){
		//设置颜色4B颜色
		ccDrawColor4B(m_TouchColor.r,m_TouchColor.g,m_TouchColor.b,255);
		//设置画笔宽度
		glLineWidth(10);
		//以m_pTouchPiont的坐标画十字线线
		ccDrawLine(ccp(0,m_pTouchPiont.y),ccp(getContentSize().width,m_pTouchPiont.y));
		ccDrawLine(ccp(m_pTouchPiont.x,0),ccp(m_pTouchPiont.x,getContentSize().height));
		//将画笔宽度设置回去
		glLineWidth(1);
		//设置点的大小
		ccPointSize(30);
		ccDrawPoint(m_pTouchPiont);
	}
	//设置成员变量的点的位置 取地址
	void setTouchPos(const CCPoint& pt){
		m_pTouchPiont = pt;
	}
	void setTouchColor(ccColor3B color){
		m_TouchColor = color;
	}
	//静态的产生类对象放置于父类node中
	static TouchPoint* touchPointWithParent(CCNode* pParent){
		//新建一个对象
		TouchPoint* pRet =new TouchPoint();
		//设置本对象Draw的显示范围大小为父类NODE的大小!!!!
		pRet->setContentSize(pParent->getContentSize());
		//锚点设置为0,0 左下角
		pRet->setAnchorPoint(ccp(0.0f,0.0f));
		//自动释放
		pRet->autorelease();
		return pRet;
	}
private:
	//此类的成员变量
	CCPoint m_pTouchPiont;
	ccColor3B m_TouchColor;
};
CCScene*  TouchScale::scene(){
	CCScene * scene = CCScene::create();
	TouchScale* layer = TouchScale::create();
	scene->addChild(layer);
	return scene;
}
bool TouchScale::init(){
	bool bRet = false;
	do 
	{
		//1. super init first
		if (!CCLayer::init())
		{
			return false;
		}
		CCSize visibileSize = CCDirector::sharedDirector()->getVisibleSize();
		CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();

		//2.add a menu item with "X"image,which is clicked to quit the program

		//add a "close" icon to exit the progress.it`s an autorelease object
		CCMenuItemImage* pCloseItem = CCMenuItemImage::create("CloseNormal.png",
			"CloseSelected.png",
			this,
			menu_selector(TouchScale::menuCloseCallback));

		pCloseItem->setPosition(ccp(origin.x + visibileSize.width - pCloseItem->getContentSize().width/2 ,
			origin.y + pCloseItem->getContentSize().height/2));
		CCMenu* pMenu = CCMenu::create(pCloseItem,NULL);
		pMenu->setPosition(CCPointZero);
		this->addChild(pMenu,1);

		CCSprite* sp = CCSprite::create("heat.png");
		sp->setPosition(ccp(visibileSize.width/2,visibileSize.height/2));
		//sp->setScale(0.4f);
		this->addChild(sp,2,789);
		setTouchEnabled(true);

// 		mPoint2 = ccp(0,0);
// 		movePoint2 = ccp(0,0);
		bRet = true;
	} while (0);
	return bRet;
}
void TouchScale::FollowMove(CCSet *pTouches, CCEvent *pEvent){
	
}
void TouchScale::DoScale(CCSet *pTouches, CCEvent *pEvent){
	
}
static CCDictionary s_dic;
//每次取出的对象pTouches 能确定的是ID号码,以CCset中的getID来进行标识
//永远取出的都是1,应为不可能同时按下,总有先后,所以需要将每次Began的点的坐标保存
//在Moved里取坐标 与Began中的坐标对比,

//控制按到第二下开始计算初始距离
static bool initialD=false;

void TouchScale::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent){
	//CCSet的迭代器
	CCSetIterator iter = pTouches->begin();
	//迭代出pTouches所有Touches
	for (;iter!= pTouches->end();iter++)
	{
		//取出Touches
		CCTouch* pTouch = (CCTouch*)(*iter);
		//得到取出的Touch的位置坐标
		CCPoint location = pTouch->getLocation();

		//通过TouchPiont的静态方法得到 TouchPiont
		TouchPoint* pTouchPoint = TouchPoint::touchPointWithParent(this);
		//对新建的pTouchPoint进行位置以及颜色的设置
		pTouchPoint->setTouchPos(location);
		//通过容器中的pTouch的ID取出对应的颜色。最多支持5点
		pTouchPoint->setTouchColor(s_TouchColors[pTouch->getID()]);

		//添加到layer中将这个设置好的pTouchPoint,可以设置覆盖关系
		addChild(pTouchPoint);
		//添加到一个CCDictionary中。类似键值对的方式存入,
		//键使用从CCSetIterator取出的对象的ID进行标识
		//先加入对象,然后是键
		s_dic.setObject(pTouchPoint,pTouch->getID());
		CCLog("getID......%d",pTouch->getID());

		//开始了:
		//第一个点,坐标保存了
		if (pTouch->getID()==0)
		{
			mPoint1 = location;
			CCLog("first Point!");
			initialD = true;

		}
		//有第二个点。坐标保存了。
		if (pTouch->getID()==1&& initialD ==true)
		{
			mPoint2 = location;
			CCLog("second Point!");
			//计算刚按下的距离
			distance = mPoint1.getDistance(mPoint2);
			CCLog("intial Distance.......",distance);

			//得到精灵当前的缩放比例
			beforeScale = ((CCSprite*)getChildByTag(789))->getScale();

		}

	}

}
void TouchScale::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent){
	CCSetIterator iter = pTouches->begin();
	for (;iter!=pTouches->end();iter++)
	{
		CCTouch* pTouch = (CCTouch*)(*iter);
		//得到触摸点的坐标
		CCPoint location = pTouch->getLocation();
		//从自己的容器中按CCtouch的ID取出对应的对象
		TouchPoint* pTP =(TouchPoint*)s_dic.objectForKey(pTouch->getID());
		//将对象坐标修改为CCset按ID标识的CCTouch得到的坐标位置
		pTP->setTouchPos(location);

		//使用第一个按下的点与第二个点的坐标计算一下距离

		if (distance!=0)
		{
			if (pTouch->getID()==0)
			{
				movePoint1 = location;

			}
			if (pTouch->getID()==1)
			{
				movePoint2 = location;
				//计算移动后两点的距离
				//
				moveDistance = movePoint1.getDistance(movePoint2);
				//移动后的距离/初始距离  得到比例
				float mScale = moveDistance/distance;
				CCLog("Scale=====================%f",mScale);

				//最后缩放以下图片,看看效果
				//((CCSprite*)getChildByTag(789))->setScale(mScale);

				//这样的缩放与android手机上的照片缩放不一样,因为每次获取的初始距离与刚移动后的距离都在1.0附近,
				//缩放都从精灵的原始尺寸开始的。如何在结束缩放后 将精灵的缩放比例保存?在手指离开屏幕后保存缩放比例,下次按下计算

				
				//在原有比例上再进行缩放,原有比例在按下的时候获取

				if (beforeScale*mScale>0.5f  && beforeScale*mScale<2.0f)
				{
					((CCSprite*)getChildByTag(789))->setScale(beforeScale*mScale);
				}
				//((CCSprite*)getChildByTag(789))->setScale(beforeScale*mScale);

				 //缩放的太快了,怎样降低缩放速度,增加用户体验,减少缩放的比例

			}
		}
	}

}
void TouchScale::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent){
	CCSetIterator iter = pTouches->begin();
	for (;iter!=pTouches->end();iter++)
	{
		CCTouch* pTouch = (CCTouch*)(*iter);
		//从自己的容器中取出pTouch
		TouchPoint* pTP = (TouchPoint*)s_dic.objectForKey(pTouch->getID());
		//Layer中删除这个Touch
		removeChild(pTP,true);
		//从自己的容器中以pTouch的ID删除这个对象TouchPoint
		s_dic.removeObjectForKey(pTouch->getID());
	}
	//只要有手指拿起来,就让初始距离为0
	distance = 0;
	initialD = false;

	CCLog("ccTouchesEnded...");
}
void TouchScale::ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent){
	ccTouchesEnded(pTouches,pEvent);
}

void TouchScale::menuCloseCallback(CCObject* pSender){
	CCDirector::sharedDirector()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
	exit(0);
#endif

}


以前一直用cygwin编译so库,找了一堆教程终于可以使用python创建多平台(cocos2d-x 2.1.4),不用cygwin直接用ndk在eclipse中就能编译,好复杂全是坑。但是终于能用了。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: