public void render(GraphicsContext gc) {
		int numSpritesRendered = 0;

		//TODO refactor this loop and optimize it -> add camera movement support
		if (currentMap != null) {
			gc.save();
			gc.translate(-100, -100);
			List<List<Integer>> tileIndex = currentMap.getTileIndex();
			for (List<Integer> tileIndexForLayer : tileIndex) {
				int x = 0;
				int y = 0;
				int tileWidth = currentMap.getTileWidth();
				int tileHeight = currentMap.getTileHeight();
				for (int index : tileIndexForLayer) {
					if (index > 0) {
						Entry<Integer, Tileset> entry = currentMap.getTilesets().lowerEntry(index + 1);

						Sprite sprite = mapSpriteCache.get(entry.getValue());
						sprite.setAnimation(index - entry.getKey());
						sprite.setLocation(x * tileWidth, y * tileHeight);
						sprite.render(gc);
						++numSpritesRendered;
					}

					++x;
					if (x >= currentMap.getWidth()) {
						x = 0;
						y++;
					}
				}
			}
			gc.restore();
		}

		for (Entry<GameObject, Sprite> entry : spriteCache.entrySet()) {
			Sprite sprite = entry.getValue();

			if (LOGGER.isDebugEnabled()) {
				GameObject obj = entry.getKey();
				gc.save();
				gc.setGlobalAlpha(0.3);

				// render sprite boundaries
				gc.setFill(Color.BLUE);
				gc.fillRect(sprite.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight());

				if (obj instanceof CollidingGameObject) {
					// render gameObject collision boundaries
					gc.setFill(Color.RED);
					Rectangle2D collisionRect = ((Unit) obj).getCollisionRect();
					gc.fillRect(collisionRect.getMinX(), collisionRect.getMinY(), collisionRect.getWidth(), collisionRect.getHeight());
				}

				gc.restore();
			}

			if (!sprite.isHidden()) {
				++numSpritesRendered;
				sprite.render(gc);
			}
		}

		if (LOGGER.isInfoEnabled()) {
			gc.setFill(Color.rgb(255, 255, 0));
			gc.fillText("FPS: " + oldFPS, 5, 15);

			gc.setFill(Color.rgb(255, 0, 0));
			gc.fillText("RENDERED SPRITES: " + numSpritesRendered, 5, 35);
		}
	}