Well, I thought I would keep it personal for once and talk a bit about my life and how I balance work with family.
I have a normal 8 – 16 job where designing software is one of my work areas. In evenings I like to code on personal projects, like my mobile games. In my private life I have a wife and two young children. How can I prioritize all of this so that everyone are happy?
I guess the short answer is that I can’t. Spending time with personal projects at home will affect the amount of time I spend on my children. However, by keeping a strict schedule for myself I am able to maximize the amount of time I have at my disposal. I divide the week into segments which I try to follow, everything needs to be pre-defined routine.
On weekdays I wake up at around 7:15, I wake the children and take them to school and kindergarden. At 8:30 I start work, and at 17:00 I quit for the day. On a weekday evening I will do some personal programming and spend an hour or so with the children. I usually also get them to bed at night. I go to bed at around 23:30. Over the weekends I do not do any programming, but spend time with my family and go with them on small excursions.
Rinse, repeat. Not an awful lot of hours for personal projects every week, but if I do this routine week in and week out I will eventually create something worthwhile.
Well, that is my routine. Thank you for reading!
I wanted to have the camera rotate so that the planet center would always be straight down. I realized that I could only rotate the camera by a given amount of degrees, not set an absolute angle. This made things a bit harder, so I thought I would share how I did it.
//As center of planet is in (0, 0), it is enough to fetch the current position of the camera to get the correct angle.
Vector2 shipPlanetVector = new Vector2(m_camera.position.x, m_camera.position.y);
//Fetch vector up for camera. The angle between these two is how much we need to rotate the camera.
Vector2 cameraUp = new Vector2(m_camera.up.x, m_camera.up.y);
m_camera.rotate(cameraUp.angle() - shipPlanetVector.angle());
A few days ago my computer froze when I was saving a file I had been working on in Eclipse a few hours. After having restarted, it turned out that the file became totally corrupt. I had not uploaded to my repository that day, so several hours of work was lost, or was it?
After some digging, it turns out that Eclipse saves all source file changes as unique files which is linked to the actual source file. This functionality is called “Local History” in Eclipse. The Local History can even be used to compare different versions of the file. Good to know if you don’t have a repository connected directly to Eclipse, or if you are working offline somewhere.
Well, rendering half a million tiles with the LibGDX OrthogonalTiledMapRenderer is apparently not a good idea. FPS when drawing the whole planet was less than 1 on target, not nice.
After some research I found out that people who know what they are doing are mapping their static map layers to SpriteCache which they send to the GPU one time only. After some trial and error I had my half million tile large planet on screen with a very decent FPS.
You can use a SpriteCache by doing something similar to this:
//Create your TiledMap m_map here.
TiledMapTileLayer planetLayer = (TiledMapTileLayer) m_map.getLayers().get(0);
spriteCache = new SpriteCache(1000000, false);
for (int y = 0; y < planetLayer.getHeight(); y++)
for (int x = 0; x < planetLayer.getWidth(); x++)
Cell cell = planetLayer.getCell(x, y);
if (cell != null)
float tileX = (x - (planetLayer.getWidth() / 2)) * planetLayer.getTileWidth() * planetScale;
float tileY = (y - (planetLayer.getHeight() / 2)) * planetLayer.getTileHeight() * planetScale;
spriteCache.add(cell.getTile().getTextureRegion(), tileX, tileY, 0, 0, 16, 16, planetScale, planetScale, 0);
normalCacheID = spriteCache.endCache();
//spriteCache is done. It is now possible to use it when rendering
//You need to define your OrthographicCamera cameraPlanet
Generally speaking I think rendering half a million tiles might be a bad idea anyway for low end phones. But this is a step in the right direction. If needed, smarter optimization can be performed.
Some possible optimization ideas:
- Create an image of the rendered planet, show that image instead of the actual tiles when zoomed out. Show the tiles when zoomed in and only showing a part of the planet.
- Create mega-tiles to fill the inside of the planet with a small amount of tiles. Keep the normal 16×16 resolution on surface tiles and tiles close to the surface.
- Do not allow zoom out to show the whole planet. Not a good idea, as it would take away from player experience.
I’ve been mapping the surface tiles to box2d bodies with the help of the awesome tool Physics Body Editor. I have divided all the tiles up into separate image files, and then used those as background to map the box2d bodies in the editor.
The resulting json file can be opened with the very helpful BodyEditorLoader.java functionality.
BodyEditorLoader surfaceLoader = new BodyEditorLoader(Gdx.files.internal("data/PlanetSurface/BodyDefinitions.json"));
public Body AddBodyToCell(Cell cell, Vector2 position, World world, float scale)
BodyDef bd = new BodyDef();
bd.type = BodyType.StaticBody;
FixtureDef fd = new FixtureDef();
fd.density = 1;
fd.friction = 1f;
fd.restitution = 0.05f;
Body MyBody = world.createBody(bd);
surfaceLoader.attachFixture(MyBody, cellNameDictionary.get(cell), fd, 16f * scale);
MyBody.setTransform(position.x, position.y, 0f);
After some tinkering with when to load and when to remove the temporary surface bodies we get something like this:
The surface bodies are created in a radius around the ship. Depending on which tile is used, the corresponding body definition from the json file is added to the world.
When the ship moves away from the bodies, they will be removed from the world.
Full planet generation with better textures is now finished. Next step will be to figure out how to generate collision mapping for it.
I introduced the rules I talked about previously, and I also solved the problem with the surface connecting properly at the end. I basically introduced a weight based on the current angle of the vector pointing to the latest tile. This weight would make it more and more probable that tiles are chosen to move closer to the height of the starting point.
I also added tile filling for the planet (that was very irritating to get done), so now I can basically generate a whole planet.
Things to do:
- How do we get collision detection with the ship?
- Test different planet sizes on target, start thinking about optimization if we run into problems
- Make some nicer looking placeholder graphics to make it look a bit more like a planet