我要实现的功能很简单,就是点击屏幕上的任意点,能够从屏幕中间发射出一颗子弹,子弹要能飞到屏幕外。
我使用了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);
看了一些博文,很多都没有指出如何打斜线,有的就是打垂直线或者水平线,希望我的这篇能帮到有需要的童鞋~~~~