Question

I'm trying to make some moving tiles from a Tiled map editor tmx file. I have the moving tiles in their own layer, and I just want to simply have them move up, and then when they reach a certain y, move back down, and etc.

I have been looking around for a bit on a clear way of accomplishing this, but my efforts have been unsuccessful.

I tried using some of the methods here.

I'm still really new to cocos2d development in general, so I wold appreciate any insight on this. Thank you very much for your time. If you have any questions, please ask! :) Also if it helps, the tiles I'm trying to move are in a big T shape.

FINAL UPDATE:

(Removed more irrelevant code so anyone in the future can easily find my solution (the full answer is below), you can find where I got my layer iterate method at the link above).

Okay, so I have finally got it working close to how I want.. I don't think this is exactly the most ideal way of doing it, but this is what I've got.

Note: In order for this to work for you, you have to run your app out of debug mode or it will lag/make the player fall through the ground (at least it did for me..).

I have an update function that calls certain functions every frame. (Checking collisions, moving platforms, etc).

That update function calls my move platforms function..

like this:

[self movePlatforms:0.1];

this is my movePlatforms function..

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

So basically, I created a int moveCount and a BOOL goingDown to keep track of how many times my movePlatform function has been called. So after 100 calls, it switches direction.

(This works fine for me, you might need something else like a collision detecter if that is the case use this).

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

Hopefully this works for someone in the future, I know this was quite the headache for me, and it probably isn't even done correctly or there is a much better way to do it, but if this helps you, that is awesome!

Was it helpful?

Solution 2

Here is the (kind of) step by step of how I got my moving tiles working, this is only related to the moving tiles, and nothing else.

Note: You will need to run this as a release (not debug) in order to get everything running smoothly, and not having your character fall through the ground.

In the interface I created these variables:

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

The CCTMXTiledMap is the instance of my map. The BOOL and int are two variables I use to keep track of my moving tiles.

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

After the init method, I then create my move platforms method:

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

So this is where the magic happens, I use methods I got from here, and the gentleman Mauricio Tollin told me I could update a tile position rather than destroy and recreate them.

So I iterate through every tile in my moving platforms layer, and tell them to go down 1 every call, until moveCount >= 100, then it says goingDown is now false, and it switches its direction. From there it just goes back and forth, counting to 100, and then back down.

If you want it to move longer, just increase 100 to 200 or whatever you want. (Or you can use a check to detect collision, and when it collides with a specified sprite, you can have it change then. If that is more of what you want, use this).

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

After all of that, I create my update method:

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

In the init method it schedules the update method to be called every frame, and then the update method will run the movePlatforms method (or any other function that needs to be checked frequently, such as hazard detection, etc).

You can also make the platforms move slower by changing the time passed into movePlatforms, or you can schedule a slower update interval in the init method.

I hope this helps someone out in the future, I just wanted to create this answer with a more in depth process of how I got this working, since my question post was really unorganized and heavily edited while I was learning.

OTHER TIPS

Creating and removing tiles will effect your performance. Instead of it, try to move the tile changing their position:

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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top