我正在iOS 7上用sprite工具包编写2D球游戏,目前正在努力进行一次物理模拟。
解释预期的行为:如果一个球落入茶杯中,它将绕圈,失去速度,最后静止在杯子的中心。
我试图用重力归档这个,但精灵套件中的重力仅适用于垂直的X和Y轴,而不是Z轴。我还试图通过在beginContact上使用小物理体切换重力值来使用水平重力,具体取决于茶杯中当前的球位置。但有些联系人被删除,结果很远,看起来很现实。
我想我需要在update:方法中解决这个问题,但我不知道要走哪条路。 任何建议都非常欢迎,我需要提一下,我不是数学方面的专家,请解释一下你要走的路。 : - )
答案 0 :(得分:2)
由于在SpriteKit中没有内置支持这种行为,而不是试图破解现有功能以获得你想要的东西,你可能最好在x,y 2D世界中集成一些已发布的2D物理公式。我认为像模拟磁性或归位行为这样的东西可能是正确的。
一个简单的例子就是(在场景的-update:方法中):
CGFloat strength = 0.5; //(some scaling value)
CGPoint ballLocation = ball.position;
CGPoint cupLocation = cup.position;
[ball.physicsBody applyForce:CGVectorMake((cupLocation.x - ballLocation.x) * strength,
(cupLocation.y - ballLocation.y) * strength)];
答案 1 :(得分:0)
遵循Joshd的好主意,我创建了一个NSArray,就像上面的评论中所解释的一样。希望这些片段能帮助其他人......
结果可以在youtube上找到:http://youtu.be/Uephg94UH30 对不起Airplay帧速率不好,它在我的iPad上运行得非常流畅
-update:函数可以完成工作,但只有在_meditationIsActive时才会触发。当任何球与一个洞接触时,这个布尔值设置在 -didBeginContact:中。
if (_lastCheck > 0.005)
{
if (_meditationIsActive)
{
CGFloat strength = 0.1; //(some scaling value)
CGPoint ballLocation;
CGPoint holeLocation;
for (MeditationHole * holeObj in _meditationHoles)
{
if (holeObj.connectedMeditationBall != nil)
{
ballLocation = holeObj.connectedMeditationBall.position;
holeLocation = holeObj.position;
[holeObj.connectedMeditationBall.physicsBody applyForce:CGVectorMake(
(holeLocation.x - ballLocation.x) * strength, (holeLocation.y - ballLocation.y) * strength)];
}
}
_meditationIsActive = [self doesMeditationApplies];
}
_lastCheck = 0;
}
最后,我正在检查阵列中是否有一个有效的球与一个洞接触,以避免在每次更新期间进行检查。这是通过以下功能完成的,其中位置检查+/- 48检测到球靠近一个洞并且+/- 1个球仍然静止
- (bool)doesMeditationApplies
{
bool isInArea = NO;
int perfectMatchCount = 0;
for (MeditationHole * holeObj in _meditationHoles)
{
if (holeObj)
{
if (holeObj.connectedMeditationBall != nil)
{
MeditationBall * ballObj = holeObj.connectedMeditationBall;
if ((ballObj.position.x >= holeObj.position.x - 48) &&
(ballObj.position.x <= holeObj.position.x + 48) &&
(ballObj.position.y >= holeObj.position.y - 48) &&
(ballObj.position.y <= holeObj.position.y + 48))
{
isInArea = YES;
}
else
{
holeObj.connectedMeditationBall = nil;
}
if ((ballObj.position.x >= holeObj.position.x - 1) &&
(ballObj.position.x <= holeObj.position.x + 1) &&
(ballObj.position.y >= holeObj.position.y - 1) &&
(ballObj.position.y <= holeObj.position.y + 1))
{
perfectMatchCount++;
isInArea = YES;
}
}
}
}
if (perfectMatchCount == _oxydStonesMax)
{
if (_sound)
{
self.pauseMusicPlaybackBlock(YES);
NSLog(@"PlaySound Meditation");
[OxydScene PlaySystemSound:@"Win2"];
}
isInArea = NO;
[self showPauseScreenWithWin:YES andPauseOnly:NO];
}
return isInArea;
}