我目前正在使用Objective-C和SpriteKit与朋友一起工作。我和我的朋友都是SpriteKit的新手,所以我们正在研究的这个项目更多的只是一种学习体验。但是,当然,我们遇到了一些麻烦。同一类型的多个对象上的SpriteKit碰撞检测
游戏相当简单:有一个球飞过屏幕并从“墙壁”或iPhone屏幕边缘弹开。用户控制屏幕底部的桨,使球返回,防止球触及屏幕底部。每次击球时,屏幕顶部的得分计数器都会增加1。
这是我们正在努力完成的。当比赛的比分等于5时,我们为场景添加一个新球。新球开始自行移动,但每当我们尝试检测新球是否碰到屏幕边缘时,碰撞就不会被检测到。
这里是我们的方法,该方法返回一个球对象:
+(id)ball
{
// the ball is a random image from google
Ball *ball = [Ball spriteNodeWithImageNamed:@"ball"];
// set the position of the ball
ball.position = CGPointMake(0, 80);
// set ball name property
ball.name = @"ball";
// give the ball a physics body
ball.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:ball.size];
ball.physicsBody.affectedByGravity = NO;
return ball;
}
这种方法被称为移动球的场景:
-(void)move:(int)deltaX withDeltaY:(int)deltaY
{
SKAction *testMoveRight = [SKAction moveByX:deltaX y:deltaY duration:0.03];
// this will repeat the action over and over
SKAction *move = [SKAction repeatActionForever:testMoveRight];
[self runAction:move];
}
这些是我们的碰撞检测类:
// this category is for the original ball in the game
static const uint32_t ballCategory = 0x1 << 0;
// this category is for the second ball that gets added to the game
static const uint32_t ball2Category = 0x1 << 1;
static const uint32_t paddleCategory = 0x1 << 2;
static const uint32_t topBarrierCategory = 0x1 << 3;
static const uint32_t leftBarrierCategory = 0x1 << 4;
static const uint32_t rightBarrierCategory = 0x1 << 5;
static const uint32_t gameOverBarrierCategory = 0x1 << 6;
这里是我们的didBeginContact方法:
-(void)didBeginContact:(SKPhysicsContact *)contact
{
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) {
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
else {
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
// first ball contact
if ((firstBody.categoryBitMask & ballCategory) != 0 && (secondBody.categoryBitMask & rightBarrierCategory) != 0) {
[ball move:-15 withDeltaY:0];
}
else if ((firstBody.categoryBitMask & ballCategory) != 0 && (secondBody.categoryBitMask & topBarrierCategory) != 0) {
[ball move:0 withDeltaY:-20];
}
else if ((firstBody.categoryBitMask & ballCategory) != 0 && (secondBody.categoryBitMask & leftBarrierCategory) != 0) {
[ball move:15 withDeltaY:0];
}
else if ((firstBody.categoryBitMask & ballCategory) != 0 && (secondBody.categoryBitMask & paddleCategory) != 0) {
[ball move:0 withDeltaY:20];
// increment score
self.score++;
// update the score label
self.deathLabel.text = [NSString stringWithFormat:@"%i", self.score];
// add a new ball to the scene if the score is 5
if (score == 5) {
[scene addChild:ball2];
[ball2 move:5 withDeltaY:10];
}
}
// second ball contact detection
if ((firstBody.categoryBitMask & ball2Category) != 0 && (secondBody.categoryBitMask & rightBarrierCategory) != 0) {
[ball2 move:-15 withDeltaY:0];
}
}
为什么我们添加到场景中的第二个球没有检测到它与正确的屏障(屏幕右边缘)相撞?当它到达屏幕的右边缘时,它不会反弹并像我们想要的那样向左移动。有什么建议么?
感谢您的澄清。你有没有想过我是否可以让球的物理体在从障碍物弹回时不会失去“速度”,并让它向相反的方向移动?正如你上面所建议的那样,我已经设定了球的类别边界掩蔽和碰撞边界掩蔽,但是最终在两个障碍反弹之后球失去了速度。有什么建议么?我仍然对我应该如何使用didBeginContact方法感到困惑。 – Surfero 2014-10-27 01:41:15
didBeginContact用于当两个对象彼此接触时(对象不会互相反弹,didBeginContact将被调用,但对象将继续移动/执行它们的操作)时要调用的方法。对于球不断弹跳,将其恢复到1.0f: 'ball.physicsBody.restitution = 1.0f' 恢复原状是'弹性'的值,其中1.0f表示弹跳时不会失速,0.0f表示只要碰撞它停止(0反弹)。如果这回答你的问题,我将不胜感激,如果你标记我的答案是正确的。谢谢! – Andriko13 2014-10-27 02:03:28
至于朝相反的方向移动,您可能需要明确指出您的意思。 – Andriko13 2014-10-27 02:04:08