~~~~我的生活,我的点点滴滴!!
一般在游戏中我们避免不了处理旋转或者子弹发射什么的,就比如塔防游戏来说吧,我们需要判断敌人往哪里走,炮塔就往哪里转,转完
然后朝着一个方向发射子弹,这段话里面我们涉及到了旋转、移动等等cocos2dx里面简单的2D旋转使用RotateTo(或RotateBy),复杂点的
有OrbitCamera(轨迹运行动画),直线移动当然是MoveTo(或MoveBy)了,这里先来讲解RotateTo与MoveTo的组合效果。
MainLayer::MainLayer()
{
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(MainLayer::onTouchBegan, this);
listener->onTouchEnded = CC_CALLBACK_2(MainLayer::onTouchEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
auto sprite = Sprite::create(s_pathGrossini);
auto layer = LayerColor::create(Color4B(255,255,0,255));
addChild(layer, -1);
addChild(sprite, 0, kTagSprite);
sprite->setPosition( Point(20,150) );
//小兔子白又白,蹦蹦跳跳真可爱,JumpTo就是4s内跳到Point(300,48),调试为100,分4次跳完
//这个我前面的blog有讲到。
sprite->runAction( JumpTo::create(4, Point(300,48), 100, 4) );
//这个是制造出背影屏幕一闪一闪的效果。
layer->runAction( RepeatForever::create(
Sequence::create(
FadeIn::create(1),
FadeOut::create(1),
NULL)
));
}
bool MainLayer::onTouchBegan(Touch* touch, Event *event)
{
return true;
}
void MainLayer::onTouchEnded(Touch* touch, Event *event)
{
auto location = touch->getLocation();
auto s = getChildByTag(kTagSprite);
s->stopAllActions();
//鼠标点击结束后,精灵移动到目标点
s->runAction( MoveTo::create(1, Point(location.x, location.y) ) );
float o = location.x - s->getPosition().x;
float a = location.y - s->getPosition().y;
//把弧度转换成角度,里面的实现就是乘以一个常量值这个常量值为360/(2*pi)
float at = (float) CC_RADIANS_TO_DEGREES( atanf( o/a) );
//这样做是为了让人物头的方向始终朝向终点,旋转方向如何定义了?
//下面测试,如果是90度,他是按顺时针方向在旋转,如果是-90度,
//他是按逆时针方向在旋转,一般物体默认方向为了Y轴向上。
if( a < 0 )
{
if( o < 0 )
at = 180 + fabs(at);
else
at = 180 - fabs(at);
}
log("angle: %lf", at);
//1秒内旋转at度,在和上面MoveTo配合起来后,造成了旋转移动的效果
s->runAction( RotateTo::create(1, at) );
}
运行效果图:
//gif
在来看看复杂的OrbitCamera,可以来实现简单的翻卡牌的效果。
//参数分别为:旋转的时间,起始半径,半径差,起始z角,旋转z角差,起始x角,旋转x角差
static OrbitCamera* create(float t, float radius, float deltaRadius, float angleZ, float deltaAngleZ, float angleX, float deltaAngleX);
这参数初看都看不懂,真佩服写这个接口的人,我们简单一个一个参数来试试达到的效果,然后猜测一下其含义:
参数 t:完成时间
参数 radius: 起始半径,只要大于0效果都一样
参数 deltaRadius: 未知
参数 angleZ:起始Z角,就是看你要从哪个角度开始旋转(水平方向的)
参数 deltaAngleZ:旋转Z角差,也就是要让图片旋转几度,360是一圈。
参数 angleX:起始X角,类似于angleZ
参数 deltaAngleX:旋转X角差,就是控制竖直方向的旋转。
粗略如上,参照start530博文。
既然是卡牌肯定有正反两面,正面翻转过去后,反面就显示出来,这样的话我们可以创建两个精灵A和B,A隐藏后B显示出来就OK了,流程如下:
1、创建A和B两个精灵,初始位置要一样,B一开始要隐身。让他俩同时开始旋转, 规定2s为1圈,即360°;
2、当A旋转到90°时,也就是0.5s后要隐身,B显示出来了;
3、B旋转1s,也就是180°后,B隐身,A显示出来了。这样一直转下去。
auto boy = Sprite::create("boy.png");
boy->setPosition(Point(300,300));
this->addChild(boy,2);
auto girl = Sprite::create("girl.png");
girl->setPosition(Point(300,300));
girl->setVisible(false);//一开始设置为不可见
this->addChild(girl,2);
auto seq1 = Sequence::create(DelayTime::create(0.5f),
Hide::create(),//0.5s后隐身,
DelayTime::create(1.0f),
Show::create(),//再过1s后现身
nullptr);
auto rotate1 = OrbitCamera::create(2.0f,1,0,0,360,0,0);
auto seq2 = Sequence::create(DelayTime::create(0.5f),
Show::create(),//0.5s后现身
DelayTime::create(1.0f),
Hide::create(),//再过1s后隐身
nullptr);
auto rotate2 = rotate1->clone();
boy->runAction(RepeatForever::create(Spawn::create(rotate1,seq1,nullptr)));
girl->runAction(RepeatForever::create(Spawn::create(rotate2,seq2,nullptr)));
Show与Hide两个接口,它俩类似我们熟知的FadeIn,FadeOut,让对象隐身或者显示。但Fade需要时间参数,而Show,Hide不用。还是蛮好用的。
后面的会有专门来讲这个效果的例子,今天在这里只是提前打预防针。