예제 #1
0
        public GameScreen(GraphicsDevice graphics, ContentManager content)
        {
            cam = new Camera();
            cam.Translate(new Vector2(-10.0f, 50.0f));

            renderTargetBackground = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
            renderTarget           = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
            renderTargetWater      = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
            renderTargetAir        = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight);

            var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.BackgroundCreaturePrefabs);

            if (files.Count > 0)
            {
                BackgroundCreatureManager = new BackgroundCreatureManager(files);
            }
            else
            {
                BackgroundCreatureManager = new BackgroundCreatureManager("Content/BackgroundSprites/BackgroundCreaturePrefabs.xml");
            }

#if LINUX
            var blurEffect = content.Load <Effect>("blurshader_opengl");
            damageEffect = content.Load <Effect>("damageshader_opengl");
#else
            var blurEffect = content.Load <Effect>("blurshader");
            damageEffect = content.Load <Effect>("damageshader");
#endif

            damageStencil = TextureLoader.FromFile("Content/Map/walldamage.png");
            damageEffect.Parameters["xStencil"].SetValue(damageStencil);
            damageEffect.Parameters["aMultiplier"].SetValue(50.0f);
            damageEffect.Parameters["cMultiplier"].SetValue(200.0f);

            lightBlur = new BlurEffect(blurEffect, 0.001f, 0.001f);
        }
예제 #2
0
        public void DrawBackground(SpriteBatch spriteBatch, Camera cam,
                                   BackgroundSpriteManager backgroundSpriteManager     = null,
                                   BackgroundCreatureManager backgroundCreatureManager = null)
        {
            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap);

            Vector2 backgroundPos = cam.WorldViewCenter;

            backgroundPos.Y = -backgroundPos.Y;
            backgroundPos  *= 0.05f;

            if (backgroundPos.Y < 1024)
            {
                if (backgroundPos.Y < 0)
                {
                    backgroundTop.SourceRect = new Rectangle((int)backgroundPos.X, (int)backgroundPos.Y, 1024, (int)Math.Min(-backgroundPos.Y, 1024));
                    backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, Math.Min(-backgroundPos.Y, GameMain.GraphicsHeight)),
                                            Vector2.Zero, level.BackgroundColor);
                }
                if (backgroundPos.Y > -1024)
                {
                    background.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), 1024, 1024);
                    background.DrawTiled(spriteBatch,
                                         (backgroundPos.Y < 0) ? new Vector2(0.0f, (int)-backgroundPos.Y) : Vector2.Zero,
                                         new Vector2(GameMain.GraphicsWidth, (int)Math.Ceiling(1024 - backgroundPos.Y)),
                                         Vector2.Zero, level.BackgroundColor);
                }
            }

            spriteBatch.End();

            spriteBatch.Begin(SpriteSortMode.Deferred,
                              BlendState.AlphaBlend,
                              SamplerState.LinearWrap, DepthStencilState.Default, null, null,
                              cam.Transform);


            if (backgroundSpriteManager != null)
            {
                backgroundSpriteManager.DrawSprites(spriteBatch, cam);
            }
            if (backgroundCreatureManager != null)
            {
                backgroundCreatureManager.Draw(spriteBatch);
            }

            Rectangle srcRect = new Rectangle(0, 0, 2048, 2048);
            Vector2   origin  = new Vector2(cam.WorldView.X, -cam.WorldView.Y);
            Vector2   offset  = -origin + dustOffset;

            while (offset.X <= -srcRect.Width)
            {
                offset.X += srcRect.Width;
            }
            while (offset.X > 0.0f)
            {
                offset.X -= srcRect.Width;
            }
            while (offset.Y <= -srcRect.Height)
            {
                offset.Y += srcRect.Height;
            }
            while (offset.Y > 0.0f)
            {
                offset.Y -= srcRect.Height;
            }
            for (int i = 0; i < 4; i++)
            {
                float scale      = 1.0f - i * 0.2f;
                float recipScale = 1.0f / scale;

                //alpha goes from 1.0 to 0.0 when scale is in the range of 0.5-0.25
                float alpha = (cam.Zoom * scale) < 0.5f ? (cam.Zoom * scale - 0.25f) * 40.0f : 1.0f;
                if (alpha <= 0.0f)
                {
                    continue;
                }

                Vector2 offsetS = offset * scale + new Vector2(cam.WorldView.Width, cam.WorldView.Height) * (1.0f - scale) * 0.5f - new Vector2(256.0f * i);
                while (offsetS.X <= -srcRect.Width * scale)
                {
                    offsetS.X += srcRect.Width * scale;
                }
                while (offsetS.X > 0.0f)
                {
                    offsetS.X -= srcRect.Width * scale;
                }
                while (offsetS.Y <= -srcRect.Height * scale)
                {
                    offsetS.Y += srcRect.Height * scale;
                }
                while (offsetS.Y > 0.0f)
                {
                    offsetS.Y -= srcRect.Height * scale;
                }

                dustParticles.DrawTiled(spriteBatch, origin + offsetS, new Vector2(cam.WorldView.Width - offsetS.X, cam.WorldView.Height - offsetS.Y), Vector2.Zero, srcRect, Color.White * alpha, new Vector2(scale));
            }

            spriteBatch.End();

            RenderWalls(GameMain.Instance.GraphicsDevice, cam);
        }
예제 #3
0
        public void DrawBackground(SpriteBatch spriteBatch, Camera cam, BackgroundCreatureManager backgroundCreatureManager = null)
        {
            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap);

            Vector2 backgroundPos = cam.WorldViewCenter;

            backgroundPos.Y = -backgroundPos.Y;
            backgroundPos  /= 20.0f;

            if (backgroundPos.Y < 1024)
            {
                if (backgroundPos.Y < 0)
                {
                    backgroundTop.SourceRect = new Rectangle((int)backgroundPos.X, (int)backgroundPos.Y, 1024, (int)Math.Min(-backgroundPos.Y, 1024));
                    backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, Math.Min(-backgroundPos.Y, GameMain.GraphicsHeight)),
                                            Vector2.Zero, level.BackgroundColor);
                }
                if (backgroundPos.Y > -1024)
                {
                    background.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), 1024, 1024);
                    background.DrawTiled(spriteBatch,
                                         (backgroundPos.Y < 0) ? new Vector2(0.0f, (int)-backgroundPos.Y) : Vector2.Zero,
                                         new Vector2(GameMain.GraphicsWidth, (int)Math.Ceiling(1024 - backgroundPos.Y)),
                                         Vector2.Zero, level.BackgroundColor);
                }
            }

            spriteBatch.End();

            spriteBatch.Begin(SpriteSortMode.BackToFront,
                              BlendState.AlphaBlend,
                              SamplerState.LinearWrap, DepthStencilState.Default, null, null,
                              cam.Transform);

            backgroundSpriteManager.DrawSprites(spriteBatch, cam);

            if (backgroundCreatureManager != null)
            {
                backgroundCreatureManager.Draw(spriteBatch);
            }


            for (int i = 0; i < 4; i++)
            {
                float scale = 1.0f - i * 0.2f;

                //alpha goes from 1.0 to 0.0 when scale is in the range of 0.2-0.1
                float alpha = (cam.Zoom * scale) < 0.2f ? (cam.Zoom * scale - 0.1f) * 10.0f : 1.0f;
                if (alpha <= 0.0f)
                {
                    continue;
                }

                Vector2 offset = (new Vector2(cam.WorldViewCenter.X, cam.WorldViewCenter.Y) + dustOffset) * scale;
                Vector3 origin = new Vector3(cam.WorldView.Width, cam.WorldView.Height, 0.0f) * 0.5f;

                dustParticles.SourceRect = new Rectangle(
                    (int)((offset.X - origin.X + (i * 256)) / scale),
                    (int)((-offset.Y - origin.Y + (i * 256)) / scale),
                    (int)((cam.WorldView.Width) / scale),
                    (int)((cam.WorldView.Height) / scale));

                spriteBatch.Draw(dustParticles.Texture,
                                 new Vector2(cam.WorldViewCenter.X, -cam.WorldViewCenter.Y),
                                 dustParticles.SourceRect, Color.White * alpha, 0.0f,
                                 new Vector2(cam.WorldView.Width, cam.WorldView.Height) * 0.5f / scale, scale, SpriteEffects.None, 1.0f - scale);
            }

            spriteBatch.End();

            RenderWalls(GameMain.Instance.GraphicsDevice, cam);
        }
예제 #4
0
        public void Generate(bool mirror = false)
        {
            if (backgroundSpriteManager == null)
            {
                var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.BackgroundSpritePrefabs);
                if (files.Count > 0)
                {
                    backgroundSpriteManager = new BackgroundSpriteManager(files);
                }
                else
                {
                    backgroundSpriteManager = new BackgroundSpriteManager("Content/BackgroundSprites/BackgroundSpritePrefabs.xml");
                }
            }
#if CLIENT
            if (backgroundCreatureManager == null)
            {
                var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.BackgroundCreaturePrefabs);
                if (files.Count > 0)
                {
                    backgroundCreatureManager = new BackgroundCreatureManager(files);
                }
                else
                {
                    backgroundCreatureManager = new BackgroundCreatureManager("Content/BackgroundSprites/BackgroundCreaturePrefabs.xml");
                }
            }
#endif

            Stopwatch sw = new Stopwatch();
            sw.Start();

            if (loaded != null)
            {
                loaded.Unload();
            }
            loaded = this;

            positionsOfInterest = new List <InterestingPosition>();

            Voronoi voronoi = new Voronoi(1.0);

            List <Vector2> sites = new List <Vector2>();

            bodies = new List <Body>();

            Rand.SetSyncedSeed(ToolBox.StringToInt(seed));

#if CLIENT
            renderer = new LevelRenderer(this);

            backgroundColor = generationParams.BackgroundColor;
            float avgValue = (backgroundColor.R + backgroundColor.G + backgroundColor.G) / 3;
            GameMain.LightManager.AmbientLight = new Color(backgroundColor * (10.0f / avgValue), 1.0f);
#endif

            SeaFloorTopPos = generationParams.SeaFloorDepth + generationParams.MountainHeightMax + generationParams.SeaFloorVariance;

            float minWidth = 6500.0f;
            if (Submarine.MainSub != null)
            {
                Rectangle dockedSubBorders = Submarine.MainSub.GetDockedBorders();
                minWidth = Math.Max(minWidth, Math.Max(dockedSubBorders.Width, dockedSubBorders.Height));
            }

            Rectangle pathBorders = borders;
            pathBorders.Inflate(-minWidth * 2, -minWidth * 2);

            startPosition = new Vector2(
                Rand.Range(minWidth, minWidth * 2, Rand.RandSync.Server),
                Rand.Range(borders.Height * 0.5f, borders.Height - minWidth * 2, Rand.RandSync.Server));

            endPosition = new Vector2(
                borders.Width - Rand.Range(minWidth, minWidth * 2, Rand.RandSync.Server),
                Rand.Range(borders.Height * 0.5f, borders.Height - minWidth * 2, Rand.RandSync.Server));

            //----------------------------------------------------------------------------------
            //generate the initial nodes for the main path and smaller tunnels
            //----------------------------------------------------------------------------------

            List <Vector2> pathNodes = new List <Vector2>();
            pathNodes.Add(new Vector2(startPosition.X, borders.Height));

            Vector2 nodeInterval = generationParams.MainPathNodeIntervalRange;

            for (float x = startPosition.X + nodeInterval.X;
                 x < endPosition.X - nodeInterval.X;
                 x += Rand.Range(nodeInterval.X, nodeInterval.Y, Rand.RandSync.Server))
            {
                pathNodes.Add(new Vector2(x, Rand.Range(pathBorders.Y, pathBorders.Bottom, Rand.RandSync.Server)));
            }

            pathNodes.Add(new Vector2(endPosition.X, borders.Height));

            if (pathNodes.Count <= 2)
            {
                pathNodes.Insert(1, borders.Center.ToVector2());
            }

            GenerateTunnels(pathNodes, minWidth);

            //----------------------------------------------------------------------------------
            //generate voronoi sites
            //----------------------------------------------------------------------------------

            Vector2 siteInterval = generationParams.VoronoiSiteInterval;
            Vector2 siteVariance = generationParams.VoronoiSiteVariance;
            for (float x = siteInterval.X / 2; x < borders.Width; x += siteInterval.X)
            {
                for (float y = siteInterval.Y / 2; y < borders.Height; y += siteInterval.Y)
                {
                    Vector2 site = new Vector2(
                        x + Rand.Range(-siteVariance.X, siteVariance.X, Rand.RandSync.Server),
                        y + Rand.Range(-siteVariance.Y, siteVariance.Y, Rand.RandSync.Server));

                    if (smallTunnels.Any(t => t.Any(node => Vector2.Distance(node, site) < siteInterval.Length())))
                    {
                        //add some more sites around the small tunnels to generate more small voronoi cells
                        if (x < borders.Width - siteInterval.X)
                        {
                            sites.Add(new Vector2(x, y) + Vector2.UnitX * siteInterval * 0.5f);
                        }
                        if (y < borders.Height - siteInterval.Y)
                        {
                            sites.Add(new Vector2(x, y) + Vector2.UnitY * siteInterval * 0.5f);
                        }
                        if (x < borders.Width - siteInterval.X && y < borders.Height - siteInterval.Y)
                        {
                            sites.Add(new Vector2(x, y) + Vector2.One * siteInterval * 0.5f);
                        }
                    }

                    if (mirror)
                    {
                        site.X = borders.Width - site.X;
                    }

                    sites.Add(site);
                }
            }


            //----------------------------------------------------------------------------------
            // construct the voronoi graph and cells
            //----------------------------------------------------------------------------------

            Stopwatch sw2 = new Stopwatch();
            sw2.Start();

            List <GraphEdge> graphEdges = voronoi.MakeVoronoiGraph(sites, borders.Width, borders.Height);

            Debug.WriteLine("MakeVoronoiGraph: " + sw2.ElapsedMilliseconds + " ms");
            sw2.Restart();

            //construct voronoi cells based on the graph edges
            cells = CaveGenerator.GraphEdgesToCells(graphEdges, borders, GridCellSize, out cellGrid);

            Debug.WriteLine("find cells: " + sw2.ElapsedMilliseconds + " ms");
            sw2.Restart();

            //----------------------------------------------------------------------------------
            // generate a path through the initial path nodes
            //----------------------------------------------------------------------------------

            List <VoronoiCell> mainPath = CaveGenerator.GeneratePath(pathNodes, cells, cellGrid, GridCellSize,
                                                                     new Rectangle(pathBorders.X, pathBorders.Y, pathBorders.Width, borders.Height), 0.5f, mirror);

            for (int i = 2; i < mainPath.Count; i += 3)
            {
                positionsOfInterest.Add(new InterestingPosition(mainPath[i].Center, PositionType.MainPath));
            }

            List <VoronoiCell> pathCells = new List <VoronoiCell>(mainPath);

            //make sure the path is wide enough to pass through
            EnlargeMainPath(pathCells, minWidth);

            foreach (InterestingPosition positionOfInterest in positionsOfInterest)
            {
                WayPoint wayPoint = new WayPoint(positionOfInterest.Position, SpawnType.Enemy, null);
                wayPoint.MoveWithLevel = true;
            }

            startPosition.X = pathCells[0].Center.X;

            //----------------------------------------------------------------------------------
            // tunnels through the tunnel nodes
            //----------------------------------------------------------------------------------

            foreach (List <Vector2> tunnel in smallTunnels)
            {
                if (tunnel.Count < 2)
                {
                    continue;
                }

                //find the cell which the path starts from
                int startCellIndex = CaveGenerator.FindCellIndex(tunnel[0], cells, cellGrid, GridCellSize, 1);
                if (startCellIndex < 0)
                {
                    continue;
                }

                //if it wasn't one of the cells in the main path, don't create a tunnel
                if (cells[startCellIndex].CellType != CellType.Path)
                {
                    continue;
                }

                var newPathCells = CaveGenerator.GeneratePath(tunnel, cells, cellGrid, GridCellSize, pathBorders);

                positionsOfInterest.Add(new InterestingPosition(tunnel.Last(), PositionType.Cave));

                if (tunnel.Count > 4)
                {
                    positionsOfInterest.Add(new InterestingPosition(tunnel[tunnel.Count / 2], PositionType.Cave));
                }

                pathCells.AddRange(newPathCells);
            }

            Debug.WriteLine("path: " + sw2.ElapsedMilliseconds + " ms");
            sw2.Restart();


            //----------------------------------------------------------------------------------
            // remove unnecessary cells and create some holes at the bottom of the level
            //----------------------------------------------------------------------------------

            cells = CleanCells(pathCells);
            pathCells.AddRange(CreateBottomHoles(generationParams.BottomHoleProbability, new Rectangle(
                                                     (int)(borders.Width * 0.2f), 0,
                                                     (int)(borders.Width * 0.6f), (int)(borders.Height * 0.8f))));

            foreach (VoronoiCell cell in cells)
            {
                if (cell.Center.Y < borders.Height / 2)
                {
                    continue;
                }
                cell.edges.ForEach(e => e.OutsideLevel = true);
            }

            //----------------------------------------------------------------------------------
            // initialize the cells that are still left and insert them into the cell grid
            //----------------------------------------------------------------------------------

            foreach (VoronoiCell cell in pathCells)
            {
                cell.edges.ForEach(e => e.OutsideLevel = false);

                cell.CellType = CellType.Path;
                cells.Remove(cell);
            }

            for (int x = 0; x < cellGrid.GetLength(0); x++)
            {
                for (int y = 0; y < cellGrid.GetLength(1); y++)
                {
                    cellGrid[x, y].Clear();
                }
            }

            foreach (VoronoiCell cell in cells)
            {
                int x = (int)Math.Floor(cell.Center.X / GridCellSize);
                int y = (int)Math.Floor(cell.Center.Y / GridCellSize);

                if (x < 0 || y < 0 || x >= cellGrid.GetLength(0) || y >= cellGrid.GetLength(1))
                {
                    continue;
                }

                cellGrid[x, y].Add(cell);
            }


            //----------------------------------------------------------------------------------
            // create some ruins
            //----------------------------------------------------------------------------------

            ruins = new List <Ruin>();
            for (int i = 0; i < generationParams.RuinCount; i++)
            {
                GenerateRuin(mainPath);
            }


            //----------------------------------------------------------------------------------
            // generate the bodies and rendered triangles of the cells
            //----------------------------------------------------------------------------------

            startPosition.Y = borders.Height;
            endPosition.Y   = borders.Height;

            List <VoronoiCell> cellsWithBody = new List <VoronoiCell>(cells);

            List <Vector2[]> triangles;
            bodies = CaveGenerator.GeneratePolygons(cellsWithBody, out triangles);

#if CLIENT
            renderer.SetBodyVertices(CaveGenerator.GenerateRenderVerticeList(triangles).ToArray(), generationParams.WallColor);
            renderer.SetWallVertices(CaveGenerator.GenerateWallShapes(cells), generationParams.WallColor);
#endif

            TopBarrier = BodyFactory.CreateEdge(GameMain.World,
                                                ConvertUnits.ToSimUnits(new Vector2(borders.X, 0)),
                                                ConvertUnits.ToSimUnits(new Vector2(borders.Right, 0)));

            TopBarrier.SetTransform(ConvertUnits.ToSimUnits(new Vector2(0.0f, borders.Height)), 0.0f);
            TopBarrier.BodyType            = BodyType.Static;
            TopBarrier.CollisionCategories = Physics.CollisionLevel;

            bodies.Add(TopBarrier);

            GenerateSeaFloor();

            backgroundSpriteManager.PlaceSprites(this, generationParams.BackgroundSpriteAmount);
#if CLIENT
            backgroundCreatureManager.SpawnSprites(80);
#endif

            foreach (VoronoiCell cell in cells)
            {
                foreach (GraphEdge edge in cell.edges)
                {
                    edge.cell1 = null;
                    edge.cell2 = null;
                    edge.site1 = null;
                    edge.site2 = null;
                }
            }

            //initialize MapEntities that aren't in any sub (e.g. items inside ruins)
            MapEntity.MapLoaded(null);

            Debug.WriteLine("Generatelevel: " + sw2.ElapsedMilliseconds + " ms");
            sw2.Restart();

            if (mirror)
            {
                Vector2 temp = startPosition;
                startPosition = endPosition;
                endPosition   = temp;
            }

            Debug.WriteLine("**********************************************************************************");
            Debug.WriteLine("Generated a map with " + sites.Count + " sites in " + sw.ElapsedMilliseconds + " ms");
            Debug.WriteLine("Seed: " + seed);
            Debug.WriteLine("**********************************************************************************");

            if (GameSettings.VerboseLogging)
            {
                DebugConsole.NewMessage("Generated level with the seed " + seed + " (type: " + generationParams.Name + ")", Color.White);
            }
        }
예제 #5
0
        public void DrawBackground(SpriteBatch spriteBatch, Camera cam,
                                   LevelObjectManager backgroundSpriteManager          = null,
                                   BackgroundCreatureManager backgroundCreatureManager = null)
        {
            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.LinearWrap);

            Vector2 backgroundPos = cam.WorldViewCenter;

            backgroundPos.Y = -backgroundPos.Y;
            backgroundPos  *= 0.05f;

            if (level.GenerationParams.BackgroundTopSprite != null)
            {
                int backgroundSize = (int)level.GenerationParams.BackgroundTopSprite.size.Y;
                if (backgroundPos.Y < backgroundSize)
                {
                    if (backgroundPos.Y < 0)
                    {
                        var backgroundTop = level.GenerationParams.BackgroundTopSprite;
                        backgroundTop.SourceRect = new Rectangle((int)backgroundPos.X, (int)backgroundPos.Y, backgroundSize, (int)Math.Min(-backgroundPos.Y, backgroundSize));
                        backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, Math.Min(-backgroundPos.Y, GameMain.GraphicsHeight)),
                                                color: level.BackgroundTextureColor);
                    }
                    if (-backgroundPos.Y < GameMain.GraphicsHeight && level.GenerationParams.BackgroundSprite != null)
                    {
                        var background = level.GenerationParams.BackgroundSprite;
                        background.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), backgroundSize, backgroundSize);
                        background.DrawTiled(spriteBatch,
                                             (backgroundPos.Y < 0) ? new Vector2(0.0f, (int)-backgroundPos.Y) : Vector2.Zero,
                                             new Vector2(GameMain.GraphicsWidth, (int)Math.Min(Math.Ceiling(backgroundSize - backgroundPos.Y), backgroundSize)),
                                             color: level.BackgroundTextureColor);
                    }
                }
            }

            spriteBatch.End();

            spriteBatch.Begin(SpriteSortMode.Deferred,
                              BlendState.NonPremultiplied,
                              SamplerState.LinearWrap, DepthStencilState.DepthRead, null, null,
                              cam.Transform);

            backgroundSpriteManager?.DrawObjectsBack(spriteBatch, cam);
            if (cam.Zoom > 0.05f)
            {
                backgroundCreatureManager?.Draw(spriteBatch, cam);
            }

            if (level.GenerationParams.WaterParticles != null && cam.Zoom > 0.05f)
            {
                float textureScale = level.GenerationParams.WaterParticleScale;

                Rectangle srcRect = new Rectangle(0, 0, 2048, 2048);
                Vector2   origin  = new Vector2(cam.WorldView.X, -cam.WorldView.Y);
                Vector2   offset  = -origin + dustOffset;
                while (offset.X <= -srcRect.Width * textureScale)
                {
                    offset.X += srcRect.Width * textureScale;
                }
                while (offset.X > 0.0f)
                {
                    offset.X -= srcRect.Width * textureScale;
                }
                while (offset.Y <= -srcRect.Height * textureScale)
                {
                    offset.Y += srcRect.Height * textureScale;
                }
                while (offset.Y > 0.0f)
                {
                    offset.Y -= srcRect.Height * textureScale;
                }
                for (int i = 0; i < 4; i++)
                {
                    float scale = (1.0f - i * 0.2f);

                    //alpha goes from 1.0 to 0.0 when scale is in the range of 0.1 - 0.05
                    float alpha = (cam.Zoom * scale) < 0.1f ? (cam.Zoom * scale - 0.05f) * 20.0f : 1.0f;
                    if (alpha <= 0.0f)
                    {
                        continue;
                    }

                    Vector2 offsetS = offset * scale
                                      + new Vector2(cam.WorldView.Width, cam.WorldView.Height) * (1.0f - scale) * 0.5f
                                      - new Vector2(256.0f * i);

                    float texScale = scale * textureScale;

                    while (offsetS.X <= -srcRect.Width * texScale)
                    {
                        offsetS.X += srcRect.Width * texScale;
                    }
                    while (offsetS.X > 0.0f)
                    {
                        offsetS.X -= srcRect.Width * texScale;
                    }
                    while (offsetS.Y <= -srcRect.Height * texScale)
                    {
                        offsetS.Y += srcRect.Height * texScale;
                    }
                    while (offsetS.Y > 0.0f)
                    {
                        offsetS.Y -= srcRect.Height * texScale;
                    }

                    level.GenerationParams.WaterParticles.DrawTiled(
                        spriteBatch, origin + offsetS,
                        new Vector2(cam.WorldView.Width - offsetS.X, cam.WorldView.Height - offsetS.Y),
                        color: Color.White * alpha, textureScale: new Vector2(texScale));
                }
            }
            spriteBatch.End();

            RenderWalls(GameMain.Instance.GraphicsDevice, cam);

            spriteBatch.Begin(SpriteSortMode.Deferred,
                              BlendState.NonPremultiplied,
                              SamplerState.LinearClamp, DepthStencilState.DepthRead, null, null,
                              cam.Transform);
            backgroundSpriteManager?.DrawObjectsMid(spriteBatch, cam);
            spriteBatch.End();
        }
예제 #6
0
        public void DrawBack(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam, BackgroundCreatureManager backgroundCreatureManager = null)
        {
            float brightness = MathHelper.Clamp(1.1f + (cam.Position.Y - Size.Y) / 100000.0f, 0.1f, 1.0f);

            GameMain.LightManager.AmbientLight = new Color(backgroundColor * brightness, 1.0f);

            graphics.Clear(backgroundColor);

            if (renderer == null)
            {
                return;
            }
            renderer.DrawBackground(spriteBatch, cam, backgroundSpriteManager, backgroundCreatureManager);
        }
예제 #7
0
        public void DrawBack(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam, BackgroundCreatureManager backgroundSpriteManager = null)
        {
            float brightness = MathHelper.Clamp(50.0f + (cam.Position.Y - Size.Y) / 2000.0f, 10.0f, 40.0f);

            float avgValue = (backgroundColor.R + backgroundColor.G + backgroundColor.G) / 3;

            GameMain.LightManager.AmbientLight = new Color(backgroundColor * (brightness / avgValue), 1.0f);

            graphics.Clear(backgroundColor);

            if (renderer == null)
            {
                return;
            }
            renderer.DrawBackground(spriteBatch, cam, backgroundSpriteManager);
        }
예제 #8
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        public override void Update(double deltaTime)
        {
#if DEBUG && CLIENT
            if (GameMain.GameSession != null && GameMain.GameSession.Level != null && GameMain.GameSession.Submarine != null &&
                !DebugConsole.IsOpen)
            {
                var closestSub = Submarine.FindClosest(cam.WorldViewCenter);
                if (closestSub == null)
                {
                    closestSub = GameMain.GameSession.Submarine;
                }

                Vector2 targetMovement = Vector2.Zero;
                if (PlayerInput.KeyDown(Keys.I))
                {
                    targetMovement.Y += 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.K))
                {
                    targetMovement.Y -= 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.J))
                {
                    targetMovement.X -= 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.L))
                {
                    targetMovement.X += 1.0f;
                }

                if (targetMovement != Vector2.Zero)
                {
                    closestSub.ApplyForce(targetMovement * closestSub.SubBody.Body.Mass * 100.0f);
                }
            }
#endif

            foreach (MapEntity e in MapEntity.mapEntityList)
            {
                e.IsHighlighted = false;
            }

#if CLIENT
            if (GameMain.GameSession != null)
            {
                GameMain.GameSession.Update((float)deltaTime);
            }

            BackgroundCreatureManager.Update((float)deltaTime, cam);

            GameMain.ParticleManager.Update((float)deltaTime);

            GameMain.LightManager.Update((float)deltaTime);
#endif

            if (Level.Loaded != null)
            {
                Level.Loaded.Update((float)deltaTime);
            }

#if CLIENT
            if (Character.Controlled != null && Character.Controlled.SelectedConstruction != null && Character.Controlled.CanInteractWith(Character.Controlled.SelectedConstruction))
            {
                Character.Controlled.SelectedConstruction.UpdateHUD(cam, Character.Controlled);
            }
#endif

            Character.UpdateAll((float)deltaTime, cam);

            StatusEffect.UpdateAll((float)deltaTime);

#if CLIENT
            if (Character.Controlled != null && Lights.LightManager.ViewTarget != null)
            {
                cam.TargetPos = Lights.LightManager.ViewTarget.WorldPosition;
            }
#endif

            cam.MoveCamera((float)deltaTime);

            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.SetPrevTransform(sub.Position);
            }

            foreach (PhysicsBody pb in PhysicsBody.list)
            {
                pb.SetPrevTransform(pb.SimPosition, pb.Rotation);
            }

            MapEntity.UpdateAll((float)deltaTime, cam);

            Character.UpdateAnimAll((float)deltaTime);

            Ragdoll.UpdateAll((float)deltaTime, cam);

            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.Update((float)deltaTime);
            }

            GameMain.World.Step((float)deltaTime);

            if (!PlayerInput.LeftButtonHeld())
            {
                Inventory.draggingSlot = null;
                Inventory.draggingItem = null;
            }
        }