コード例 #1
0
ファイル: Level.cs プロジェクト: kallotec/Bonsai
        void loadMap(string mapPath)
        {
            currentMapPath = mapPath;

            // Variables
            Jumps.Value      = 0;
            CoinsCount.Value = 0;

            // Reset game objects
            GameObjects.RemoveAll(o => o is Coin || o is Platform || o is Door);

            // Create map tiles
            var doc      = SvgDocument.Open(mapPath);
            var elements = doc.Children.FindSvgElementsOf <SvgPath>();

            // get images

            var patterns = doc.Children.FindSvgElementsOf <SvgPatternServer>();
            var images   = new Dictionary <string, Texture2D>();

            foreach (var pattern in patterns)
            {
                var image = pattern.Children.FindSvgElementsOf <SvgImage>().FirstOrDefault();
                if (image == null)
                {
                    continue;
                }

                if (!string.IsNullOrWhiteSpace(image.Href))
                {
                    var v          = image.Href.ToString() ?? string.Empty;
                    var startIndex = v.IndexOf(',') + 1;
                    var len        = v.Length - startIndex;

                    var base64  = v.Substring(startIndex, len).TrimStart();
                    var texture = convertBase64ToTexure(base64);

                    images.Add(pattern.ID, texture);
                }
            }

            // Load new platforms
            var platformsToLoad = new List <Platform>();

            var maxMapX = 0;
            var maxMapY = 0;

            playerStart = new Vector2(0, 0);
            playerExit  = new Vector2(0, 0);

            foreach (var elem in elements)
            {
                // colors
                var fillColor   = elem.Fill?.ToString() ?? "#FF0000";
                var strokeColor = elem.Stroke?.ToString();

                fillColor = fillColor.TrimStart("url(".ToArray()).TrimEnd(")".ToArray());

                if (fillColor == null || !fillColor.StartsWith("#"))
                {
                    fillColor = "#FF0000";
                }

                if (strokeColor == null || !strokeColor.StartsWith("#"))
                {
                    strokeColor = null;
                }

                var       imageKey  = fillColor.TrimStart('#');
                Texture2D imageData = null;

                if (images.ContainsKey(imageKey))
                {
                    imageData = images[imageKey];
                    fillColor = "#FF0000";
                }

                // dimensions
                var x = (int)Math.Round(elem.Bounds.X, 1);
                var y = (int)Math.Round(elem.Bounds.Y, 1);
                var w = (int)Math.Round(elem.Bounds.Width, 1);
                var h = (int)Math.Round(elem.Bounds.Height, 1);

                // create poly
                var vertexes = elem.PathData.Select(d => new Vector2(d.Start.X, d.Start.Y))
                               .Union(elem.PathData.Select(d => new Vector2(d.End.X, d.End.Y)))
                               .Distinct().ToArray();

                Debug.WriteLine($"[shape]");
                Debug.WriteLine($"size: {x} {y} - {w} x {h}");
                Debug.WriteLine($"verts: {vertexes.Length}");

                if (fillColor == "#000001")
                {
                    playerStart.X = x;
                    playerStart.Y = y;
                }
                else if (fillColor == "#000002")
                {
                    // Door
                    playerExit.X = x;
                    playerExit.Y = y;
                }
                else
                {
                    // Platform
                    var platform = new Platform(fillColor, strokeColor, vertexes, imageData);
                    platform.Load(_loader);
                    platformsToLoad.Add(platform);
                }

                maxMapX = Math.Max(maxMapX, x + w);
                maxMapY = Math.Max(maxMapY, y + h);
            }

            Debug.WriteLine($"Map size in px: {maxMapX} x {maxMapY}");

            // setup chunks
            chunkMap.Reset(chunkWidth: 100, chunkHeight: 100, mapWidth: maxMapX, mapHeight: maxMapY);

            // physics reset
            var phys = new MapPhysics(chunkMap, physSettings);

            foreach (var platform in platformsToLoad)
            {
                if (!GameObjects.Contains(platform))
                {
                    GameObjects.Add(platform);
                }

                chunkMap.UpdateEntity(platform);
            }

            // Verify that the level has a beginning and an end.
            if (playerStart == Vector2.Zero)
            {
                throw new NotSupportedException("A level must have a starting point.");
            }
            if (playerExit == Vector2.Zero)
            {
                throw new NotSupportedException("A level must have an exit.");
            }

            // Set player position for new map
            player.Props.Position = playerStart;

            addCoinToLevel(new Vector2(300, 0));

            // Add end point
            addDoorToLevel(playerExit);
        }
コード例 #2
0
ファイル: Level.cs プロジェクト: kallotec/Bonsai
        void loadMap()
        {
            // reset game objects
            GameObjects.RemoveAll(o => o is LootBox || o is Wall);

            // setup chunks
            chunkMap.Reset(chunkWidth: 100, chunkHeight: 100, mapWidth: 1000, mapHeight: 1000);

            // physics reset
            phys = new MapPhysics(chunkMap, physSettings);

            // read map elements
            var doc   = SvgDocument.Open(ContentPaths.PATH_MAP_1);
            var rects = doc.Children.FindSvgElementsOf <SvgRectangle>();

            foreach (var rect in rects)
            {
                if (rect.Fill.ToString() == "#000001")
                {
                    playerStart = new Vector2(rect.X, rect.Y);
                }
                else if (rect.Fill.ToString() == "#000002")
                {
                    playerExit = new Vector2(rect.X, rect.Y);
                }
                else if (rect.Fill.ToString() == "#000010")
                {
                    var lootBox = new LootBox();
                    lootBox.Props.Position = new Vector2(rect.X, rect.Y);
                    lootBox.Load(_loader);
                    GameObjects.Add(lootBox);
                    chunkMap.UpdateEntity(lootBox);
                }
                else
                {
                    // create wall
                    var fill = getRgba(rect.Fill.ToString());
                    var wall = new Wall(new RectangleF(rect.X, rect.Y, rect.Width, rect.Height), fill);
                    wall.Load(_loader);
                    GameObjects.Add(wall);
                    chunkMap.UpdateEntity(wall);
                }
            }

            // Verify that the level has a beginning and an end.
            //if (playerStart == Vector2.Zero)
            //    throw new NotSupportedException("A level must have a starting point.");
            if (playerExit == Vector2.Zero)
            {
                throw new NotSupportedException("A level must have an exit.");
            }

            // Set player position for new map
            player.Props.Position = playerStart;
            bot.Props.Position    = new Vector2(10, 10);
            chunkMap.UpdateEntity(player);
            chunkMap.UpdateEntity(bot);

            addCoinToLevel(new Vector2(200, 200));

            Camera.SetFocus(player, immediateFocus: true);
        }
コード例 #3
0
        public void ApplyPhysics(PhysicalProperties entityProps, IPhysicsObject entity, GameTime gameTime)
        {
            var delta      = (float)gameTime.ElapsedGameTime.TotalSeconds;
            var lastPos    = entityProps.Position;
            var neighbours = new IPhysicsObject[0];

            var overlappingObjs = new List <IPhysicsObject>();

            // [ Y ]

            entityProps.Position.Y += (entityProps.Velocity.Y * delta);

            // get new neighbours since objects have probably moved
            neighbours = chunkMap.GetNearbyCollidables(entity);

            // overlaps
            if (entity.IsOverlappingEnabled)
            {
                var overlaps = neighbours.Where(n => n.IsOverlappingEnabled && entity.OverlapBox.IntersectsWith(n.OverlapBox));

                foreach (var overlap in overlaps)
                {
                    overlap.OnOverlapping(entity);
                    entity.OnOverlapping(overlap);

                    if (!overlappingObjs.Contains(overlap))
                    {
                        overlappingObjs.Add(overlap);
                    }
                }
            }

            // collision
            if (entity.IsCollisionEnabled)
            {
                var collisions = neighbours.Where(n => n.IsCollisionEnabled && entity.CollisionBox.IntersectsWith(n.CollisionBox));

                var hasCollided = false;

                foreach (var collision in collisions)
                {
                    if (hasCollided)
                    {
                        continue;
                    }

                    hasCollided = true;

                    var up = entityProps.Velocity.Y < 0;
                    entityProps.Velocity.Y = 0;

                    if (up)
                    {
                        entityProps.Position.Y = collision.CollisionBox.Bottom + 1;
                    }
                    else
                    {
                        entityProps.Position.Y = collision.CollisionBox.Top - entity.CollisionBox.Height;
                    }

                    collision.OnCollision(entity);
                    entity.OnCollision(collision);
                }
            }


            // [ X ]

            entityProps.Position.X = entityProps.Position.X + (entityProps.Velocity.X * delta);
            // get new neighbours since objects have probably moved
            neighbours = chunkMap.GetNearbyCollidables(entity);

            if (entity.IsOverlappingEnabled)
            {
                // overlaps
                var overlaps = neighbours.Where(n => n.IsOverlappingEnabled && entity.OverlapBox.IntersectsWith(n.OverlapBox));

                foreach (var overlap in overlaps)
                {
                    overlap.OnOverlapping(entity);
                    entity.OnOverlapping(overlap);

                    if (!overlappingObjs.Contains(overlap))
                    {
                        overlappingObjs.Add(overlap);
                    }
                }
            }

            if (entity.IsCollisionEnabled)
            {
                // collision
                var collisions = neighbours.Where(n => n.IsCollisionEnabled && entity.CollisionBox.IntersectsWith(n.CollisionBox));

                var hasCollided = false;

                foreach (var collision in collisions)
                {
                    if (hasCollided)
                    {
                        continue;
                    }

                    hasCollided = true;

                    entityProps.Velocity.X = 0;
                    entityProps.Position.X = lastPos.X;

                    collision.OnCollision(entity);
                    entity.OnCollision(collision);
                }
            }

            // track overlappers
            entityProps.OverlappingObjects = overlappingObjs;

            // get new neighbours since objects have probably moved
            neighbours = chunkMap.GetNearbyCollidables(entity);

            switch (physSettings.PhysicsType)
            {
            case PhysicsType.Platformer:
                handlePlatformerAdditionalPhysics(entityProps, entity, neighbours, gameTime);
                break;

            case PhysicsType.Topdown:
                handleTopDownAdditionalPhysics(entityProps, entity, neighbours, gameTime);
                break;
            }

            // [ Chunk map update ]

            chunkMap.UpdateEntity(entity);
        }