hello,一連好幾天的雨。
《占星起源》星星的創(chuàng)建和游戲檢測
回顧:
上次把《占星起源》的“線段”弄好了,現(xiàn)在就要開始弄“星星”了。對了《占星起源》本身有很多關(guān)卡,這里只是開發(fā)其中一個,可能有人看了之后覺得挺奇怪的,可以說這里本身不算是一個游戲,在下一期,將會解釋怎么實現(xiàn)其他關(guān)卡:
現(xiàn)在開始開發(fā)“星星”:
當(dāng)玩家移動線段跟星星有接觸的時候,星星應(yīng)該有所反應(yīng),提示玩家成功連接一顆星星:
效果:(這里沒有其他美術(shù)資源,所以。。。。)
現(xiàn)在就來開發(fā)這個類:
class?Star :public?Sprite{
public:
?CREATE_FUNC(Star);
?virtual?bool?init();
?void?SMove();//動作
?Sprite*ball;//底圖(用來執(zhí)行動畫的東西)
?void?Setop();//動作停止
};
實現(xiàn):
bool?Star::init(){
?this->initWithFile("ch.png");//初始化紋理
?this->setScale(0.5);//縮放
?ball=Sprite::create("io.png");
?ball->setPosition(this->getContentSize().width/2,this->getContentSize().height/2);
?this->addChild(ball,-1);//加入到渲染
//下一期這里會有變動
?return?true;
}
void?Star::SMove(){
?auto?ac1=ScaleTo::create(0.5,?3);//動作1
?auto?ac2=ScaleTo::create(0.5,?1);//動作2
?auto?seq=Sequence::create(ac1,ac2,?NULL);//動作組合
?auto?rep=RepeatForever::create(EaseInOut::create(seq,0.5));
//重復(fù)執(zhí)行
?ball->runAction(rep);//執(zhí)行動作
}
(這里就是視頻中動作的主要代碼了,是不是很簡單的說)
void?Star::Setop(){
?ball->stopAllActions();
//下一期這里會有變動
}
(就這樣就寫好了星星這個類,往后可能會增加一些功能)
然后布局你的星星:(這里布局如下:)
布局(創(chuàng)建)星星的時候,還要考慮接下來對星星的檢測。所以這里使用一個 vector容器來存放星星,方便以后遍歷:(這里沒有使用地圖來布局)
頭文件中:
?Star*p1,*p2,*p3,*p4,*p5,*p6;
?Vector<Sprite*> *pol;
實現(xiàn)文件中:
pol=new?Vector<Sprite*>(0);// 初始化容器
void?GameScene::CreateP(){
?p1=Star::create();
?p2=Star::create();
?p3=Star::create();
?p4=Star::create();
?p5=Star::create();
?p1->setPosition(Point(117,388));
?p2->setPosition(Point(181,288));
?p3->setPosition(Point(241,183));
?p4->setPosition(Point(367,200));
?p5->setPosition(Point(600,302));
?this->addChild(p1);
?this->addChild(p2);
?this->addChild(p3);
?this->addChild(p4);
?this->addChild(p5);
?pol->pushBack(p1);//把創(chuàng)建好的星星加入到容器里
?pol->pushBack(p2);
?pol->pushBack(p3);
?pol->pushBack(p4);
?pol->pushBack(p5);
}
如何檢測線“線段”是否穿過星星呢?
這里得寫一個比較全面的方法:
這里我推薦幾個方法(不一定最高效,但足夠可靠):
[1]
A 到 B 線段中有許多點組成,如果該線段經(jīng)過星星,必有一點在星星內(nèi)部,檢測星星內(nèi)部是否包含該點即可。
計算時是這樣的:
求出角 A ,計算A 到 B 在 X ,Y 軸方向的步進(jìn),用 A 的坐標(biāo)不斷 增加即可:
(這里并不是每一個點又要檢測,不然性能不好)
比如:
?這里的步進(jìn)為紅色箭頭距離
[2]
求出綠色線段距離(星星和一個轉(zhuǎn)折點的距離),求出 角 c(a-b) ,由三角函數(shù)算出s,判斷是否大于星星的半徑。
等等。。。。。
這里采用第2種方法:
首先為了能檢測全部的星星,所以這里寫一個函數(shù)方便檢測:
void?GameScene::check(Star*sp){// 星星類型的變量
?auto?d1=sp1->getPosition();//a 點位置
?auto?d2=sp2->getPosition();// b?
?auto?len=d1-d2;
?auto?rod=len.getAngle();//a b 距離
?auto?ang=CC_RADIANS_TO_DEGREES(-rod);
?//log("%f",ang);
?if(ang>90){
? ? ? ? ang=180-ang;//保持在 0-90度之間
? ? }
?auto?d3=sp->getPosition();//星星位置
?auto?Len=d3-d2;
?auto?Rod=Len.getAngle();
?auto?Ang=CC_RADIANS_TO_DEGREES(-Rod);
?//? log("%f",Ang);
?if(Ang>90){
? ? ? ? Ang=180-Ang;
? ? }
?auto?nexangle=fabsf(Ang-ang);/得到角c
?log("%f",nexangle);
?if(Len.getLength()*sin(CC_DEGREES_TO_RADIANS(nexangle))<=sp->getContentSize().width/2){
//判斷是否大于星星半徑
? ? ? ? sp->SMove();//執(zhí)行星星的動作
?log("cccc");
? ? }else{
? ? ? ? sp->Setop();//否則不執(zhí)行
? ? }
}
檢測的時候只需要把容器里的星星一個一個的取出來,檢測即可:
?for(auto?c=pol->begin();c!=pol->end();c++){
?check(*c);
? ? }
這個函數(shù)還是不夠的。
還需要對星星的位置進(jìn)行判斷:
時間有點晚了,下一次在補(bǔ)全吧。
以下這幾種情況不能正常檢測:
等等。。。。