/// <summary>
        /// Factory method to create Section from a given BackgroundEntity
        /// </summary>
        /// <param name="backgroundEnt"></param>
        /// <param name="maxObstacleOverride">The maximum number of obstacle in the block level</param>
        /// <returns></returns>
        private Section CreateLevelBlock(Entity backgroundEnt, int? maxObstacleOverride = null)
        {
            // Reset position
            backgroundEnt.Transform.Position = Vector3.Zero;

            var levelBlock = new Section();
            var backgroundInfo = backgroundEnt.Get<BackgroundInfo>();
            levelBlock.AddBackgroundEntity(backgroundEnt).AddHoleRange(backgroundInfo.Holes);

            var len = levelBlock.Length;
            RandomAddObstacles(levelBlock, len, maxObstacleOverride ?? backgroundInfo.MaxNbObstacles);

            return levelBlock;
        }
        /// <summary>
        /// Randomly add obstacles to the given level block, while
        /// the number of obstacles to be added is from nbObst.
        /// </summary>
        /// <param name="section"></param>
        /// <param name="patternLen"></param>
        /// <param name="nbObst"></param>
        private void RandomAddObstacles(Section section, float patternLen, int nbObst)
        {
            var halfPatternLen = patternLen / 2f;

            for (var i = 0; i < nbObst; i++)
            {
                // Random val in {0.0-1.0}
                var randVal = random.NextDouble();

                // Calculate position in Z axis by:
                // changing the value in uniform space (randVal) to world space.
                // the value is substracted with halfPatternLen because the origin (0) is at the center of the block.
                var posZ = patternLen * (float)((i + randVal) / nbObst) - halfPatternLen;

                // Random lane, and get the world position in X axis.
                var lane = random.Next(3);
                var posX = (1 - lane) * 5f;

                // Randomly get the obstacle, and set the position of this obstacle.
                bool useSubBoundingBoxes;
                var obsEnt = CloneRandomObstacle(out useSubBoundingBoxes);
                obsEnt.Transform.Position = new Vector3(posX, 0, posZ);

                section.AddObstacleEntity(obsEnt, useSubBoundingBoxes);
            }
        }
        /// <summary>
        /// Factory method to create Section from a given BackgroundEntity
        /// </summary>
        /// <param name="backgroundEnt"></param>
        /// <returns></returns>
        private Section CreateLevelBlock(BackgroundEntity backgroundEnt)
        {
            var levelBlock = new Section();

            levelBlock.AddBackgroundEntity(backgroundEnt.Entity).AddHoleRange(backgroundEnt.Holes);

            var len = levelBlock.Length;
            RandomAddObstacles(levelBlock, len, backgroundEnt.MaxNbObstacles);

            return levelBlock;
        }
 public Section CreateSafeLevelBlock()
 {
     var safeBackground = GetBackgroundEntity(BgKeys.bg_a00);
     var levelBlock = new Section();
     levelBlock.AddBackgroundEntity(safeBackground.Entity);
     return levelBlock;
 }
 private void RemoveLevelBlock(Section firstBlock)
 {
     levelBlocks.Remove(firstBlock);
     Entity.RemoveChild(firstBlock.RootEntity);
 }
        private void AddLevelBlock(Section newSection)
        {
            var count = levelBlocks.Count;
            levelBlocks.Add(newSection);

            if (count == 0)
            {
                Entity.AddChild(newSection.RootEntity);
                return;
            }

            var prevLatestBlock = levelBlocks[count - 1];

            var originDist = 0.5f * (prevLatestBlock.Length + newSection.Length);
            newSection.PositionZ = prevLatestBlock.PositionZ + originDist;

            Entity.AddChild(newSection.RootEntity);
        }