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); }
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); }
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); }
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); } }
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(); }
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); }
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); }
/// <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; } }