gpt4 book ai didi

objective-c - 通过 NSTimer 添加 SpriteNode 时,SKScene 未检测到接触

转载 作者:行者123 更新时间:2023-12-03 17:39:06 26 4
gpt4 key购买 nike

概述:我正在从场景顶部添加一个敌人。敌人最初以 150 速度 X 向右移动。 map 有左墙和右墙。当他的左右墙受到敌人攻击时,他应该立即反转方向。

问题:当我从 initWithSize 调用函数 spawnEnemy 时,敌人会按预期行事,在敌人撞到每堵墙时反转方向。当我使用 NSTimer 每 2 秒调用 spawnEnemy 时,SKScene 无法识别敌人与墙壁接触,并且不会反转敌人的方向。下面提供了代码。

生成敌人方法:

-(void)spawnEnemy{

self.testingEnemy = [SKSpriteNode spriteNodeWithImageNamed:@"normalEnemy.png"];

self.testingEnemy.position = (CGPoint) {
CGRectGetMidX(self.scene.frame),
300
};

self.testingEnemy.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.testingEnemy.frame.size];

self.testingEnemy.physicsBody.dynamic = TRUE;

self.testingEnemy.physicsBody.affectedByGravity = TRUE;

self.testingEnemy.physicsBody.mass = 0.00150;

self.testingEnemy.physicsBody.restitution = 0.0;

self.testingEnemy.physicsBody.allowsRotation = FALSE;

self.testingEnemy.physicsBody.linearDamping = 0.0;

[self addChild:self.testingEnemy];
}

initWithSize

-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {

//[self spawnEnemy]; <--- This works with expected behavior

[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(spawnEnemy) userInfo:nil repeats:NO];

}
return self
}

didBeginContact

- (void)didBeginContact:(SKPhysicsContact *)contact
{
if (contact.bodyA == self.testingEnemy.physicsBody && contact.bodyB == [self.map rightWall].physicsBody) {
NSLog(@"Hit right wall");

normalEnemyVelocityX = -normalEnemyVelocityX;

}
}

这是项目文件的链接:

https://www.dropbox.com/s/e59piru3q1hcu0e/Goldrush.zip?dl=0

最佳答案

我的2美分...

  1. 您没有处理 contact.bodyA 是墙壁而 contact.bodyB 是敌人的情况。
  2. 您在哪里设置categoryBitMask和contactTestBitMask?
  3. 您应该考虑使用 SKAction 而不是 NSTimer,因为当您暂停/恢复游戏时,SKAction 会相应地暂停/恢复。

这是一个例子...

SKAction *wait = [SKAction waitForDuration:2.0];
SKAction *spawn = [SKAction performSelector:@selector(spawnEnemy) onTarget:self];
SKAction *waitThenSpawn = [SKAction sequence:@[wait, spawn]];

[self runAction:[SKAction repeatActionForever:waitThenSpawn]];

编辑:尝试以下操作...

1) 代码不会检查接触体是否交换,并且如果场景中有多个敌人,代码将不起作用。以下是解决这些问题的方法:

static inline SKSpriteNode *bodyToNode(SKPhysicsBody *body1,
SKPhysicsBody *body2,
NSString *name) {
SKSpriteNode *node = nil;
if ([body1.node.name isEqualToString:name]) {
node = (SKSpriteNode *)body1.node;
}
else if ([body2.node.name isEqualToString:name]) {
node = (SKSpriteNode *)body2.node;
}
return node;
}

- (void)didBeginContact:(SKPhysicsContact *)contact
{
SKSpriteNode *enemyNode = nil;
SKSpriteNode *wallNode = nil;

enemyNode = bodyToNode (contact.bodyA, contact.bodyB, @"enemy");
wallNode = bodyToNode (contact.bodyA,contact.bodyB, @"wall");

if (enemyNode && wallNode) {
NSLog(@"Hit right wall %@", self.testingEnemy);
normalEnemyVelocityX = -normalEnemyVelocityX;
}
}

2) 将以下内容从 Map.m 移至 Map.h

static const uint32_t playerCategory =  1 << 0;
static const uint32_t platformCategory = 1 << 1;

3) 您没有为敌人设置类别,您需要为敌人命名,以便 didBeginContact 正常工作。将以下内容添加到名为测试的方法中:

self.testingEnemy.physicsBody.categoryBitMask = playerCategory;
self.testingEnemy.name = @"enemy";

4) 在 Map.m 中,在代码中的适当位置添加以下内容:

self.leftWall.name = @"wall";

self.rightWall.name = @"wall";

5)从此语句中删除playerCategory:

self.bottomRightHorizWall.physicsBody.contactTestBitMask = platformCategory;

关于objective-c - 通过 NSTimer 添加 SpriteNode 时,SKScene 未检测到接触,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25458268/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com