예제 #1
0
        public GameWorld(Game game, Camera cam) : base(game)
        {
            _cam             = cam;
            _tileMap         = new TileMap();
            _collisionEngine = new CollisionEngine();

            CollisionComponent.CreatedCollisionComponent += RegisterCollisionBox;
        }
예제 #2
0
        public RaceEngine()
        {
            _collisionEngine = new CollisionEngine(4, 250);
            m_physicsEngine  = new PhysicsEngine();
            m_obstacles      = new List <TireObstacle>(100);
            m_cars           = new List <RaceCar>(4);

            m_physicsEngine.UpdateForcesEvent += PhysicsEngine_UpdateForcesEvent;
        }
 public void CheckCollision()
 {
     if (CollisionEngine.CollisionCheck(new Rectangle((int)(pos.X - dims.X / 2), (int)(pos.Y - dims.Y / 2), (int)dims.X, (int)dims.Y), Globals.currWorld.levels[Globals.currWorld.currLevel].platforms))
     {
         parent.DeleteProjectile(this);
     }
     if (CollisionEngine.CollisionCheck(new Rectangle((int)pos.X, (int)pos.Y, (int)dims.X, (int)dims.Y), ((CollisionObject)Globals.currWorld.hero).GetCollisionBox()))
     {
         ((Entity)Globals.currWorld.hero).GetHit(damage);
         parent.DeleteProjectile(this);
     }
 }
예제 #4
0
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            this.IsMouseVisible = true;

            var w = (float)graphics.PreferredBackBufferWidth;
            var h = (float)graphics.PreferredBackBufferHeight;

            CollisionEngine.Init(new Region(0, (float)w, 0, (float)h), 10);
            PE = new PhysicsEngine();


            var w0 = new VertWallBody(new Vector2(0, h / 2), h);
            var w1 = new VertWallBody(new Vector2(w, h / 2), h);

            var w2 = new HorizWallBody(new Vector2(w / 2, 0), w);
            var w3 = new HorizWallBody(new Vector2(w / 2, h), w);

            PE.MapBodies.Add(w0);
            PE.MapBodies.Add(w1);
            PE.MapBodies.Add(w2);
            PE.MapBodies.Add(w3);


            var c0 = new CircleBody(30, 300, new Vector2(600, h / 2));

            c0.Velocity = -1000 * Vector2.UnitX;
            PE.ActiveBodies.Add(c0);


            Random rand = new Random();

            int nx  = 40;
            int ny  = 30;
            var rad = 4f;
            var buf = 0f;
            var pos = new Vector2(w / 2 - nx * (2f * rad + buf) / 2f, h / 2 - ny * (2f * rad + buf) / 2f);

            for (int xi = 0; xi < nx; xi++)
            {
                for (int yi = 0; yi < ny; yi++)
                {
                    var cent = pos + new Vector2((2f * rad + buf) * xi, (2f * rad + buf) * yi);
                    var ball = new CircleBody(rad, rad, cent);
                    PE.ActiveBodies.Add(ball);
                }
            }



            base.Initialize();
        }
        private void GenerateMaze(Player player)
        {
            var message         = GetComponents <DebugMessageBuilder>().First();
            var entireMaze      = BoundingBox.CreateMerged(new Cell(0, 0).GetBoundingBox(), new Cell(_width - 1, _height - 1).GetBoundingBox());
            var collisionEngine = new CollisionEngine(entireMaze);

            Add(collisionEngine);

            var chunkManager = new ChunkManager(RenderContext, message, collisionEngine, _width, _height);

            collisionEngine.Add(player);

            Add(chunkManager);
        }
예제 #6
0
        /// <summary>
        /// Calculates all the collisionforces acting on a CollisionObject.
        /// </summary>
        /// <param name="obj">The CollisionObject on which the collisions act.</param>
        /// <param name="objects">The other CollisionObjects which act on obj.</param>
        /// <returns>The sum of all the collision forces.</returns>
        public static Vector2 CollisionForces(CollisionObject obj, CollisionObject[] objects)
        {
            Vector2 output = Vector2.Zero;

            for (int j = 0; j < objects.Length; j++)
            {
                if (obj != objects[j])
                {
                    Vector2 collision = CollisionEngine.CollisionSide(obj, objects[j]);
                    if (collision != Vector2.Zero)
                    {
                        output += CollisionForce(obj, objects[j], collision);
                    }
                }
            }
            return(output);
        }
예제 #7
0
        public AbstractScene(string sceneName, bool preload = false, bool alwaysActive = false, bool useLoadingScreen = false)
        {
            if (sceneName == null || sceneName.Length == 0)
            {
                throw new Exception("The scene must have a non-null, non-empty unique name!");
            }
            this.sceneName   = sceneName;
            Preload          = preload;
            AlwaysActive     = alwaysActive;
            UseLoadingScreen = useLoadingScreen;
            UI = new UserInterface();

            LayerManager = new LayerManager(this);
            LayerManager.InitLayers();

            CollisionEngine = new CollisionEngine();

            GridCollisionChecker = new GridCollisionChecker();
        }
예제 #8
0
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            currentStage = new Stage();

            currentStage.camera.position.Y = -0;

            currentCollisionEngine = new CollisionEngines.Octree.OctreeEngine(new BoundingBox(new Vector3(-1024, -1024, -1024), new Vector3(1024, 1024, 1024)), 4);

            Actors.Misc.Box box1 = new Actors.Misc.Box(new Vector3(-100, -100, -100), new Vector3(100, 100, 100));
            box1.position = new Vector3(-200, 0, 0);
            box1.velocity = new Vector3(1, (float)0.4, 0);

            Actors.Misc.Box box2 = new Actors.Misc.Box(new Vector3(-50, -50, -100), new Vector3(50, 50, 50));
            box2.position = new Vector3(200, 0, 0);
            box2.velocity = new Vector3(-1, (float)-0.3, 0);

            Actors.Misc.Box wall1 = new Actors.Misc.Box(new Vector3(-1, -200, -300), new Vector3(1, 200, 300));
            wall1.position = new Vector3(-300, 0, 0);

            Actors.Misc.Box wall2 = new Actors.Misc.Box(new Vector3(-1, -200, -300), new Vector3(1, 200, 300));
            wall2.position = new Vector3(300, 0, 0);

            Actors.Misc.Box wall3 = new Actors.Misc.Box(new Vector3(-300, -1, -300), new Vector3(300, 1, 300));
            wall3.position = new Vector3(0, -200, 0);

            Actors.Misc.Box wall4 = new Actors.Misc.Box(new Vector3(-300, -1, -300), new Vector3(300, 1, 300));
            wall4.position = new Vector3(0, 200, 0);

            currentStage.RegisterActor(box1);
            currentStage.RegisterActor(box2);

            currentStage.RegisterActor(wall1);
            currentStage.RegisterActor(wall2);
            currentStage.RegisterActor(wall3);
            currentStage.RegisterActor(wall4);
        }
        /// <summary>
        /// Load graphics content for the game.
        /// </summary>
        public override void LoadContent()
        {
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");

            _collisions = new CollisionEngine();

            _objectsToBeWrapped = new List<hasPosition2D>();

            DisplayedMessages = new Dictionary<string, string>();
            SpriteBatchDrawable = new SpriteBatch(ScreenManager.Game.GraphicsDevice);

            // A real game would probably have more content than this sample, so
            // it would take longer to load. We simulate that by delaying for a
            // while, giving you a chance to admire the beautiful loading screen.
            // Note by Jason: Awesome... lol
            Thread.Sleep(1000);

            FontSprite = ScreenManager.Game.Content.Load<SpriteFont>("Fonts\\Arial");

            MoritoModel = ScreenManager.Game.Content.Load<Model>("Models\\morito");
            BulletModel = ScreenManager.Game.Content.Load<Model>("Models\\missile");

            //setup a camera
            Camera1 = new Camera();

            Level = new Level();
            Level.LoadContent(this);
            //Level.saveLevelToFile(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\MoritoLevel.xml");

            // once the load has finished, we use ResetElapsedTime to tell the game's
            // timing mechanism that we have just finished a very long frame, and that
            // it should not try to catch up.
            ScreenManager.Game.ResetElapsedTime();
        }
예제 #10
0
        /// <summary>
        /// Splits the maze into chunks.
        /// </summary>
        /// <param name="renderContext"></param>
        /// <param name="cells"></param>
        /// <param name="collisionEngine"></param>
        /// <returns></returns>
        private List <MazeChunk> GenerateChunks(IRenderContext renderContext, Cell[,] cells, CollisionEngine collisionEngine)
        {
            var maxSize = MazeChunk.ChunkSize;
            // instead of creating arrays per chunk we point to the source array by using indices, this is far faster and saves ram
            var w = cells.GetLength(0);
            var h = cells.GetLength(1);

            var chunks = new List <MazeChunk>();
            int yCount = (int)Math.Ceiling(h / (float)maxSize);
            int xCount = (int)Math.Ceiling(w / (float)maxSize);

            for (int y = 0; y < yCount; y++)
            {
                for (int x = 0; x < xCount; x++)
                {
                    var startX = x * maxSize;
                    var startY = y * maxSize;
                    var endX   = Math.Min((x + 1) * maxSize, w);
                    var endY   = Math.Min((y + 1) * maxSize, h);

                    var id    = y * yCount + x;
                    var chunk = new MazeChunk(renderContext, cells, startX, startY, endX, endY, id, collisionEngine);
                    chunks.Add(chunk);
                }
            }
            return(chunks);
        }
예제 #11
0
        public ChunkManager(IRenderContext renderContext, DebugMessageBuilder messageBuilder, CollisionEngine collisionEngine, int width, int height)
        {
            _messageBuilder = messageBuilder;

            var start = new Cell(0, 0).GetBoundingBox();
            var end   = new Cell(width - 1, height - 1).GetBoundingBox();

            var fullGrid = BoundingBox.CreateMerged(start, end);

            _quadtree = new Quadtree <MazeChunk>(fullGrid);

            var cells = GenerateNewMaze(width, height);

            var chunks = GenerateChunks(renderContext, cells, collisionEngine);

            _totalVertices = chunks.Sum(c => c.Vertices);
            _totalChunks   = chunks.Count;
            foreach (var c in chunks)
            {
                _quadtree.Add(c);
            }
        }
예제 #12
0
 /// <summary>
 /// Determines what the AI will do based on wether the player is on view and where he is on the platform.
 /// </summary>
 public void ComputeInput()
 {
     if (VisionBox().Intersects(((CollisionObject)Globals.currWorld.hero).GetCollisionBox()) || VisionBox().Contains(((CollisionObject)Globals.currWorld.hero).GetCollisionBox()) || ((CollisionObject)Globals.currWorld.hero).GetCollisionBox().Contains(VisionBox()))
     {
         if (!CollisionEngine.CollisionCheck(Globals.currWorld.levels[Globals.currWorld.currLevel].platforms, new Segment(new Vector2(GetCollisionBox().Center.X, GetCollisionBox().Top), new Vector2(Globals.currWorld.hero.GetCollisionBox().Center.X, Globals.currWorld.hero.GetCollisionBox().Top))))
         {
             if (!isAttacking)
             {
                 viewingDistance *= 2;
             }
             if (pos.X > Globals.currWorld.hero.pos.X)
             {
                 lastDirRight = false;
             }
             else
             {
                 lastDirRight = true;
             }
             Attack();
             vector      = Vector2.Zero;
             isAttacking = true;
         }
     }
     else
     {
         if (isAttacking)
         {
             viewingDistance /= 2;
         }
         isAttacking      = false;
         attackingCounter = new TimeSpan(0, 0, 0, 1, 250);
     }
     if (!isAttacking)
     {
         if (physicsVector.Y > 0.1f)
         {
             walkingSegment = null;
         }
         else
         {
             if (walkingSegment != null)
             {
                 if (Math.Sign(physicsVector.X) != Math.Sign(goingTo.X - pos.X) && Math.Sign(physicsVector.X) != 0 && Math.Abs(physicsVector.X) > 0.5)
                 {
                     if (goingTo == walkingSegment.defPoint1)
                     {
                         goingTo = walkingSegment.defPoint2;
                     }
                     else
                     {
                         goingTo = walkingSegment.defPoint1;
                     }
                 }
                 if (Math.Abs(goingTo.X - pos.X) < dims.X)
                 {
                     if (goingTo == walkingSegment.defPoint1)
                     {
                         goingTo = walkingSegment.defPoint2;
                     }
                     else
                     {
                         goingTo = walkingSegment.defPoint1;
                     }
                 }
                 if (Math.Sign(goingTo.X - pos.X) < 0)
                 {
                     if (vector.X > -speed)
                     {
                         vector.X += Math.Sign(goingTo.X - pos.X) * walkingAccelaration;
                     }
                 }
                 else
                 {
                     if (vector.X < speed)
                     {
                         vector.X += Math.Sign(goingTo.X - pos.X) * walkingAccelaration;
                     }
                 }
             }
             else
             {
                 FindNewWalkingSegment();
                 if (walkingSegment != null)
                 {
                     if (lastDirRight)
                     {
                         if (walkingSegment.defPoint1.X > walkingSegment.defPoint2.X)
                         {
                             goingTo = walkingSegment.defPoint1;
                         }
                         else
                         {
                             goingTo = walkingSegment.defPoint2;
                         }
                     }
                     else
                     {
                         if (walkingSegment.defPoint1.X > walkingSegment.defPoint2.X)
                         {
                             goingTo = walkingSegment.defPoint2;
                         }
                         else
                         {
                             goingTo = walkingSegment.defPoint1;
                         }
                     }
                 }
             }
         }
     }
 }
예제 #13
0
        /// <summary>
        /// Initializes a new maze chunk by generating the appropriate mesh for the specific part of the mesh.
        /// </summary>
        /// <param name="renderContext"></param>
        /// <param name="cells">The cells from which to generate the mesh. Note that a subset of cells is used by using the indices.</param>
        /// <param name="startXIndex">The start x index inside the cell array to use.</param>
        /// <param name="startYIndex">The start y index inside the cell array to use.</param>
        /// <param name="endX">The (excluded) end x value inside the cell array. Cells from <paramref name="startXIndex"/> to <paramref name="endX"/> - 1 are used.</param>
        /// <param name="endY">The (excluded) end y value inside the cell array. Cells from <paramref name="startYIndex"/> to <paramref name="endY"/> - 1 are used.</param>
        /// <param name="id">The id is used to give each chunk floor a different color so the user can easily see where chunks end.</param>
        /// <param name="collisionEngine">The collision engine to which to add the walls to.</param>
        public MazeChunk(IRenderContext renderContext, Cell[,] cells, int startXIndex, int startYIndex, int endX, int endY, int id, CollisionEngine collisionEngine)
        {
            var floorMeshBuilder = new TexturedMeshDescriptionBuilder();

            var wallMeshBuilder = GenerateWallMesh(cells, startXIndex, startYIndex, endX, endY, collisionEngine);

            // get a boundingbox that contains the entire chunk by using CreateMerged on two cells that are at the opposite end of the chunk
            var topLeft     = cells[startXIndex, startYIndex];
            var bottomRight = cells[endX - 1, endY - 1];
            var merged      = BoundingBox.CreateMerged(topLeft.GetBoundingBox(), bottomRight.GetBoundingBox());

            // generate only one big floor plane for this chunk
            floorMeshBuilder.AddPlane(merged, Plane.NegativeY, false, TileSize);
            BoundingBox = merged;

            _maze      = renderContext.MeshCreator.CreateMesh(wallMeshBuilder);
            _floor     = renderContext.MeshCreator.CreateMesh(floorMeshBuilder);
            _wallBrush = new SolidColorBrush(Color.DarkGray);

            _floorBrush = new SolidColorBrush(_colors[id % _colors.Length]);
        }
예제 #14
0
        /// <summary>
        /// This method will generate the mesh structure inside the provided boundaries. It will already reduce the vertex count by merging walls within a corridor.
        /// Note that this is not the most efficient algorithm (in regards to optimization). It is however very fast.
        /// It runs two steps: first only merging in x direction then in y direction, this will result in a mesh like this.
        /// <example>
        /// XXX
        /// X X
        /// XXX
        /// </example>
        /// into
        /// <example>
        /// 111
        /// 2 3
        /// 444
        /// </example>
        /// Note that the left side (124) could technically also be merged if the algorithm would consider faces, however since it is cell-based it will only merge each cell once.
        /// </summary>
        /// <param name="cells"></param>
        /// <param name="startXIndex"></param>
        /// <param name="startYIndex"></param>
        /// <param name="endX"></param>
        /// <param name="endY"></param>
        /// <param name="collisionEngine"></param>
        /// <returns></returns>
        public static IMeshDescription GenerateWallMesh(Cell[,] cells, int startXIndex, int startYIndex, int endX, int endY, CollisionEngine collisionEngine)
        {
            var skip            = MergeCells(cells, startXIndex, startYIndex, endX, endY);
            var wallMeshBuilder = new TexturedMeshDescriptionBuilder();

            for (int y = startYIndex; y < endY; y++)
            {
                for (int x = startXIndex; x < endX; x++)
                {
                    var c = cells[x, y];

                    var cellBox = c.GetBoundingBox();
                    if (c.Mode == CellMode.Wall)
                    {
                        if (skip[x - startXIndex, y - startYIndex] == 3)
                        {
                            // has already been merged with previous cells, do not add again
                            continue;
                        }
                        // look at the cells to the right if they can be merged
                        if (x + 1 < endX)
                        {
                            // walk to the right as long as possible
                            int count = 0;
                            int i     = 1;
                            while (x + i < endX && skip[x - startXIndex + i, y - startYIndex] == 1)
                            {
                                count = i;
                                i++;
                            }
                            // yes, merge
                            var lastCell = cells[x + count, y].GetBoundingBox();
                            cellBox = BoundingBox.CreateMerged(cellBox, lastCell);
                            // flag all as already merged
                            if (count > 0)
                            {
                                do
                                {
                                    skip[x - startXIndex + count, y - startYIndex] = 3;
                                    count--;
                                } while (count > 0);
                                wallMeshBuilder.AddBox(cellBox, TileSize);
                                collisionEngine.Add(new Wall(cellBox));
                                continue;
                            }
                        }
                        // look at the cells bellow if they can be merged
                        if (y + 1 < endY)
                        {
                            int count = 0;
                            int i     = 1;
                            while (y + i < endY && skip[x - startXIndex, y - startYIndex + i] == 2)
                            {
                                count = i;
                                i++;
                            }
                            // yes, merge
                            var lastCell = cells[x, y + count].GetBoundingBox();
                            cellBox = BoundingBox.CreateMerged(cellBox, lastCell);
                            // flag all as already merged
                            do
                            {
                                skip[x - startXIndex, y - startYIndex + count] = 3;
                                count--;
                            } while (count > 0);
                            wallMeshBuilder.AddBox(cellBox, TileSize);
                            collisionEngine.Add(new Wall(cellBox));
                            continue;
                        }

                        // no merging possible, just place default cell sized box
                        wallMeshBuilder.AddBox(cellBox, TileSize);
                        collisionEngine.Add(new Wall(cellBox));
                    }
                }
            }

            return(wallMeshBuilder);
        }