我正在进行碰撞检测,希望当Object1向下移动屏幕并最终命中Object2时,它会触发didBeginContact方法,反过来,Object1上的resetPosition会将Object1带回屏幕顶部。我已经使用NSLogs进行测试,以确保程序是否达到了didBeginContact方法,并且确实如此。最重要的是,程序也可以通过调用方法(resetPosition)来工作。唯一的问题是,它不会改变Object1的位置。我试图看看我是否可以在touchesBegan方法中调用方法resetPosition,并且它可以工作。 Object1的位置实际上已重置。你可以在didBeginContact方法中做些什么限制?如果是这样,那么尝试达到预期目标的最佳方法是什么。
以下是我的didBeginContact方法示例:
-(void)didBeginContact: (SKPhyicsContacts *)contact {
SKPhysicsBody *firstBody, *secondBody;
if(contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask){
firstBody = contact.bodyA;
secondBody = contact.bodyB;
} else {
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
if(firstBody.categoryBitMask == Category1 && secondBody.categoryBitMask == Category2){
NSLog(@"Collision Detected!");
[Object1 resetPosition];
}
为了澄清任何混淆,Category1对应于Object1,Category2对应于Object2。
以下是我的Object1类中的resetPosition方法示例:
-(void)resetPosition{
self.position = CGPointMake(0, 200);
NSLog(@"Reached Method!");
}
答案 0 :(得分:0)
你应该看看run loop。物理模拟完成之前没有任何东西被绘制出来。所以我猜你所做的改变位置会被物理模拟所覆盖。
这是运行循环的顺序:
如果你在didSimulatePhysics中移动节点的重新定位而不是在didBeginContact中执行一切都可行,我可以打赌。我想这种情况正在发生,因为你试图在模拟完成之前改变节点的位置。你可以试试这段代码(看看didSimulatePhysics部分):
#import "GameScene.h"
typedef enum uint_8{
ColliderWall = 1,
ColliderPlayer = 2,
ColliderBrick = 4
}CollisionCategory;
@interface Object1 : SKSpriteNode
@end
@implementation Object1
-(instancetype)initWithColor:(UIColor *)color size:(CGSize)size{
if(self = [super initWithColor:color size:size]){
self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:size];
self.physicsBody.categoryBitMask = ColliderPlayer;
self.physicsBody.contactTestBitMask = ColliderBrick;
self.physicsBody.collisionBitMask = ColliderBrick | ColliderWall;
self.physicsBody.dynamic = YES;
self.physicsBody.affectedByGravity = YES;
self.physicsBody.allowsRotation = NO;
}
return self;
}
@end
@interface GameScene ()<SKPhysicsContactDelegate>
@property (nonatomic, strong) Object1 *player;
@property (nonatomic, strong) SKSpriteNode *brick;
@property (nonatomic, assign) BOOL shouldMove;
@end
@implementation GameScene
-(void)didMoveToView:(SKView *)view {
/* Setup your scene here */
_shouldMove = NO;
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
self.physicsBody.contactTestBitMask = 0;
self.physicsBody.collisionBitMask = ColliderPlayer;
self.physicsBody.categoryBitMask = ColliderWall;
self.physicsWorld.contactDelegate = self;
_player = [[Object1 alloc] initWithColor:[SKColor greenColor] size:CGSizeMake(50,30)];
_player.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMaxY(self.frame)- _player.size.height-30);
[self addChild:_player];
_brick = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(330,80)];
_brick.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_brick.size];
_brick.position = CGPointMake(CGRectGetMidX(self.frame),100);
_brick.physicsBody.contactTestBitMask = ColliderPlayer;
_brick.physicsBody.collisionBitMask = ColliderPlayer;
_brick.physicsBody.categoryBitMask = ColliderBrick;
_brick.physicsBody.affectedByGravity = NO;
_brick.physicsBody.dynamic = NO;
[self addChild:_brick];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
for (UITouch *touch in touches) {
[self.player.physicsBody applyImpulse:CGVectorMake(0,55)];
}
}
-(void)didBeginContact:(SKPhysicsContact *)contact{
NSLog(@"Contact");
self.shouldMove = YES;
}
-(void)didSimulatePhysics{
if(self.shouldMove){
self.player.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMaxY(self.frame)- _player.size.height-30);
self.shouldMove = NO;
}
}
@end