My Infinite Terrain Approach:
I have started with an approach that favors completing this task as soon as possible at the cost of performance optimization.
- Create an invisible node with a physics body and add a gesture recognizer. When players swipe the screen, it moves the invisible node.
- Make a textured sprite and add it as a child of the invisible node. The textured sprite is a one of several pre-made tiles that can be repeated to produce the endless terrain.
- Start with one central tile, then write a
spawnTiles()
function that surrounds the first tile on all sides with new tiles. You can call this function for any new tile to surround that tile with more new tiles. But since this will cause tiles to overlap with other tiles, you need a way for the tiles to know if another tile already exists on all of its sides. - Add a small physics body that protrudes from each side of your tiles to act as a "sensor". When a sensor makes contact with another sensor, you know there is a another tile on that side. In the screenshot below, the green squares are sensors that lie on an open edge; the red squares are sensors that are contacting another sensor. (In production these sensors would be invisible).
- Keep calling the
spawnTiles()
method until the screen is completely textured with a significant buffer beyond the frame of the screen. Now players can scroll the terrain and have the illusion that their player sprite is moving through space. - Continuously measure the distance from each tile to the center of the screen. When the edge of the terrain is too close to the center of the view, generate new tiles along the edges so the player never sees any holes in the terrain. If a tile gets too far from the view, destroy that tile to conserve memory.
Analysis:
This is my first SpriteKit game project and I am still getting familiar with the API and libraries. This approach seemed like the quickest way to the terrain working. I expected the iPhone 6 & 7 series (my target platforms) would be sufficient to absorb the extra overhead. However, this feels like a clunky and inelegant approach. It also appears to be rather processor-intensive.
When I ran the scene pictured above in the iPhone 7 simulator, the debugger showed that the CPU was holding at just under 100%. Granted, I'm currently using an arbitrary 1500 × 2668 texture for the tiles which is much larger that I would end up using once I move beyond prototyping.
Still, this approach uses a lot of physics bodies which seems unnecessary and I believe are rather expensive. The whole idea of creating additional objects to detect the tile edges also seems like a very kludgy way to do things. I feel like there must be a better way to handle this sort of two-axis scrolling.
In summation, here are what I see as the pros and cons of this approach.
PROS
- Super fast & easy to get the scrolling behavior working
- Easy to tweak the scrolling behavior by adjusting physics body properties
CONS
- Greater overhead due to extra physics bodies
- Every tile requires six additional node objects to act as sensors
- Dealing with the physics body interactions and juggling the sensor nodes creates additional complexity, potentially leading to technical headaches (as my Stack Overflow postStack Overflow post illustrates)