我要實現的功能很簡單,就是點擊螢幕上的任意點,能夠從螢幕中間發射出一顆子彈,子彈要能飛到螢幕外。
我使用了CCMoveTo這個action,它需要一個目的點,目的點應該是我點擊的任一點與螢幕中間點連線上螢幕外的一點。我定義螢幕外20的距離為終點,就是說,子彈將飛到20之外,子彈在這個位置上,是看不到的。
根據直線的函數Y = kX + b,我們需要求出k和b的值,我們知道兩個點,起點(螢幕中間點),直線上的一點(滑鼠按下的那個點),這樣我們就可以求出k和b,這樣就確定了這條直線。然後,我們根據預先設定,只要到螢幕外20就應該停止運動了,這個20是指X座標和Y座標只要有一個到了20就應該馬上停止,要不,就有可能跑到很遠很遠的地方去了。這樣,我就可以用CCMoveTo實現發射子彈效果了。我將它寫成一個函數,在以後的項目中,就能直接使用了,代碼如下:
CCPoint HelloWorld::GetTargetPointOutOfWorld(CCPoint ptStart, CCPoint ptEnd, int nXOutOfWorld, int nYOutOfWorld){ // Y = kX + b float fK = 1.0; float fb = 0.0; if (ptStart.x != ptEnd.x) { fK = (float)(ptStart.y - ptEnd.y) / (ptStart.x - ptEnd.x); // 求出K } fb = ptStart.y - ptStart.x * fK; // 求出b // 求該直線在螢幕外的點 CCSize size = CCDirector::sharedDirector()->getWinSize(); float fY = ptStart.y > ptEnd.y ? -nYOutOfWorld : size.height + nYOutOfWorld; float fX = 1.0; if (fK != 0) { fX = (fY - fb) / fK; // 這個fX可能非常大,或者非常小 } if (ptStart.x == ptEnd.x) // 應該沿Y軸運動 { fX = ptStart.x; fY = ptStart.y > ptEnd.y ? -nXOutOfWorld : size.height + nYOutOfWorld; } else if (ptEnd.y == ptStart.y) // 應該沿X軸運動 { fX = ptStart.x > ptEnd.x ? -nXOutOfWorld : size.width + nXOutOfWorld; fY = ptStart.y; } else if (fX > size.width + nXOutOfWorld) // 重新計算fX和fY { fX = size.width + nXOutOfWorld; fY = fK * fX + fb; } else if (fX < -nXOutOfWorld) // 重新計算fX和fY { fX = -nXOutOfWorld; fY = fK * fX + fb; } return ccp(fX, fY);}
使用是這樣的:
bool HelloWorld::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent){ CCSprite* pSprite = CCSprite::create("bullet.png"); // 載入子彈圖片 CCSize size = CCDirector::sharedDirector()->getWinSize(); this->addChild(pSprite); pSprite->setPosition(ccp(size.width / 2, size.height / 2)); // 設定子彈的發射位置 const int OUT_OF_WORLD = 20; CCPoint ptOutOfWorld = GetTargetPointOutOfWorld(ccp(size.width / 2, size.height / 2), pTouch->getLocation(), OUT_OF_WORLD, OUT_OF_WORLD); // 擷取螢幕外的一個點 CCAction* pAction = CCMoveTo::create(0.5f, ptOutOfWorld); pSprite->runAction(pAction); // 發射子彈 return true;}
要實現螢幕觸摸,你還需要在init函數中註冊一下可觸摸:
this->setTouchEnabled(true); CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, false);
看了一些博文,很多都沒有指出如何打斜線,有的就是打垂直線或者水平線,希望我的這篇能幫到有需要的童鞋~~~~