1

タイル マップ エディター tmx ファイルからいくつかの動くタイルを作成しようとしています。独自のレイヤーに移動タイルがあり、単純に上に移動し、特定の y に達したら下に移動するなどしたいだけです。

私はこれを達成するための明確な方法を少し探し回っていますが、私の努力はうまくいきませんでした.

ここでいくつかのメソッドを使用してみました。

私はまだ 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;
                }
            }
        }
    }
}

したがって、基本的には、movePlatform 関数が呼び出された回数を追跡するために、int moveCount と BOOL goingDown を作成しました。したがって、100回の呼び出しの後、方向が切り替わります。

(これは私にとってはうまくいきます。これを使用する場合は、衝突検出器のようなものが必要になるかもしれません)。

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

これが将来誰かのために働くことを願っています.これは私にとってかなりの頭痛の種でした.おそらく正しく行われていないか、それを行うためのはるかに良い方法があります.

4

2 に答える 2

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;
于 2013-06-06T14:35:17.697 に答える
1

これは、移動タイルを機能させる方法の(一種の)ステップバイステップです。これは、移動タイルにのみ関連しており、他には何もありません。

注: すべてをスムーズに実行し、キャラクターが地面に落ちないようにするために、これをリリース (デバッグではなく) として実行する必要があります。

インターフェイスで、次の変数を作成しました。

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

CCTMXTiledMap は、私のマップのインスタンスです。BOOL と int は、移動するタイルを追跡するために使用する 2 つの変数です。

-(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;
                }
            }
        }
    }
}

ここで魔法が起こります。私はここから得た方法を使用します。紳士のマウリシオ・トーリンは、タイルの位置を破壊して再作成するのではなく、更新することができると教えてくれました。

したがって、移動プラットフォーム レイヤー内のすべてのタイルを繰り返し処理し、moveCount >= 100 になるまで、呼び出しごとに 1 つ下に移動するように指示します。次に、goingDown が false になり、方向が切り替わります。そこから、100 まで数えて、100 まで数えてから、100 まで数えてから、100 まで数えてから、100 まで数えます。

より長く動かしたい場合は、100 を 200 に増やしてください。(または、チェックを使用して衝突を検出し、指定したスプライトと衝突したときに変更することもできます。それ以上のことが必要な場合は、これを使用してください)。

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

その後、更新メソッドを作成します。

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

init メソッドでは、更新メソッドがフレームごとに呼び出されるようにスケジュールし、更新メソッドは movePlatforms メソッド (またはハザード検出など、頻繁にチェックする必要があるその他の関数) を実行します。

また、movePlatforms に渡される時間を変更することでプラットフォームの移動を遅くすることも、init メソッドでより遅い更新間隔をスケジュールすることもできます。

これが将来誰かに役立つことを願っています。学習中に質問の投稿が本当に整理されておらず、大幅に編集されていたため、これを機能させる方法のより詳細なプロセスでこの回答を作成したかっただけです。

于 2013-06-07T01:21:38.960 に答える