hello ,当下天气非常炎热。
上一次一直上传视频不成功,现在终于行啦!
这里补充上一次的效果视频。。。
视频
《占星起源》其实还是很好玩的,现在就来开发一个,虽然比较简单,你们也可以。其实也不能说是完全一样的,但机制什么的是一样的。
这里是一小时开发《占星起源》的上部分,这里要做的就是开发出“星座”的连线。
效果视频如下:
《占星起源》游戏截图:
这里需要联系到上一篇的makeline,因为下图效果,需要参照里面的运算。
如上图3个蓝色圆形,分别是可移动的,移动的同时影响连接他们之间的线段的长度和角度(请联系上一篇《实现《占星起源的》的MadeLine》里面有详细的解释哦);
布局:
// 生成ABC 3点:
sp1=Sprite::create("cg.png");
sp2=Sprite::create("cg.png");
sp3=Sprite::create("cg.png");
//分别设置他们的位置:
sp1->setPosition(Point(100,200));
sp2->setPosition(Point(500,400));
sp3->setPosition(Point(200,60));
//加入到渲染:
this->addChild(sp1,3);
this->addChild(sp2,3);
this->addChild(sp3,3);
//线段1
line1=Sprite::create("bar.png");
line2=Sprite::create("bar.png");
//设置锚点
line1->setAnchorPoint(Point(0,0.5));
line2->setAnchorPoint(Point(0,0.5));
//位置
line2->setPosition(sp2->getPosition());
line1->setPosition(sp1->getPosition());
这里先忽略“星星”,(黄色圆)
首先,先解决连接两点的线段问题,把这个工作分成两部分
[1], 计算出点点的距离。
[2],计算出点与点的夹角。
因为这里的的原理是通过一个10*10像素的小图,通过拉伸,旋转,模拟出连接两点的线段。
(1).如图A ,B ; B ,C:
A B 两点已经决定了AB线段的长度len;
那么通过获取A B 点的坐标 ,来计算出len。
同样的,获取到 BC的长度。
(2),计算A B ,B C 的角度:
AB间的线段和角度:
auto dis1=sp1->getPosition();// 获取A坐标
auto dis2=sp2->getPosition();//B坐标
auto v=dis2-dis1;
float len=v.length();// 距离
float sclax=len/(line1->getContentSize().width); //放大倍数
line1->setScaleX(sclax);
float rad=v.getAngle();
float rot=CC_RADIANS_TO_DEGREES(-rad);//旋转角度
line1->setRotation(rot);
BC间的线段和角度:
auto Dis1=sp2->getPosition();
auto Dis2=sp3->getPosition();
auto V=Dis2-Dis1;
float Len=V.length();
float Sclax=len/(line2->getContentSize().width);
line2->setScaleX(Sclax);
float Rad=V.getAngle();
float Rot=CC_RADIANS_TO_DEGREES(-Rad);
line2->setRotation(Rot);
计算好之后,接下来就要对手指的触摸点进行判断了。
首先,需要判断手指滑动的是处于A B C 的哪个。
(绑定事件在《实现《占星起源的》的MadeLine》里有哦),这里就不说明了。
在A点:
if(sp1->boundingBox().containsPoint(c)){
//把A 点 当成盒子,判断触摸点是否在其内部:
sp1->setPosition(c);
line1->setAnchorPoint(Point(1,0.5));
line1->setPosition(sp2->getPosition());
}
移动A时(红色为移动,黄色为线段缩放位置):
这里需要注意的是:
因为前面说到线段的模拟是通过10*10像素的图片来模拟的,在拉动不同点的时候,方大的方向是不一样的,更改放大的方向就要更改他的锚点,因为坐标也是根据锚点来决定的,所以同时也需要更改到相应的坐标去。
比如(红色为锚点位置,黄色为放大方向):
比如:
等等。。。。
否则就会出现下面的效果:
or :
在B点:
这里需要改变两条线段的锚点和坐标:
if(sp2->boundingBox().containsPoint(c)){
sp2->setPosition(c);
line1->setAnchorPoint(Point(0,0.5));
line1->setPosition(Point(sp1->getPosition()));
line2->setAnchorPoint(Point(1,0.5));
line2->setPosition(Point(sp3->getPosition()));
}
移动B时:
在C点:
if(sp3->boundingBox().containsPoint(c)){
sp3->setPosition(c);
line2->setAnchorPoint(Point(0,0.5));
line2->setPosition(Point(sp2->getPosition()));
}
这样判断好了之后就需要不断的检测,需要在游戏的每一帧都要进行检测。
这里检测的就是A B C 的位置了:
void GameScene::update(float dt){
//A B 的检测,时刻保持A B 两点的自然连接(方法同上面类似):
auto dis1=sp1->getPosition();
auto dis2=sp2->getPosition();
auto v=dis2-dis1;
float len=v.length();
float sclax=len/(line1->getContentSize().width);
line1->setScaleX(sclax);
float rad=v.getAngle();
float rot=CC_RADIANS_TO_DEGREES(-rad);
line1->setRotation(rot);
angle1=rot;
//B C 的检测 ,时刻保持 B C 两点的自然连接:
auto Dis1=sp2->getPosition();
auto Dis2=sp3->getPosition();
auto V=Dis2-Dis1;
float Len=V.length();
float Sclax=Len/(line2->getContentSize().width);
line2->setScaleX(Sclax);
float Rad=V.getAngle();
float Rot=CC_RADIANS_TO_DEGREES(-Rad);
line2->setRotation(Rot);
}
好了~~
代码下次再发出来。。。。