Ejemplo n.º 1
0
        public static void ScanCollisions()
        {
            List <Tuple <SpriteCollection, SpriteCollection> > matches = FindMatches();
            List <SpriteCollection> handled = new List <SpriteCollection>();

            foreach (var match in matches)
            {
                Rectangle hb1 = SpriteUtils.GetHitbox(match.Item1);
                Rectangle hb2 = SpriteUtils.GetHitbox(match.Item2);

                if (hb1.Intersects(hb2))
                {
                    Rectangle intersection = Rectangle.Intersect(hb1, hb2);

                    //Send the callbacks for each sprite
                    if (intersection.Right == hb1.Right &&
                        intersection.Height > intersection.Width &&
                        (match.Item1.Info.velocity.X > 0 || match.Item2.Info.velocity.X < 0))    //1 is seeing a collision on the right
                    {
                        handled.Add(match.Item1);
                        handled.Add(match.Item2);
                        (match.Item1 as ICollidable).OnCollision(Direction.RIGHT, match.Item2, intersection);
                        (match.Item2 as ICollidable).OnCollision(Direction.LEFT, match.Item1, intersection);
                    }
                    else if (intersection.Top == hb1.Top &&
                             intersection.Width > intersection.Height &&
                             (match.Item1.Info.velocity.Y < 0 || match.Item2.Info.velocity.Y > 0)) //1 is seeing a collision on the top
                    {
                        handled.Add(match.Item1);
                        handled.Add(match.Item2);
                        (match.Item1 as ICollidable).OnCollision(Direction.TOP, match.Item2, intersection);
                        (match.Item2 as ICollidable).OnCollision(Direction.BOTTOM, match.Item1, intersection);
                    }
                    else if (intersection.Bottom == hb1.Bottom &&
                             intersection.Width > intersection.Height &&
                             (match.Item1.Info.velocity.Y > 0 || match.Item2.Info.velocity.Y < 0)) //1 is seeing a collision on the bottom
                    {
                        handled.Add(match.Item1);
                        handled.Add(match.Item2);
                        (match.Item1 as ICollidable).OnCollision(Direction.BOTTOM, match.Item2, intersection);
                        (match.Item2 as ICollidable).OnCollision(Direction.TOP, match.Item1, intersection);
                    }
                    else if (intersection.Left == hb1.Left &&
                             intersection.Height > intersection.Width &&
                             (match.Item1.Info.velocity.X < 0 || match.Item2.Info.velocity.X > 0)) //1 is seeing a collision on the left
                    {
                        handled.Add(match.Item1);
                        handled.Add(match.Item2);
                        (match.Item1 as ICollidable).OnCollision(Direction.LEFT, match.Item2, intersection);
                        (match.Item2 as ICollidable).OnCollision(Direction.RIGHT, match.Item1, intersection);
                    }
                }
            }

            LastScan.Clear();
            LastScan.AddRange(handled);
        }
Ejemplo n.º 2
0
        //We're comparing every dynamic to each other since there are so few.
        //We're comparing every dynamic to nearby statics, this number should also be small
        private static List <Tuple <SpriteCollection, SpriteCollection> > FindMatches()
        {
            List <Tuple <SpriteCollection, SpriteCollection> > matches = new List <Tuple <SpriteCollection, SpriteCollection> >();

            lock (SpriteLayer.CollisionLayer)
            {
                //Compare all dynamics
                SpriteCollection current, temp;
                Rectangle        hb1, hb2;
                for (int i = 0; i < dynamics.Count; i++)
                {
                    current = dynamics[i];
                    if (current is ICollidable && !current.Info.manual)
                    {
                        hb1 = SpriteUtils.GetHitbox(current);
                        for (int j = i + 1; j < dynamics.Count; j++)
                        {
                            temp = dynamics[j];
                            if (temp is ICollidable)
                            {
                                hb2 = SpriteUtils.GetHitbox(temp);
                                if (hb1.Intersects(hb2))
                                {
                                    matches.Add(new Tuple <SpriteCollection, SpriteCollection>(current, temp));
                                }
                            }
                        }
                    }
                }

                List <int[]> gridsToCheck;
                foreach (SpriteCollection dynamic in dynamics)
                {
                    if (dynamic is ICollidable && !dynamic.Info.manual)
                    {
                        gridsToCheck = SpriteUtils.GetNearbyGrids(dynamic);
                        hb1          = SpriteUtils.GetHitbox(dynamic);
                        foreach (int[] grid in gridsToCheck)
                        {
                            try
                            {
                                if (grid[0] >= 0 && grid[1] < CollisionHandler.grid.GetLength(1))
                                {
                                    List <SpriteCollection> spritesInGrid = CollisionHandler.grid[grid[0], grid[1]];
                                    if (spritesInGrid != null)
                                    {
                                        foreach (SpriteCollection spr in spritesInGrid)
                                        {
                                            if (SpriteLayer.CollisionLayer.Sprites.Contains(spr) && spr is ICollidable)
                                            {
                                                hb2 = SpriteUtils.GetHitbox(spr);
                                                if (hb1.Intersects(hb2))
                                                {
                                                    matches.Add(new Tuple <SpriteCollection, SpriteCollection>(dynamic, spr));
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            catch (IndexOutOfRangeException)
                            {
                            }
                        }
                    }
                }
            }
            return(matches);
        }
Ejemplo n.º 3
0
        public static void LoadLevel(Sprint4 game, string path)
        {
            if (File.Exists(path))
            {
                int maxX = 0;

                //Console.WriteLine("Loading level from {0}", path);
                string[] lines = File.ReadAllLines(path);

                string type, x, y;
                string boundLeft, boundRight, boundTop, boundBottom;
                string arg1, arg2, arg3;

                SpriteLayer currentLayer = null;

                foreach (string line in lines)
                {
                    if (line.Length > 0 && !line.StartsWith("//"))
                    {
                        if (line.StartsWith("Layer"))
                        {
                            string[] tokens = Regex.Split(line, ":");
                            if (tokens.Length >= 2)
                            {
                                string layer = tokens[1];
                                if (layer.Equals("Collision"))
                                {
                                    currentLayer = SpriteLayer.CollisionLayer;
                                }
                                else if (layer.Equals("Background"))
                                {
                                    currentLayer = SpriteLayer.BackgroundLayer;
                                }
                                else if (layer.Equals("HuD"))
                                {
                                    currentLayer = SpriteLayer.HuDLayer;
                                }
                            }
                            continue;
                        }

                        if (currentLayer == null)
                        {
                            Console.WriteLine("[Error] We're starting to load sprites, but a Layer:<LAYER> has not been identified.");
                        }

                        ReadFile(line, out type, out x, out y, out boundLeft, out boundRight, out boundTop, out boundBottom, out arg1, out arg2, out arg3);
                        //Console.WriteLine("Params: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}",
                        //  type, x, y, boundLeft, boundRight, boundTop, boundBottom, arg1, arg2, arg3);

                        if (type.Length == 0 || x.Length == 0 || y.Length == 0)
                        {
                            Console.WriteLine("Invalid parameters provided. type, x, and y must be defined.");
                            continue;
                        }

                        SpriteCollection sprite;

                        switch (type)
                        {
                        case "floor":
                            sprite = SpriteFactory.CreateFloorTile(game);
                            break;

                        case "stair":
                            sprite = SpriteFactory.CreateStairBlock(game);
                            break;

                        case "used":
                            sprite = SpriteFactory.CreateBrick(game);
                            sprite.SetSheetState(SpriteStates.Sheets.USED);
                            sprite.SetSpriteState(SpriteStates.Sprites.IDLE);
                            break;

                        case "brick":
                            sprite = SpriteFactory.CreateBrick(game);
                            break;

                        case "hidden":
                            sprite = SpriteFactory.CreateHiddenBlock(game);
                            break;

                        case "question":
                            sprite = SpriteFactory.CreateQuestionBlock(game);
                            break;

                        case "coin":
                            sprite = SpriteFactory.CreateCoin(game);
                            break;

                        case "fireflower":
                            sprite = SpriteFactory.CreateFireFlower(game);
                            break;

                        case "mushroom":
                            sprite = SpriteFactory.CreateMushroom(game);
                            break;

                        case "oneup":
                            sprite = SpriteFactory.Create1UP(game);
                            break;

                        case "goomba":
                            sprite = SpriteFactory.CreateGoomba(game);
                            break;

                        /*case "koopa":
                         *  if (arg1.Equals("Green") || arg1.Equals("Red"))
                         *  {
                         *      sprite = SpriteFactory.CreateKoopa(game, arg1);
                         *  }
                         *  else
                         *  {
                         *      Console.WriteLine("[Error] Invalid arg1 for Koopa. Must be Green or Red");
                         *      continue;
                         *  }
                         *  break;//*/
                        case "pipe":
                            sprite = SpriteFactory.CreatePipe(game);
                            break;

                        case "background":
                            sprite = SpriteFactory.CreateBackground(game);
                            break;

                        case "mario":
                            sprite = SpriteFactory.CreateHuDMario(game);
                            break;

                        case "flag":
                            sprite    = SpriteFactory.CreateFlag(game);
                            game.flag = (sprite as SpriteFlag);
                            break;

                        case "flagpole":
                            sprite = SpriteFactory.CreateFlagpole(game);
                            break;

                        default:
                            Console.WriteLine("Unrecognized type provided: {0}", type);
                            continue;
                        }

                        string[] xTokens = Regex.Split(x, "[+\\-\\*/]");
                        string[] yTokens = Regex.Split(y, "[+\\-\\*/]");

                        int x1 = resolveValue(game, xTokens[0], sprite);
                        int y1 = resolveValue(game, yTokens[0], sprite);

                        if (xTokens.Length > 1)
                        {
                            if (xTokens.Length != 2)
                            {
                                Console.WriteLine("[Error] x position with an operator provided, but no second value.");
                                continue;
                            }
                            int x2 = resolveValue(game, xTokens[1], sprite);

                            if (x.Contains("+"))
                            {
                                x1 += x2;
                            }
                            else if (x.Contains("-"))
                            {
                                x1 -= x2;
                            }
                            else if (x.Contains("*"))
                            {
                                x1 *= x2;
                            }
                            else if (x.Contains("/"))
                            {
                                x1 /= x2;
                            }
                        }

                        if (yTokens.Length > 1)
                        {
                            if (yTokens.Length != 2)
                            {
                                Console.WriteLine("[Error] y position with an operator provided, but no second value.");
                                continue;
                            }
                            int y2 = resolveValue(game, yTokens[1], sprite);

                            if (y.Contains("+"))
                            {
                                y1 += y2;
                            }
                            else if (y.Contains("-"))
                            {
                                y1 -= y2;
                            }
                            else if (y.Contains("*"))
                            {
                                y1 *= y2;
                            }
                            else if (y.Contains("/"))
                            {
                                y1 /= y2;
                            }
                        }

                        //Console.WriteLine("Setting position to ({0}, {1})", x1, y1);
                        sprite.SetPosition(x1, y1);
                        if (sprite is SpriteFlagpole)
                        {
                            game.flagposition = (int)sprite.Info.position.X;
                        }
                        if (boundLeft.Length > 0)
                        {
                            //should have already caught it if not all 4 bounds were provided
                            //defaults are already assigned as well

                            int bl, br, bt, bb;

                            bl = resolveValue(game, boundLeft, sprite);
                            br = resolveValue(game, boundRight, sprite);
                            bt = resolveValue(game, boundTop, sprite);
                            bb = resolveValue(game, boundBottom, sprite);

                            //Console.WriteLine("Setting bounds of {0} to {1}, {2}, {3}, {4}", sprite.name, bl, bt, (br - bl), (bb - bt));
                            sprite.Info.bounds = new Rectangle(bl, bt, (br - bl), (bb - bt));
                        }

                        if (arg1 != null)
                        {
                            if (sprite is SpriteBlock)
                            {
                                switch (arg1)
                                {
                                case "coin":
                                    (sprite as SpriteBlock).item = new SpriteCoin(game);
                                    int count = 1;
                                    if (arg2 != null)
                                    {
                                        count = resolveValue(game, arg2, sprite);
                                    }
                                    (sprite as SpriteBlock).itemCount = count;
                                    break;

                                case "fireflower":
                                    (sprite as SpriteBlock).item = new SpriteFireFlower(game);
                                    break;

                                case "mushroom":
                                    (sprite as SpriteBlock).item = new SpriteMushroom(game, "Sprites/Items/supershroom");
                                    break;

                                case "oneup":
                                    (sprite as SpriteBlock).item = new SpriteMushroom(game, "Sprites/Items/oneupshroom");
                                    break;

                                case "star":
                                    (sprite as SpriteBlock).item = new SpriteStar(game);
                                    break;
                                }
                            }
                        }

                        currentLayer.AddSprite(sprite);

                        if (sprite.Info.x + sprite.Info.spriteWidth > maxX)
                        {
                            maxX = sprite.Info.x + sprite.Info.spriteWidth;
                        }
                    }
                }

                //Console.WriteLine("Setting game bounds and Collision grid");
                game.bounds = new Rectangle(0, 0, maxX, game.GetViewport().Height);

                foreach (SpriteLayer sl in new SpriteLayer[] { SpriteLayer.BackgroundLayer, SpriteLayer.HuDLayer, SpriteLayer.GameOverLayer })
                {
                    foreach (SpriteCollection sprite in sl.Sprites)
                    {
                        sprite.Info.bounds = game.bounds;
                    }
                }

                int rows    = (int)Math.Ceiling(maxX / 32D) + 1;
                int columns = (int)Math.Ceiling(game.bounds.Height / 32D) + 1;
                CollisionHandler.grid = new List <SpriteCollection> [rows, columns];
                for (int i = 0; i < rows; i++)
                {
                    for (int j = 0; j < columns; j++)
                    {
                        CollisionHandler.grid[i, j] = new List <SpriteCollection>();
                    }
                }
                //Console.WriteLine("Creating grid with {0} rows and {1} columns", rows, columns);
                //Set grids
                foreach (SpriteCollection st in CollisionHandler.statics)
                {
                    List <int[]> grids = SpriteUtils.DetermineGrids(st);
                    foreach (int[] grid in grids)
                    {
                        CollisionHandler.grid[grid[0], grid[1]].Add(st);
                    }
                    st.Info.bounds = game.bounds;
                }

                foreach (SpriteCollection dy in CollisionHandler.dynamics)
                {
                    if (dy.Info.bounds == null || dy.Info.bounds == default(Rectangle))
                    {
                        //Console.WriteLine("Setting {0} bounds to default", dy.name);
                        dy.Info.bounds = game.bounds;
                    }
                }
            }
            else
            {
                //.WriteLine("[Error] File not found: {0}", path);
            }
        }