Sniffle6
Sniffle6

Reputation: 149

A noob error :3

The supplied DisplayObject must be a child of the caller.

What a basic error right? Iv fixed many of these but maybe im just over thinking this... idk anyways...

I have a game drawing a map based off a perlin noise and a bitmap, well drawing the WHOLE map and moving EVERY tile of the map is unpractical and not smart. So iv set it to draw a section of the map and when you push the arrow keys it deletes the tiles and re draws them with the new array of tiles it needs. BUT When i move from the first set of the map, to the next set it deletes the tiles and re draws them fine, but when i try to move to another section of the map it gives me supplied display object must be a child of the caller. Which i get the error, it says what its deleting has to be within what its deleting from (i think). But im not sure why it works the first time but not the next? My guess is it has something to do with the worldTiles sprite that im adding the tiles too. But i dont know how to go about fixing it

If you set the map width to 1600, then push the right key once, it will draw the next area tiles, but you cant go anywhere else without getting an error http://www.fastswf.com/xl3LXbg

On the level class, which is a class that runs when it reaches a certain frame on the timeline. Aka a class connected to a MovieClip on the screen. Within that class I create a new World.class object

    world = new World(this);

This just creates the worldTiles sprite onto the level class and runs the first generate tile when the class is first ran

public function World(parentMC:MovieClip)
    {
        worldTiles = new Sprite();
        parentMC.addChild(worldTiles);
        generateTile();
            }

This is what sets the X and Y of the drawRect and the X and Y of the array it draws the tiles of.

    if (k.keyCode == Keyboard.RIGHT)
    {
        world.deleteTiles();
        world.X += 800/world.TILE_SIZE;
        world.generateTile();
        X += 800/MAP_SCALE;
    }
    if (k.keyCode == Keyboard.LEFT)
    {
        world.deleteTiles();
        world.X -= 800/world.TILE_SIZE;//the actual X width of the tiles being drawn
        world.generateTile();
        X -= 800/MAP_SCALE;//drawRect
    }

This is what im using to delete the tiles on the screen.

public function deleteTiles()
{
    if (tilesInWorld.length > 0)
    {
        for (var i:int = 0; i < tilesInWorld.length; i++)
        {
            worldTiles.removeChild(tilesInWorld[i]);
        }
    }
}

And then when the tiles get re add'd it re runs the generateTiles() function which is this

public function generateTile()
    {
        for (var i=X; i < X+80 i++) //using 80,60 cause thats the screen width / 10, which is default tile size
        {
            for (var j=Y+60; j < grid_height; j++)
            {
                hm = heightmap[i][j];
                if (hm >= 0.84)
                {
                    tile = new Water();
                }
                else if (hm >= 0.8 && hm < 0.84)
                {
                    tile = new Shallow();
                }
                else if (hm >= 0.7 && hm < 0.8)
                {
                    tile = new Sand();
                }
                else if (hm >= 0.2 && hm < 0.7)
                {
                    tile = new Tile();
                }
                else
                {
                    tile = new Stone();
                }
                tile.width = TILE_SIZE;
                tile.height = TILE_SIZE;
                worldTiles.x = 0;
                worldTiles.y = 0;
                tile.x = TILE_SIZE * (i % grid_width);
                tile.y = TILE_SIZE * (j % grid_height);
                tilesInWorld.push(tile);
                worldTiles.addChild(tile);
            }
        }
    }

Upvotes: 0

Views: 25

Answers (1)

Marcela
Marcela

Reputation: 3738

You're never removing the tiles from your tilesInWorld array, so the second time you call deleteTiles it's attempting to delete tiles that were already deleted. Try something like this:

public function deleteTiles()
{
    while (tilesInWorld.length > 0)
    {
        // this will remove the tile from the array, then remove it from the display list
        worldTiles.removeChild(tilesInWorld.pop());
    }
}

Upvotes: 1

Related Questions