0
\$\begingroup\$

So I'm making a side-scrolling adventure type game in Java. The worlds are procedurally generated, so I can't manually place tiles. Therefore, I every 20 ticks (1/3 second) I update every block's tile on the screen. I know this is a terrible solution, and it's causing a bit of lag. I tried only updating the blocks' tiles once when it was created, but it doesn't work well with the way I've programmed my world generation.

Basically, how the ground is generated is the top layer of ground is generated first, then when the player gets close enough, the layers below are created.

public void testForBlocks()
{
        topTaken=false;
        bottomTaken=false;
        rightTaken=false;
        leftTaken=false;

        for(int i=0;i<handler.screenBlocks.size();i++)
        {
                Block b = handler.screenBlocks.get(i);
                if(b.solid)
                {
                        if(b.oneWay==oneWay)
                        {
                                if(b.x==x&&b.y==y+32)
                                        bottomTaken=true;
                                if(b.x==x&&b.y==y-32)
                                        topTaken=true;
                                if(b.y==y&&b.x==x+32)
                                        rightTaken=true;
                                if(b.y==y&&b.x==x-32)
                                        leftTaken=true;
                        }
                }
        }

        setSprite();
}

This means that if I only update the tile's position once, the tile won't recognize that there is a block below it yet(because there isn't), and will be assigned the wrong tile.

Basically, my question is: How can I update tiles, while keeping it efficient?

I feel like I'm missing an obvious solution. Can anyone help me? Thanks in advance. :)

\$\endgroup\$
  • \$\begingroup\$ Could you expand with some information on the size of your tiles and how many tiles you want on screen? \$\endgroup\$ – William Mariager Sep 8 '14 at 10:47
  • \$\begingroup\$ Each tile is 32x32 pixels, and I can fit 33 along the width of the screen, and 21 along the height. The most number of tiles that will be on the screen at once is probably about 1100 of something near that. \$\endgroup\$ – TheBeocro Sep 8 '14 at 10:53
  • \$\begingroup\$ Do you keep track of a viewport? Like the top/left + width/height? \$\endgroup\$ – William Mariager Sep 8 '14 at 11:04
  • \$\begingroup\$ Show us your code. It's not really clear (at least for me) what do mean by updating tiles and why it's really inefficient. P.S. This resource could be useful: www-cs-students.stanford.edu/~amitp/gameprog.html#tiles \$\endgroup\$ – Petr Abdulin Sep 8 '14 at 11:05
  • \$\begingroup\$ Comments removed. Remember that comments are not for discussing solutions or other back and forth. Comments are for clarifying the question. \$\endgroup\$ – MichaelHouse Sep 9 '14 at 14:44
1
\$\begingroup\$

I have two possible solutions.

1) Generate a seed in the beginning of the load. Then load an original world using said seed. A large chunk of the world, you can then use that seed to generate large amounts of the new world while using minimal memory, and the original world will give you enough of a buffer till you get to that section.

2) Generate a group of areas. Then simply recycle them. Kind of like a biome generation. Specific biomes (or areas in this case) will be loaded from past areas. No generation needed except for the loading of old areas.

\$\endgroup\$
0
\$\begingroup\$

Just generate the complete map before the start of the game, generating it while playing seems silly to me, but I don't exactly know what your goal is. Then just render the the visible tiles to the screen. When a tile needs to be updated just update it, if you have too many tiles that needs updating on a single frame just update the tiles visible first and put the rest on hold, maybe a list that gets worked on after X on screen tiles have been updated.

\$\endgroup\$
  • \$\begingroup\$ The map being infinite is a big part of my game, so I can't really generate the entire map ahead of time. Also, "When a tile needs to be updated just update it": My problem is that I'm not sure how to tell when a tile does need to be updated. \$\endgroup\$ – TheBeocro Sep 8 '14 at 10:55
  • \$\begingroup\$ If a player gets close to a chunk you can generate it. If this starts lagging, update a party of it each frame. If you are not sure about when Tiles need to be updated it is kinda hard to write an alghorithm about it. What exactly needs to be updated? \$\endgroup\$ – Madmenyo Sep 8 '14 at 11:16
  • \$\begingroup\$ That's what I'm doing; generating chunks when the player gets near. I'm just want to update tiles that are on-screen, or if possible, have had a block adjacent to them appear or disappear. \$\endgroup\$ – TheBeocro Sep 8 '14 at 11:18
  • \$\begingroup\$ You know the screen/camera position so you can calculate what to draw. You do not store visibility in tiles or chunks but call the chunks/tiles if they need to be drawn. \$\endgroup\$ – Madmenyo Sep 8 '14 at 11:23
0
\$\begingroup\$

The solution was provided by William'MindWorX'Mariager: Only update the tiles in the camera view if the camera view has moved a certain amount, and leave everything else alone. At least, that's how I perceived it, and it worked pretty well.

\$\endgroup\$
  • \$\begingroup\$ Do you mean by that, update only then new tiles are moved into camera's view? \$\endgroup\$ – Petr Abdulin Sep 9 '14 at 7:23
0
\$\begingroup\$

So IF I understand this correct you are dynamicly creating some nodes(tiles) which define the "game" engine. These nodes are connected by vicinity so that each node has a specific number of neighbour nodes and it all works great.

The part of where the issue comes in is that those neighbour nodes need to exist for you to be able to define what sprite should be used to DRAW that node and the question is how to only update the nodes that have not yet been updated but have all the neighbour nodes?

Then the straight forward solution would be that once you create a new node (probably not yet ready to draw) you need to update all its neghbour nodes instead of self. Or rather yet update all the neighbours and the node itself just to be sure.

To make a solution a bit better you should add a boolean value indicating the validation so if(valid==false) update() where update would set the sprite (or whatever needs to be done) and set the valid property to true. So whenever a node is generated get all the nearby nodes and iterate through them using this procedure...

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.