cocos2dx 缩放场景以后的碰撞检测跟触摸

本文探讨了在cocos2dx中,当场景经过缩放后,如何正确进行精灵之间的碰撞检测和触摸处理。通过在不同层添加精灵并调整坐标系统,以解决缩放场景导致的碰撞检测问题。详细讲解了关键代码和坐标转化的过程,以帮助开发者理解缩放场景下的碰撞检测实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家看了这题目之后或许可能会淡然一笑,心想:这会有什么问题吗?正常情况下,两个精灵放在同一个层,这样子是没有问题的,但是你有没有试过两个精灵在不同层的碰撞检测?如果你尝试过,就知道这篇文章为什么会诞生了……

我有一个HelloWorld,这个是主场景,我在主场景中添加了一个游戏层,GameLayer的实例,添加了一个碰撞精灵,Pig的实例。在这里多说一句,我的适配使用了:CCEGLView::sharedOpenGLView()->setDesignResolutionSize(1280, 720, kResolutionNoBorder);

Pig添加:【其中的一个需要进行碰撞检测的精灵】,方法如下:

?
1
2
3
4
5
6
void HelloWorld::addPig()
{
Pig *pig = Pig::getInstance();
pig->setPosition(ccp(300,200));
this ->addChild(pig);
}

GameLayer添加:【游戏层】,方法如下:

?
1
2
3
4
// init gamelayer
m_pGameLayer = GameLayer::create();
m_pGameLayer->setPosition(ccp(500,0));
addChild(m_pGameLayer);

这两个操作之后,我们就把游戏层和游戏精灵加载到场景中了,接下来处理下主场景:

?
1
2
setAnchorPoint(CCPointZero);
this ->ignoreAnchorPointForPosition( false );

这些准备就绪后,我们再到游戏层GameLayer中添加地面,Ground的实例。

Ground添加,【另外一个需要进行碰撞检测的精灵】,添加方法如下:

?
1
2
3
4
5
6
7
void GameLayer::addGround()
{
Ground *ground = Ground::create( "Icon-72.png" );
ground->setPosition(ccp(200,200));
ground->setGameLayer( this );
this ->addChild(ground);
}

这样之后,我们的Ground实例精灵和Pig实例精灵就分别位于两个层上了,Ground:添加到了GameLayer层,Pig:添加到了HelloWorld层。

我们在Ground实例中进行碰撞检测,区域判断如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
CCRect Ground::atlasRect()
{
CCSize cSize = getContentSize();
CCPoint pos = this ->getPosition();
return CCRectMake(pos.x - cSize.width/2, pos.y - cSize.height/2, cSize.width, cSize.height);
}
 
bool Ground::isContaintRect(CCRect rect)
{
return atlasRect().intersectsRect(rect);
}
 
CCRect Ground::getPigRect()
{
Pig *pigTemp = Pig::getInstance();
 
CCPoint pos = pigTemp->getPosition();
pos = ccp(pos.x*pigTemp->getGlobalScale(),pos.y*pigTemp->getGlobalScale());
pos = _m_pGameLayer->convertToNodeSpace(pos);
 
CCSize cSize = pigTemp->getContentSize();
float width = cSize.width;
float height = cSize.height;
 
return CCRectMake(pos.x - width/2, pos.y - height/2, width, height);
}

在这段代码中,

?
1
2
pos = ccp(pos.x*pigTemp->getGlobalScale(),pos.y*pigTemp->getGlobalScale());
pos = _m_pGameLayer->convertToNodeSpace(pos);

这两句是比较重要的,第一句处理了缩放后坐标的转化,第二句统一了两个精灵的坐标系,将两个精灵的坐标转化为相对于游戏层的坐标。

关于pigTemp->getGlobalScale(),这个是为了大家测试方便,代码方便,我把场景的缩放值绑定到了Pig的实例上。。。

在这里,大家可能还不明白为什么我使用了convertToNodeSpace进行坐标转化之后还要处理一下Pig实例的坐标。

下面大家跟我一步步看看源码:

convertToNodeSpace方法:

?
1
2
3
4
5
CCPoint CCNode::convertToNodeSpace( const CCPoint& worldPoint)
{
CCPoint ret = CCPointApplyAffineTransform(worldPoint, worldToNodeTransform());
return ret;
}

这里边主要是CCPointApplyAffineTransform,点的映射转化,它是一个宏定义:#define CCPointApplyAffineTransform __CCPointApplyAffineTransform

__CCPointApplyAffineTransform如下:

?
1
2
3
4
5
6
7
CCPoint __CCPointApplyAffineTransform( const CCPoint& point, const CCAffineTransform& t)
{
CCPoint p;
p.x = ( float )(( double )t.a * point.x + ( double )t.c * point.y + t.tx);
p.y = ( float )(( double )t.b * point.x + ( double )t.d * point.y + t.ty);
return p;
}

在这里边它进行了坐标的处理,但是没有涉及到场景的缩放值,所以,到这里你应该明白了。。。

希望这个对大家有帮助。。。

欢迎大神拍砖,多多指教……

之前很多朋友说文章不详细啊,没有例子啊,希望大家多多提意见,之后文章尽量详细,贴图。例子都挂在我的github下面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值