hello扳还,一連好幾天的雨橱夭。
《占星起源》星星的創(chuàng)建和游戲檢測(cè)
回顧:
上次把《占星起源》的“線段”弄好了,現(xiàn)在就要開始弄“星星”了俏让。對(duì)了《占星起源》本身有很多關(guān)卡呈础,這里只是開發(fā)其中一個(gè)橱健,可能有人看了之后覺得挺奇怪的,可以說(shuō)這里本身不算是一個(gè)游戲拘荡,在下一期,將會(huì)解釋怎么實(shí)現(xiàn)其他關(guān)卡:
現(xiàn)在開始開發(fā)“星星”:
當(dāng)玩家移動(dòng)線段跟星星有接觸的時(shí)候巨税,星星應(yīng)該有所反應(yīng)粉臊,提示玩家成功連接一顆星星:
效果:(這里沒有其他美術(shù)資源,所以扼仲。。驰后。矗愧。)
現(xiàn)在就來(lái)開發(fā)這個(gè)類:
class?Star :public?Sprite{
public:
?CREATE_FUNC(Star);
?virtual?bool?init();
?void?SMove();//動(dòng)作
?Sprite*ball;//底圖(用來(lái)執(zhí)行動(dòng)畫的東西)
?void?Setop();//動(dòng)作停止
};
實(shí)現(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);//加入到渲染
//下一期這里會(huì)有變動(dòng)
?return?true;
}
void?Star::SMove(){
?auto?ac1=ScaleTo::create(0.5,?3);//動(dòng)作1
?auto?ac2=ScaleTo::create(0.5,?1);//動(dòng)作2
?auto?seq=Sequence::create(ac1,ac2,?NULL);//動(dòng)作組合
?auto?rep=RepeatForever::create(EaseInOut::create(seq,0.5));
//重復(fù)執(zhí)行
?ball->runAction(rep);//執(zhí)行動(dòng)作
}
(這里就是視頻中動(dòng)作的主要代碼了唉韭,是不是很簡(jiǎn)單的說(shuō))
void?Star::Setop(){
?ball->stopAllActions();
//下一期這里會(huì)有變動(dòng)
}
(就這樣就寫好了星星這個(gè)類,往后可能會(huì)增加一些功能)
然后布局你的星星:(這里布局如下:)
布局(創(chuàng)建)星星的時(shí)候钠乏,還要考慮接下來(lái)對(duì)星星的檢測(cè)春塌。所以這里使用一個(gè) vector容器來(lái)存放星星,方便以后遍歷:(這里沒有使用地圖來(lái)布局)
頭文件中:
?Star*p1,*p2,*p3,*p4,*p5,*p6;
?Vector<Sprite*> *pol;
實(shí)現(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);
}
如何檢測(cè)線“線段”是否穿過(guò)星星呢俏拱?
這里得寫一個(gè)比較全面的方法:
這里我推薦幾個(gè)方法(不一定最高效吼句,但足夠可靠):
[1]
A 到 B 線段中有許多點(diǎn)組成,如果該線段經(jīng)過(guò)星星搞隐,必有一點(diǎn)在星星內(nèi)部远搪,檢測(cè)星星內(nèi)部是否包含該點(diǎn)即可。
計(jì)算時(shí)是這樣的:
求出角 A 谁鳍,計(jì)算A 到 B 在 X 劫瞳,Y 軸方向的步進(jìn)绷柒,用 A 的坐標(biāo)不斷 增加即可:
(這里并不是每一個(gè)點(diǎn)又要檢測(cè),不然性能不好)
比如:
?這里的步進(jìn)為紅色箭頭距離
[2]
求出綠色線段距離(星星和一個(gè)轉(zhuǎn)折點(diǎn)的距離)伺绽,求出 角 c(a-b) ,由三角函數(shù)算出s,判斷是否大于星星的半徑郊楣。
等等。钥组。今瀑。。橘荠。
這里采用第2種方法:
首先為了能檢測(cè)全部的星星,所以這里寫一個(gè)函數(shù)方便檢測(cè):
void?GameScene::check(Star*sp){// 星星類型的變量
?auto?d1=sp1->getPosition();//a 點(diǎn)位置
?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í)行星星的動(dòng)作
?log("cccc");
? ? }else{
? ? ? ? sp->Setop();//否則不執(zhí)行
? ? }
}
檢測(cè)的時(shí)候只需要把容器里的星星一個(gè)一個(gè)的取出來(lái)挺份,檢測(cè)即可:
?for(auto?c=pol->begin();c!=pol->end();c++){
?check(*c);
? ? }
這個(gè)函數(shù)還是不夠的贮懈。
還需要對(duì)星星的位置進(jìn)行判斷:
時(shí)間有點(diǎn)晚了,下一次在補(bǔ)全吧各聘。
以下這幾種情況不能正常檢測(cè):
等等抡医。。大脉。水孩。