Cocos2d-x 基础示例-精灵移动2
2012-11-20 00:42
387 查看
Cocos2d-x 基础示例-精灵移动2
先推荐一下红哥的精灵教程
http://blog.csdn.net/honghaier/article/details/8117903
红哥里面使用的ccTouchesMoved,回忆下我之前的教程,使用的是ccTouchesBegan,大家可以体验一下这两种方式的不同。
当我们的手指触碰到屏幕的一瞬间,调用的是ccTouchesBegan,之后手指如果在屏幕上滑动,手指会一直调用ccTouchesMoved,所以大家可以想象一下这两种方式不同。我的方式会无视之后手指的位置,精灵只会向第一个点击的地方移动。而红哥的方式则是无视第一点触碰的坐标,一直会跟着之后的手指位置移动,这就是 began(起始)和moved(滑动)的区别。
但实际上,我们在正常实现触碰+移动的时候,很少使用ccMove家族的成员,最重要的原因是他们非常死板,很不灵活,除了贝塞尔(CCBezier)同学比较受欢迎,其他的同学基本不能和ccTouch家族结合使用。所以接下来,我们会模拟两种比较实用的方式来实现飞机的移动。
1. 精灵以匀速向当前触摸点行动,当触摸取消时,精灵停止。
这种方式相对而言比较常见,让我们一起实现之。
第一步:让我们在ccTouchesMoved函数中添加一下代码:
CCSetIteratorit=pTouches->begin();
CCTouch* touch=(CCTouch*)(*it);
CCPointm_tBeginPos=touch->locationInView();
m_tBeginPos=CCDirector::sharedDirector()->convertToGL(m_tBeginPos);
等!!!
这里插播个话题,这段代码反复出现(ccTouch家族都用他),功能完全一样!如果大家发现这种倒霉代码,最好考虑把他变成一个更可爱的子函数。
我们在helloworld头文件中加入函数声明:
// 触摸相关
CCPoint convertToGL(CCSet *pTouches);
并且一定要保证这位同学跟ccTouches那三兄弟在一起,这才是良好的编程习惯!!不然等代码量上去了,有你哭的那天。
之后的实现如下
CCPoint
HelloWorld::convertToGL(cocos2d::CCSet *pTouches)
{
if (!pTouches) {
CCSetIteratorit=pTouches->begin();
CCTouch* touch=(CCTouch*)(*it);
CCPointm_tBeginPos=touch->locationInView();
m_tBeginPos=CCDirector::sharedDirector()->convertToGL(m_tBeginPos);
return m_tBeginPos;
}
assert(!"pTouches is Null!!!!!");
}
部分同学对这里面的if (!pTouches)和assert(!"pTouches is Null!!!!!"),这是本人编写子函数的一个习惯,这样如果传进来的pTouches参数为空,编译时会直接捕捉到这个错误,而不会继续下传。当然以我们现在这个规模的程序来说,确实是有点杀鸡牛刀了,但我还是推荐大家以后编写子函数的时候使用这种方式
这样这段代码就封装好了,以后我们编写哪个ccTouch的时候,可以直接使用我们convertToGL了!(这个函数的中文意思是“转换成GL”)
于是我们的ccTouchesMoved函数变成了这样
void
HelloWorld::ccTouchesMoved(CCSet *pTouches,
CCEvent *pEvent)
{
CCPoint m_CurrentPos=convertToGL(pTouches);
}
我们现在获取了当前坐标,该让player向目标移动了!
第一:先定义飞机向那儿移动的速度。
在头文件中增加
private:
float playerSpd=1;
定义playerSpd为速度,初始值为1。
第二:找出当前帧移动的单位向量
这里普及一下基础的几何知识,一个从点A和点B的向量AB,它是B点的坐标对应减掉A点的坐标。例如A点坐标是(a1,a2),B点坐标是(b1,b2),那么AB向量为(b1-a1,b2-a2).
但是我们单求“向量”是不对的,我们应该求的是“单位向量”。这个单位向量非常神奇,A点坐标加上(单位向量乘以两点间距离)之后,得出的结果是B点坐标。而速度则是每帧移动的距离,则(单位向量*速度)就可以计算出每帧的点坐标值啦!大家可以理解这个“单位向量”为“方向”。
为了实现这一步,我们可以定义一个子函数来实现上述过程,问题就在于这个子函数应该定义在什么地方。
其实可以思考一下,我们什么时候会用到这个子函数?所有存在CCPoint的情况下!
所以这个子函数最好定义在CCPoint类的类内。
另外一方面,为了能够让过程和数学过程更像,我们需要重载CCPoint的减号“-”,让这个函数支持两个CCPoint类做减法。
So,在CCPoint类的实现中中添加如下两个函数体(声明我就不写了,懒,大家自己加到头文件里吧)
CCPoint&
CCPoint::operator- (const
CCPoint& other)
{
this->x=
this->x-other.x;
this->y=
this->y-other.y;
return *this;
}
另外增加计算单位向量的函数
CCPoint
CCPoint::computeUnitVector()
{
CCPoint p1=*this;
assert(sqrt((p1.x)*(p1.x)+(p1.y)*(p1.y)));
p1.x=p1.x/sqrt((p1.x)*(p1.x)+(p1.y)*(p1.y));
p1.y=p1.y/sqrt((p1.x)*(p1.x)+(p1.y)*(p1.y));
return p1;
}上面这个函数直接计算出某向量的单位向量了.
现在CCPoint类已经不单纯是一个“点”了,它现在还可以表示一个“向量”和“单位向量”,所以我们还需要用到让CCPoint类能够乘以一个speed。
在CCPoint头文件中加入定义,并在在CCPoint实现文件中,加入如下代码:
CCPoint&
CCPoint::operator*(const
float& speed)
{
this->x=this->x*speed;
this->y=this->y*speed;
return *this;
}
另一方面,还需要重载CCPoint的+号函数,能让两个CCPoint相加,得出一个新坐标,具体实现如下
CCPoint&
CCPoint::operator+(const
CCPoint &other)
{
this->x=
this->x+other.x;
this->y=
this->y+other.y;
return *this;
}
OK,让我们回到CCTouchesMoved中;加入如下代码
void
HelloWorld::ccTouchesMoved(CCSet *pTouches,
CCEvent *pEvent)
{
CCPoint m_CurrentPos=convertToGL(pTouches);
//获得当前坐标
CCPoint playerCurPos=player->getPosition();
//如果距离不为0,则向那个方位移动一个速度
if (ccpDistance(playerCurPos,m_CurrentPos)!=0)
{
CCPointm_vector=m_CurrentPos-playerCurPos;
//将m_vector转换为单位向量
m_vector=m_vector.computeUnitVector();
//每次调用ccTouchesMoved的时候,都向单位方向移动一个速度值
player->setPosition(playerCurPos+m_vector*playerSpd);
}
}
现在,当玩家在屏幕上滑动时,飞机就会向触摸的地方移动了。但有一个非常残酷的事实… 现在只有滑动的时候,才会调用CCTouchesMoved - -,CCTouchesMoved对对触摸进行了判断,所以现在这架飞机变成了非常奇异的家伙,你滑动手指,才会向你移动,你不滑动手指,他坚决不动.
很遗憾~苹果在底层做了判断,毕竟,如果手一直按住都响应的话,那设备将及其费电- -,所以我们只能换另外一种方式了~
可以仔细思考一下我们需求的流程,如下:
点击屏幕,则屏幕向该点以一定速度移动。
如果中途发生滑动,则修改该点坐标
如果触摸停止,则此动作停止
所以我们可以采用另外一种方式来实现此功能
ccTouchesBegan用来初始化点坐标,并激活飞机的一个动作,此动作不停得向触摸点移动
ccTouchesMoved用来改变此点的坐标
ccTouchesEnded终结此动作。
我们如果需要实现此功能,则需要以上三个函数协同工作,才能共同达成目标,下一讲将会讲述如何实现此功能。
先推荐一下红哥的精灵教程
http://blog.csdn.net/honghaier/article/details/8117903
红哥里面使用的ccTouchesMoved,回忆下我之前的教程,使用的是ccTouchesBegan,大家可以体验一下这两种方式的不同。
当我们的手指触碰到屏幕的一瞬间,调用的是ccTouchesBegan,之后手指如果在屏幕上滑动,手指会一直调用ccTouchesMoved,所以大家可以想象一下这两种方式不同。我的方式会无视之后手指的位置,精灵只会向第一个点击的地方移动。而红哥的方式则是无视第一点触碰的坐标,一直会跟着之后的手指位置移动,这就是 began(起始)和moved(滑动)的区别。
但实际上,我们在正常实现触碰+移动的时候,很少使用ccMove家族的成员,最重要的原因是他们非常死板,很不灵活,除了贝塞尔(CCBezier)同学比较受欢迎,其他的同学基本不能和ccTouch家族结合使用。所以接下来,我们会模拟两种比较实用的方式来实现飞机的移动。
1. 精灵以匀速向当前触摸点行动,当触摸取消时,精灵停止。
这种方式相对而言比较常见,让我们一起实现之。
第一步:让我们在ccTouchesMoved函数中添加一下代码:
CCSetIteratorit=pTouches->begin();
CCTouch* touch=(CCTouch*)(*it);
CCPointm_tBeginPos=touch->locationInView();
m_tBeginPos=CCDirector::sharedDirector()->convertToGL(m_tBeginPos);
等!!!
这里插播个话题,这段代码反复出现(ccTouch家族都用他),功能完全一样!如果大家发现这种倒霉代码,最好考虑把他变成一个更可爱的子函数。
我们在helloworld头文件中加入函数声明:
// 触摸相关
CCPoint convertToGL(CCSet *pTouches);
并且一定要保证这位同学跟ccTouches那三兄弟在一起,这才是良好的编程习惯!!不然等代码量上去了,有你哭的那天。
之后的实现如下
CCPoint
HelloWorld::convertToGL(cocos2d::CCSet *pTouches)
{
if (!pTouches) {
CCSetIteratorit=pTouches->begin();
CCTouch* touch=(CCTouch*)(*it);
CCPointm_tBeginPos=touch->locationInView();
m_tBeginPos=CCDirector::sharedDirector()->convertToGL(m_tBeginPos);
return m_tBeginPos;
}
assert(!"pTouches is Null!!!!!");
}
部分同学对这里面的if (!pTouches)和assert(!"pTouches is Null!!!!!"),这是本人编写子函数的一个习惯,这样如果传进来的pTouches参数为空,编译时会直接捕捉到这个错误,而不会继续下传。当然以我们现在这个规模的程序来说,确实是有点杀鸡牛刀了,但我还是推荐大家以后编写子函数的时候使用这种方式
这样这段代码就封装好了,以后我们编写哪个ccTouch的时候,可以直接使用我们convertToGL了!(这个函数的中文意思是“转换成GL”)
于是我们的ccTouchesMoved函数变成了这样
void
HelloWorld::ccTouchesMoved(CCSet *pTouches,
CCEvent *pEvent)
{
CCPoint m_CurrentPos=convertToGL(pTouches);
}
我们现在获取了当前坐标,该让player向目标移动了!
第一:先定义飞机向那儿移动的速度。
在头文件中增加
private:
float playerSpd=1;
定义playerSpd为速度,初始值为1。
第二:找出当前帧移动的单位向量
这里普及一下基础的几何知识,一个从点A和点B的向量AB,它是B点的坐标对应减掉A点的坐标。例如A点坐标是(a1,a2),B点坐标是(b1,b2),那么AB向量为(b1-a1,b2-a2).
但是我们单求“向量”是不对的,我们应该求的是“单位向量”。这个单位向量非常神奇,A点坐标加上(单位向量乘以两点间距离)之后,得出的结果是B点坐标。而速度则是每帧移动的距离,则(单位向量*速度)就可以计算出每帧的点坐标值啦!大家可以理解这个“单位向量”为“方向”。
为了实现这一步,我们可以定义一个子函数来实现上述过程,问题就在于这个子函数应该定义在什么地方。
其实可以思考一下,我们什么时候会用到这个子函数?所有存在CCPoint的情况下!
所以这个子函数最好定义在CCPoint类的类内。
另外一方面,为了能够让过程和数学过程更像,我们需要重载CCPoint的减号“-”,让这个函数支持两个CCPoint类做减法。
So,在CCPoint类的实现中中添加如下两个函数体(声明我就不写了,懒,大家自己加到头文件里吧)
CCPoint&
CCPoint::operator- (const
CCPoint& other)
{
this->x=
this->x-other.x;
this->y=
this->y-other.y;
return *this;
}
另外增加计算单位向量的函数
CCPoint
CCPoint::computeUnitVector()
{
CCPoint p1=*this;
assert(sqrt((p1.x)*(p1.x)+(p1.y)*(p1.y)));
p1.x=p1.x/sqrt((p1.x)*(p1.x)+(p1.y)*(p1.y));
p1.y=p1.y/sqrt((p1.x)*(p1.x)+(p1.y)*(p1.y));
return p1;
}上面这个函数直接计算出某向量的单位向量了.
现在CCPoint类已经不单纯是一个“点”了,它现在还可以表示一个“向量”和“单位向量”,所以我们还需要用到让CCPoint类能够乘以一个speed。
在CCPoint头文件中加入定义,并在在CCPoint实现文件中,加入如下代码:
CCPoint&
CCPoint::operator*(const
float& speed)
{
this->x=this->x*speed;
this->y=this->y*speed;
return *this;
}
另一方面,还需要重载CCPoint的+号函数,能让两个CCPoint相加,得出一个新坐标,具体实现如下
CCPoint&
CCPoint::operator+(const
CCPoint &other)
{
this->x=
this->x+other.x;
this->y=
this->y+other.y;
return *this;
}
OK,让我们回到CCTouchesMoved中;加入如下代码
void
HelloWorld::ccTouchesMoved(CCSet *pTouches,
CCEvent *pEvent)
{
CCPoint m_CurrentPos=convertToGL(pTouches);
//获得当前坐标
CCPoint playerCurPos=player->getPosition();
//如果距离不为0,则向那个方位移动一个速度
if (ccpDistance(playerCurPos,m_CurrentPos)!=0)
{
CCPointm_vector=m_CurrentPos-playerCurPos;
//将m_vector转换为单位向量
m_vector=m_vector.computeUnitVector();
//每次调用ccTouchesMoved的时候,都向单位方向移动一个速度值
player->setPosition(playerCurPos+m_vector*playerSpd);
}
}
现在,当玩家在屏幕上滑动时,飞机就会向触摸的地方移动了。但有一个非常残酷的事实… 现在只有滑动的时候,才会调用CCTouchesMoved - -,CCTouchesMoved对对触摸进行了判断,所以现在这架飞机变成了非常奇异的家伙,你滑动手指,才会向你移动,你不滑动手指,他坚决不动.
很遗憾~苹果在底层做了判断,毕竟,如果手一直按住都响应的话,那设备将及其费电- -,所以我们只能换另外一种方式了~
可以仔细思考一下我们需求的流程,如下:
点击屏幕,则屏幕向该点以一定速度移动。
如果中途发生滑动,则修改该点坐标
如果触摸停止,则此动作停止
所以我们可以采用另外一种方式来实现此功能
ccTouchesBegan用来初始化点坐标,并激活飞机的一个动作,此动作不停得向触摸点移动
ccTouchesMoved用来改变此点的坐标
ccTouchesEnded终结此动作。
我们如果需要实现此功能,则需要以上三个函数协同工作,才能共同达成目标,下一讲将会讲述如何实现此功能。
相关文章推荐
- Cocos2d-x基础示例 精灵移动3
- Cocos2d-x基础示例-精灵移动1
- cocos2d-x学习笔记(三)让精灵按照自己设定的运动轨迹行动(曲线移动)。(以椭圆轨迹为例)。
- cocos2d-x项目101次相遇:使用触摸事件移动 精灵
- 【iphone游戏开发】iphone-Cocos2d游戏开发之四:精灵实现缩放,旋转,跳动,移动等动画
- 游戏基础元素之精灵——Cocos2d-x学习历程(九)
- cocos2d-x 基础--导演,场景,层,精灵
- cocos2d-x学习笔记(三)让精灵按照自己设定的运动轨迹行动(曲线移动)。(以椭圆轨迹为例)。
- Cocos2d-js : 精灵动作实现 示例
- cocos2d-x基础概念介绍——导演、场景、层、精灵
- Cocos2d-x中,如何通过触摸来移动一个精灵
- Cocos2d-x 3.2 Lua示例 ClickAndMoveTest(点击移动测试)
- Cocos2d-x《雷电大战》(2)-精灵随手指移动,你点哪我走哪!
- cocos2d-x精灵自定义路径移动
- 【iphone游戏开发】iphone-Cocos2d游戏开发之四:精灵实现缩放,旋转,跳动,移动等动画
- 关于在cocos2d-x中一个精灵移动到 另外一个地点的实现方法。
- iphone游戏开发之cocos2d ( 八 )使用加速计(重力感应)控制精灵移动UIAcceleration
- cocos2d-x精灵移动的方法
- cocos2d-x项目101次相遇:使用触摸事件移动 精灵
- Cocos2d-x 单点触摸--让精灵随手指移动起来