移动平台? Cocos2d和Tiled

时间:2013-06-04 20:08:10

标签: ios xcode cocos2d-iphone tmx

我正在尝试从Tiled地图编辑器tmx文件制作一些移动的图块。 我在他们自己的层中有移动的瓷砖,我只是想让它们向上移动,然后当它们达到某个y时,向下移动等等。

我一直在寻找一个明确的方法来完成这个,但我的努力没有成功。

我尝试使用一些方法here

我对cocos2d开发一般都是新手,所以我对此有所了解。非常感谢您的宝贵时间。如果您有任何问题,请询问! :) 此外,如果它有帮助,我试图移动的瓷砖是大T形。

最终更新:

(删除了更多不相关的代码,以便将来任何人都可以轻松找到我的解决方案(完整的答案如下),你可以在上面的链接中找到我的图层迭代方法。)

好的,所以我终于让它接近我想要的......我不认为这是最理想的做法,但这就是我所拥有的。

注意:为了让它适合你,你必须让你的应用程序退出调试模式,否则它会滞后/让玩家掉到地上(至少它对我来说......)。

我有一个更新功能,每帧调用某些功能。 (检查碰撞,移动平台等)。

该更新函数调用我的移动平台函数..

像这样:

[self movePlatforms:0.1];

这是我的movePlatforms函数..

-(void)movePlatforms: (ccTime) dt{
    if(goingDown){
        moveCount++;
    }else{
        moveCount--;
    }
    CGSize s = [movingTiles layerSize];
    for( int x=0; x<s.width;x++) {
        for( int y=0; y< s.height; y++ ) {
            CCSprite *tile = [movingTiles tileAt:ccp(x,y)];
            if(goingDown){
                CGPoint newPosition = ccp(tile.position.x, tile.position.y - 1);
                tile.position = newPosition;
                if(moveCount >= 100){
                     goingDown = false;
                }
            }else{
                 CGPoint newPosition = ccp(tile.position.x, tile.position.y + 1);
                tile.position = newPosition;
                if(moveCount <= 0){
                    goingDown = true;
                }
            }
        }
    }
}

基本上,我创建了一个int moveCount和一个BOOL goDown来跟踪我的movePlatform函数被调用了多少次。所以100次通话后,它会切换方向。

(这对我来说很好,你可能还需要像碰撞检测器这样的其他东西,如果是这样的话就使用它。)

if (CGRectIntersectsRect([someSprite boundingBox], [someSprite boundingBox])) {
    //Do something
}

希望这对未来的某个人有用,我知道这对我来说非常头疼,它可能甚至没有正确完成或有更好的方法来做到这一点,但如果这有助于你,那就是真棒!

2 个答案:

答案 0 :(得分:2)

创建和删除切片会影响您的性能。 而不是它,尝试移动瓷砖改变他们的位置:

CCSprite *tile = [movingTiles tileAt:ccp(92,platformY)];
[movingTiles removeTileAt:ccp(92,platformY)];
CGPoint newTilePosition = tile.position;
if (goingDown){
    newTilePosition.y ++;
    if(newTilePosition.y >= 20){
        goingDown = false;
    }
}else{
    newTilePosition.y --;
    if(newTilePosition.y <= 10){
        goingDown = true;
    }
}
tile.position = newTilePosition;

答案 1 :(得分:1)

这是我的移动瓷砖如何工作的一步一步的步骤,这只与移动的瓷砖有关,而不是别的。

注意:你需要将它作为一个版本(而不是调试版)来运行,以便让所有内容顺利运行,而不是让你的角色掉在地上。

在界面中我创建了这些变量:

@interface HelloWorldLayer(){
    CCTMXTiledMap *map;
    BOOL goingDown;
    int moveCount;
}

CCTMXTiledMap是我的地图的实例。 BOOL和int是我用来跟踪移动磁贴的两个变量。

-(id) init {
    if( (self=[super init]) ) {
         // add our map
         map = [[CCTMXTiledMap alloc] initWithTMXFile:@"level1-1.tmx"];
         map.position = ccp(0,0);
         [self addChild:map];

         //add our moving platforms layer
         movingTiles = [map layerNamed:@"moving_platforms"];

         //set the variables I use to keep track of the moving platforms
         goingDown = true;
         moveCount = 0;

         //schedule my update method
         [self schedule:@selector(update:)];
    }
    return self;
}

在init方法之后,我创建了我的移动平台方法:

-(void)movePlatforms: (ccTime) dt{
    if(goingDown){
        moveCount++;
    }else{
        moveCount--;
    }
    CGSize s = [movingTiles layerSize];
    for( int x=0; x<s.width;x++) {
        for( int y=0; y< s.height; y++ ) {
            CCSprite *tile = [movingTiles tileAt:ccp(x,y)];
            if(goingDown){
                CGPoint newPosition = ccp(tile.position.x, tile.position.y - 1);
                tile.position = newPosition;
                if(moveCount >= 100){
                    goingDown = false;
                }
            }else{
                CGPoint newPosition = ccp(tile.position.x, tile.position.y + 1);
                tile.position = newPosition;
                if(moveCount <= 0){
                    goingDown = true;
                }
            }
        }
    }
}

所以这就是魔术发生的地方,我使用了here得到的方法,而绅士Mauricio Tollin告诉我,我可以更新一个瓦片位置,而不是销毁并重新创建它们。

因此,我遍历移动平台层中的每个磁贴,并告诉他们每次调用时都会关闭1,直到moveCount&gt; = 100,然后它说goDown现在为false,并且它会切换方向。从那里它来回,数到100,然后再回来。

如果你想让它移动更长时间,只需增加100到200或任何你想要的。 (或者您可以使用检查来检测碰撞,当它与指定的精灵发生碰撞时,您可以将其更改。如果这更符合您的要求,请使用此方法。)

if (CGRectIntersectsRect([someSprite boundingBox], [someSprite boundingBox])) {
    //Do something
}

毕竟,我创建了更新方法:

-(void)update:(ccTime)dt{
    [self movePlatforms:0.1];
}

在init方法中,它调度每帧调用的update方法,然后update方法将运行movePlatforms方法(或需要经常检查的任何其他函数,例如危险检测等)。

您还可以通过更改传递给movePlatforms的时间来使平台移动得更慢,或者您可以在init方法中安排更慢的更新间隔。

我希望将来可以帮助某人,我只是想通过更深入的过程来创建这个答案,因为我的问题帖子在我学习的时候真的没有组织和大量编辑。