【问题标题】:How to continuously check collisions in Tiled tilemaps during a CCMoveTo如何在 CCMoveTo 期间连续检查 Tiled tilemap 中的碰撞
【发布时间】:2013-04-25 10:34:53
【问题描述】:

你好堆栈溢出的好人 我今天站在你面前的一个(不是很好的)cocos2d 问题。

如何在动作中检查碰撞而不是检查目标图块? 我正在使用具有元图层的瓷砖地图,其中有可碰撞的瓷砖。以下代码在我单击可碰撞图块时有效,但当我单击超出它时无效,如果发生这种情况,他将直接穿过。

目前,我检测到与此代码的冲突:

-(void)setPlayerPosition:(CGPoint)position {
CGPoint tileCoord = [self tileCoordForPosition:position];
int tileGid = [_meta tileGIDAt:tileCoord];
if (tileGid) {
    NSDictionary *properties = [_tileMap propertiesForGID:tileGid];
    if (properties) {
        NSString *collision = properties[@"Collidable"];
        if (collision && [collision isEqualToString:@"True"]) {
            return;
        }
    }
}

float speed = 10;
CGPoint currentPlayerPos = _player.position;
CGPoint newPlayerPos = position;
double PlayerPosDifference = ccpDistance(currentPlayerPos, newPlayerPos) / 24;
int timeToMoveToNewPostition = PlayerPosDifference / speed;
id moveTo = [CCMoveTo actionWithDuration:timeToMoveToNewPostition position:position];
[_player runAction:moveTo];

//_player.position = position;
}

顺便说一句,这是从这个方法调用的:

-(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
[_player stopAllActions];
CGPoint touchLocation = [touch locationInView:touch.view];

touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];
touchLocation = [self convertToNodeSpace:touchLocation];

CGPoint playerPos = _player.position;
CGPoint diff = ccpSub(touchLocation, playerPos);

int diffx = diff.x;
int diffy = diff.y;
int adiffx = diffx / 24;
int adiffy = diffy / 24; //Porque my tile size is 24     

if ( abs(diff.x) > abs(diff.y) ) {
    if (diff.x > 0) {
        playerPos.x = playerPos.x + adiffx * 24;
    } else {
        playerPos.x = playerPos.x + adiffx * 24;
    }
} else {
    if (diff.y > 0) {
        playerPos.y = playerPos.y + adiffy * 24;
    }else{
        playerPos.y = playerPos.y + adiffy * 24;
    }
}
[self setPlayerPosition:playerPos];
}

我试过了

    [self schedule:@selector(setPlayerPosition:) interval:0.5];

没有任何运气,这只是立即使应用程序崩溃

NSAssert( pos.x < _layerSize.width && pos.y < _layerSize.height && pos.x >=0 && pos.y >=0, @"TMXLayer: invalid position"); 我真的不能责怪它在那里崩溃。

如何在CCMoveTo 运行时不断检查与可碰撞元图块的碰撞?

【问题讨论】:

  • 您只检查触摸位置的磁贴。您是否维护所有瓷砖的阵列?如果是这样,那么您可以安排一个“碰撞检测器”方法来主动检查玩家和所有图块之间的任何碰撞。
  • 不,我不知道,因为我不知道怎么做 :D 你能启发我吗,太棒了@SmugbitStudios

标签: ios objective-c xcode cocos2d-iphone


【解决方案1】:

在您的 init 中,安排一个碰撞检测方法:

[self schedule:@selector(checkCollisions:)];

然后定义如下:

-(void)checkCollisions:(ccTime)dt
{
    CGPoint currentPlayerPos = _player.position;
    CGPoint tileCoord = [self tileCoordForPosition:currentPlayerPos];
    int tileGid = [_meta tileGIDAt:tileCoord];
    if (tileGid) 
    {
        NSDictionary *properties = [_tileMap propertiesForGID:tileGid];
        if (properties) 
        {
            NSString *collision = properties[@"Collidable"];
            if (collision && [collision isEqualToString:@"True"]) 
            {
                [_player stopAllActions];
                return;
            }
        }
    }
}

【讨论】:

  • 太好了,谢谢!这(有点)有效!除了,当他撞到瓷砖时,他会卡在瓷砖里……就像中途一样。有什么方法可以让他在遇到障碍时无法行走?
  • 这样做只会在精灵进入墙内时停止。
  • 你应该在移动之前检查碰撞,如果移动会让你进入墙内,请停止移动。
  • 玩家位置是相对于锚点的。默认情况下,它是 ccp(0.5f, 0.5f),它位于玩家精灵的中间。您可以跟踪玩家的方向(上、下、左、右),并相应地修改 currentPlayerPos(向上需要增加一半的玩家高度,向下需要减去它,向左需要减去一半的玩家高度宽度,右边需要添加它)。
  • 考虑到 CCMoveTo 的使用,我认为这个想法是将玩家移动到触摸位置,如果有任何障碍物挡住了它,它会移动到最近的瓷砖然后停止。如果您还想沿对角线移动,只需再增加 4 个方向(NE、SE、NW、SW),也可以修改选中的瓷砖位置。我也认为它可以很好地处理 1 个像素的边界,但鉴于其他代码建议整个图块移动,最小值为 24 像素,即单个图块的宽度。
【解决方案2】:

我使用了类似的元层。我个人跳过了使用 MoveTo,并创建了自己的更新代码,既可以移动精灵又可以进行碰撞检测。

我找出潜在的新位置是什么,然后我找出新位置的精灵的所有四个角中的瓷砖位置,然后我循环浏览精灵将在的所有瓷砖,如果有的话可碰撞,我停止精灵。

我实际上更进一步,检查是只移动 x 还是只移动 y 会改变结果,如果是,则移动到那个位置。

【讨论】:

  • 这看起来很聪明,但我还没有真正达到实现我自己的 CCMoveTo 方法的水平。你能提供一个例子/更深入地解释一下如何开始吗?
  • 我保持简单,但使用一个复杂的数学方程。我没有说移动到 foo 位置,而是说向 foo 方向移动,速度为 bar。然后我根据方向和速度使用数学计算下一帧的位置。一旦我知道新职位是什么,我就可以检查上面提到的内容。另外,为了限制这种移动,我说以 bar 的速度向 foo 方向移动,持续时间为 baz。然后,我会跟踪总经过的时间,并在设定的持续时间结束后停止移动。
  • 看起来很聪明。您有兴趣发布您的代码吗?请:D
猜你喜欢
  • 1970-01-01
  • 2022-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-28
  • 2018-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多