public GameScreen() { RacingGameManager.LoadLevel(TrackSelection.SelectedTrack); RacingGameManager.Player.Reset(); BaseGame.LightDirection = LensFlare.DefaultLightPos; Sound.StartGearSound(); Sound.Play(Sound.Sounds.GameMusic); }
public GamePage() { this.InitializeComponent(); // Create the game. var launchArguments = string.Empty; _game = MonoGame.Framework.XamlGame <RacingGameManager> .Create(launchArguments, Window.Current.CoreWindow, swapChainPanel); }
/// <summary> /// Create game screen /// </summary> public GameScreen() { // Load level RacingGameManager.LoadLevel(TrackSelection.SelectedTrack); // Reset player variables (start new game, reset time and position) RacingGameManager.Player.Reset(); // Fix light direction (was changed by CarSelection screen!) // LightDirection will normalize BaseGame.LightDirection = LensFlare.DefaultLightPos; // Start gear sound Sound.StartGearSound(); // Play game music Sound.Play(Sound.Sounds.GameMusic); }
/// <summary> /// Create game screen /// </summary> public GameScreen(RacingGameManager.Level mapName) { // Load level RacingGameManager.LoadLevel(mapName); // Reset player variables (start new game, reset time and position) RacingGameManager.Player.Reset(); // Fix light direction (was changed by CarSelection screen!) // LightDirection will normalize BaseGame.LightDirection = LensFlare.DefaultLightPos; // Start gear sound Sound.StartGearSound(); // Play game music Sound.Play(Sound.Sounds.GameMusic); RacingGameManager.InputInterface.Escape += InputInterface_Escape; }
// Rest of car variables is automatically calculated below! #endregion #region Render /// <summary> /// Render /// </summary> /// <returns>Bool</returns> public bool Render() { if (BaseGame.AllowShadowMapping) { // Let camera point directly at the center, around 10 units away. BaseGame.ViewMatrix = Matrix.CreateLookAt( new Vector3(0, 10.45f, 2.75f), new Vector3(0, 0, -1), new Vector3(0, 0, 1)); // Let the light come from the front! Vector3 lightDir = -LensFlare.DefaultLightPos; lightDir = new Vector3(lightDir.X, lightDir.Y, -lightDir.Z); // LightDirection will normalize BaseGame.LightDirection = lightDir; // Show 3d cars // Rotate all 3 cars depending on the current selection float perCarRot = MathHelper.Pi * 2.0f / 3.0f; float newCarSelectionRotationZ = RacingGameManager.currentCarNumber * perCarRot; carSelectionRotationZ = InterpolateRotation( carSelectionRotationZ, newCarSelectionRotationZ, BaseGame.MoveFactorPerSecond * 5.0f); // Prebuild all render matrices, we will use them for several times // here. Matrix[] renderMatrices = new Matrix[3]; for (int carNum = 0; carNum < 3; carNum++) { renderMatrices[carNum] = Matrix.CreateRotationZ(BaseGame.TotalTime / 3.9f) * Matrix.CreateTranslation(new Vector3(0, 5.0f, 0)) * Matrix.CreateRotationZ(-carSelectionRotationZ + carNum * perCarRot) * Matrix.CreateTranslation(new Vector3(1.5f, 0.0f, 1.0f)); } // Last translation translates the position of the cars in the UI; // For shadows make sure the car position is the origin RacingGameManager.Player.SetCarPosition(Vector3.Zero, new Vector3(0, 1, 0), new Vector3(0, 0, 1)); // Generate shadows ShaderEffect.shadowMapping.GenerateShadows( delegate { for (int carNum = 0; carNum < 3; carNum++) { // Only the car throws shadows RacingGameManager.CarModel.GenerateShadow( renderMatrices[carNum]); } }); // Render shadows ShaderEffect.shadowMapping.RenderShadows( delegate { for (int carNum = 0; carNum < 3; carNum++) { // Both the car and the selection plate receive shadows RacingGameManager.CarSelectionPlate.UseShadow( renderMatrices[carNum]); RacingGameManager.CarModel.UseShadow(renderMatrices[carNum]); } }); } // This starts both menu and in game post screen shader! // It will render into the sceneMap texture which we will use // later then. BaseGame.UI.PostScreenMenuShader.Start(); // Render background and black bar BaseGame.UI.RenderMenuBackground(); BaseGame.UI.RenderBlackBar(170, 390); // Immediately paint here, else post screen UI will // be drawn over! Texture.additiveSprite.End(); Texture.alphaSprite.End(); //SpriteHelper.DrawAllSprites(); // Restart the sprites after the paint Texture.additiveSprite.Begin(SpriteBlendMode.Additive); Texture.alphaSprite.Begin(SpriteBlendMode.AlphaBlend); // Cars header int posX = 10; int posY = 18; if (Environment.OSVersion.Platform != PlatformID.Win32NT) { posX += 36; posY += 26; } BaseGame.UI.Headers.RenderOnScreenRelative1600( posX, posY, UIRenderer.HeaderChooseCarGfxRect); // Allow selecting the car color TextureFont.WriteText(BaseGame.XToRes(85), BaseGame.YToRes(512), "Car Color: "); for (int num = 0; num < RacingGameManager.CarColors.Count; num++) { Rectangle rect = RacingGameManager.currentCarColor == num? BaseGame.CalcRectangle(250 + num * 50 - 6, 500 - 6, 46 + 12, 46 + 12) : BaseGame.CalcRectangle(250 + num * 50, 500, 46, 46); RacingGameManager.colorSelectionTexture.RenderOnScreen( rect, RacingGameManager.colorSelectionTexture.GfxRectangle, RacingGameManager.CarColors[num]); if (Input.MouseInBox(rect) && Input.MouseLeftButtonPressed) { if (RacingGameManager.currentCarColor != num) { Sound.Play(Sound.Sounds.Highlight); } RacingGameManager.currentCarColor = num; } } // Show car maxSpeed, Acceleration and Mass values. // Also show braking, friction and engine values based on that. CarPhysics.SetCarVariablesForCarType( CarTypeMaxSpeed[RacingGameManager.currentCarNumber], CarTypeMass[RacingGameManager.currentCarNumber], CarTypeMaxAcceleration[RacingGameManager.currentCarNumber]); // Show info and helper texts //TextureFont.WriteText(30, BaseGame.YToRes(280), // "Car: Left/Right"); //TextureFont.WriteText(30, BaseGame.YToRes(370), // "Color: Up/Down"); // Calculate values float maxSpeed = -1.5f + 2.45f * (CarTypeMaxSpeed[RacingGameManager.currentCarNumber] / CarPhysics.DefaultMaxSpeed); float acceleration = -1.25f + 1.85f * (CarTypeMaxAcceleration[RacingGameManager.currentCarNumber] / CarPhysics.DefaultMaxAccelerationPerSec); float mass = -0.65f + 1.5f * (CarTypeMass[RacingGameManager.currentCarNumber] / CarPhysics.DefaultCarMass); float braking = -0.2f + acceleration - mass + maxSpeed; float friction = -1 + (1 / mass + maxSpeed / 5); float engine = -0.2f + 0.5f * (maxSpeed / mass + acceleration - maxSpeed * 5 + 5); if (engine > 0.95f) { engine = 0.95f; } ShowCarPropertyBar( BaseGame.XToRes(1024 - 258), BaseGame.YToRes(190), "Max Speed: " + (int)(CarTypeMaxSpeed[RacingGameManager.currentCarNumber] / CarPhysics.MphToMeterPerSec) + "mph", maxSpeed); ShowCarPropertyBar( BaseGame.XToRes(1024 - 258), BaseGame.YToRes(235), "Acceleration:", acceleration); ShowCarPropertyBar( BaseGame.XToRes(1024 - 258), BaseGame.YToRes(280), "Car Mass:", mass); ShowCarPropertyBar( BaseGame.XToRes(1024 - 258), BaseGame.YToRes(335), "Braking:", braking); ShowCarPropertyBar( BaseGame.XToRes(1024 - 258), BaseGame.YToRes(390), "Friction:", friction); ShowCarPropertyBar( BaseGame.XToRes(1024 - 258), BaseGame.YToRes(445), "Engine:", engine); // Also show bouncing arrow on top of car float arrowWave = (float)Math.Sin(BaseGame.TotalTime / 0.46f) * (float)Math.Cos(BaseGame.TotalTime / 0.285f); float arrowScale = 0.75f - 0.065f * arrowWave; Rectangle arrowRect = BaseGame.CalcRectangle(512, 120, (int)Math.Round(UIRenderer.BigArrowGfxRect.Width * arrowScale), (int)Math.Round(UIRenderer.BigArrowGfxRect.Width * arrowScale)); arrowRect.X -= arrowRect.Width / 2; // Not displayed anymore .. // Show left/right arrows Rectangle selArrowGfxRect = UIRenderer.SelectionArrowGfxRect; Rectangle leftRect = BaseGame.CalcRectangle(35, 250, selArrowGfxRect.Width, selArrowGfxRect.Height); leftRect.Y = BaseGame.YToRes(300 + 60) + arrowRect.Y / 3; leftRect.X += (int)Math.Round(BaseGame.XToRes(12) * arrowWave); BaseGame.UI.Buttons.RenderOnScreen( leftRect, new Rectangle(selArrowGfxRect.X + selArrowGfxRect.Width, selArrowGfxRect.Y, -selArrowGfxRect.Width, selArrowGfxRect.Height)); Rectangle rightRect = BaseGame.CalcRectangle( 1024 - 335 - selArrowGfxRect.Width, 250, selArrowGfxRect.Width, selArrowGfxRect.Height); rightRect.Y = BaseGame.YToRes(300 + 60) + arrowRect.Y / 3; rightRect.X -= (int)Math.Round(BaseGame.XToRes(12) * arrowWave); BaseGame.UI.Buttons.RenderOnScreen( rightRect, UIRenderer.SelectionArrowGfxRect); // Also handle xbox controller input if (Input.GamePadLeftJustPressed || Input.KeyboardLeftJustPressed || Input.MouseLeftButtonJustPressed && Input.MouseInBoxRelative(new Rectangle(512 + 50, 170, 512 - 150, 135))) { Sound.Play(Sound.Sounds.Highlight); RacingGameManager.currentCarNumber = (RacingGameManager.currentCarNumber + 1) % 3; } else if (Input.GamePadRightJustPressed || Input.KeyboardRightJustPressed || Input.MouseLeftButtonJustPressed && Input.MouseInBoxRelative(new Rectangle(100, 170, 512 - 200, 135))) { Sound.Play(Sound.Sounds.Highlight); RacingGameManager.currentCarNumber = (RacingGameManager.currentCarNumber + 2) % 3; } // Mouse input is handled in RacingGameManager.cs if (Input.GamePadUpJustPressed || Input.KeyboardUpJustPressed) { Sound.Play(Sound.Sounds.Highlight); RacingGameManager.currentCarColor = (RacingGameManager.currentCarColor + RacingGameManager.NumberOfCarColors - 1) % RacingGameManager.NumberOfCarColors; } else if (Input.GamePadDownJustPressed || Input.KeyboardDownJustPressed) { Sound.Play(Sound.Sounds.Highlight); RacingGameManager.currentCarColor = (RacingGameManager.currentCarColor + 1) % RacingGameManager.NumberOfCarColors; } bool aButtonPressed = BaseGame.UI.RenderBottomButtons(false); if (Input.GamePadAJustPressed || Input.KeyboardSpaceJustPressed || aButtonPressed) { RacingGameManager.AddGameScreen(new TrackSelection()); return(false); } if (Input.KeyboardEscapeJustPressed || Input.GamePadBJustPressed || Input.GamePadBackJustPressed || BaseGame.UI.backButtonPressed) { return(true); } return(false); }
/// <summary> /// Render /// </summary> /// <returns>Bool</returns> public bool Render() { // This starts both menu and in game post screen shader! if (BaseGame.UsePostScreenShaders) { BaseGame.UI.PostScreenMenuShader.Start(); } // Render background and black bar BaseGame.UI.RenderMenuBackground(); BaseGame.UI.RenderBlackBar(280, 192); // Show logos // Little helper to keep track if mouse is actually over a button. // Required because buttons are selected even when not hovering over // them for GamePad support, but we still want the mouse only to // be apply when we are actually over the button. int mouseIsOverButton = -1; // If the user manipulated the mouse, stop ignoring the mouse // This allows the mouse to override the game pad or keyboard selection if (Input.HasMouseMoved || Input.MouseLeftButtonJustPressed) { ignoreMouse = false; } // Show buttons // Part 1: Calculate global variables for our buttons Rectangle activeRect = BaseGame.CalcRectangleCenteredWithGivenHeight( 0, 0, ActiveButtonWidth, ButtonRects[0]); Rectangle inactiveRect = BaseGame.CalcRectangleCenteredWithGivenHeight( 0, 0, InactiveButtonWidth, ButtonRects[0]); int totalWidth = activeRect.Width + (NumberOfButtons - 1) * inactiveRect.Width + (NumberOfButtons - 1) * BaseGame.XToRes(DistanceBetweenButtons); int xPos = BaseGame.XToRes(512) - totalWidth / 2; int yPos = BaseGame.YToRes(316); for (int num = 0; num < NumberOfButtons; num++) { // Is this button currently selected? bool selected = num == SelectedButton; // Increase size if selected, decrease otherwise currentButtonSizes[num] += (selected ? 1 : -1) * BaseGame.MoveFactorPerSecond * 2; if (currentButtonSizes[num] < 0) { currentButtonSizes[num] = 0; } if (currentButtonSizes[num] > 1) { currentButtonSizes[num] = 1; } // Use this size to build rect Rectangle thisRect = InterpolateRect(activeRect, inactiveRect, currentButtonSizes[num]); Rectangle renderRect = new Rectangle( xPos, yPos - (thisRect.Height - inactiveRect.Height) / 2, thisRect.Width, thisRect.Height); BaseGame.UI.Buttons.RenderOnScreen(renderRect, ButtonRects[num], selected ? Color.White : new Color(192, 192, 192, 192)); // Add border effect if selected if (selected) { BaseGame.UI.Buttons.RenderOnScreen(renderRect, UIRenderer.MenuButtonSelectionGfxRect); } // Also add text below button Rectangle textRenderRect = new Rectangle( xPos, renderRect.Bottom + BaseGame.YToRes(5), renderRect.Width, renderRect.Height * TextRects[0].Height / ButtonRects[0].Height); if (selected) { BaseGame.UI.Buttons.RenderOnScreen(textRenderRect, TextRects[num], selected ? Color.White : new Color(192, 192, 192, 192)); } // Also check if the user hovers with the mouse over this button if (Input.MouseInBox(renderRect)) { mouseIsOverButton = num; } xPos += thisRect.Width + BaseGame.XToRes(DistanceBetweenButtons); } if (!ignoreMouse && mouseIsOverButton >= 0) { SelectedButton = mouseIsOverButton; } // Handle input, we have 2 modes: Immediate response if one of the // keys is pressed to move our selected menu entry and after a timeout we // move even more. Controlling feels more natural this way. if (Input.KeyboardLeftPressed || Input.GamePadLeftPressed) { pressedLeftMs += BaseGame.ElapsedTimeThisFrameInMilliseconds; } else { pressedLeftMs = 0; } if (Input.KeyboardRightPressed || Input.GamePadRightPressed) { pressedRightMs += BaseGame.ElapsedTimeThisFrameInMilliseconds; } else { pressedRightMs = 0; } // Handle GamePad input, and also allow keyboard input if (Input.GamePadLeftJustPressed || Input.KeyboardLeftJustPressed || (pressedLeftMs > 250 && (Input.KeyboardLeftPressed || Input.GamePadLeftPressed))) { pressedLeftMs -= 250; Sound.Play(Sound.Sounds.Highlight); SelectedButton = (SelectedButton + NumberOfButtons - 1) % NumberOfButtons; ignoreMouse = true; } else if (Input.GamePadRightJustPressed || Input.KeyboardRightJustPressed || (pressedRightMs > 250 && (Input.KeyboardRightPressed || Input.GamePadRightPressed))) { pressedRightMs -= 250; Sound.Play(Sound.Sounds.Highlight); SelectedButton = (SelectedButton + 1) % NumberOfButtons; ignoreMouse = true; } // If user presses the mouse button or the game pad A or Space, // start the game screen for the currently selected game part. if ((mouseIsOverButton >= 0 && Input.MouseLeftButtonJustPressed) || Input.GamePadAJustPressed || Input.KeyboardSpaceJustPressed) { idleTime = 0.0f; // Start game screen switch (SelectedButton) { case 0: RacingGameManager.AddGameScreen(new CarSelection()); break; case 1: RacingGameManager.AddGameScreen(new Highscores()); break; case 2: RacingGameManager.AddGameScreen(new Options()); break; case 3: RacingGameManager.AddGameScreen(new Help()); break; case 4: // Exit return(true); } } if (Input.KeyboardEscapeJustPressed || Input.GamePadBackJustPressed) { return(true); } // If the game sits idle at the menu for too long, // return to the splash screen idleTime += BaseGame.ElapsedTimeThisFrameInMilliseconds; if (idleTime > TimeOutMenu) { idleTime = 0.0f; RacingGameManager.AddGameScreen(new SplashScreen()); } return(false); }
/// <summary> /// Render car model with this seperate method because we /// render it in 2 steps, first the solid stuff, then the alpha glass. /// We also rotate the wheels around :) /// </summary> /// <param name="carNumber">Car type number (0, 1 or 2) for the car /// texture</param> /// <param name="carColor">Car color we are currently using.</param> /// <param name="shadowCarMode">In the shadow car mode we render /// everything (including wheels and glass) with a special ShadowCar /// shader, that is very transparent. Used for the shadow car when /// playing that shows how we drove the last time.</param> /// <param name="renderMatrix">Render matrix for the car</param> public void RenderCar(int carNumber, Color carColor, bool shadowCarMode, Matrix renderMatrix) { // Multiply object matrix by render matrix, result is used multiple // times here. renderMatrix = objectMatrix * renderMatrix; // Do we just want to render the shadow car? Then do this in a // simpified way here instead of messing with the already complicated // code below. if (shadowCarMode) { // Start shadow car shader ShaderEffect simpleShader = ShaderEffect.lighting; simpleShader.Render( "ShadowCar", delegate { int wheelNumber = 0; // And just render all meshes with it! for (int meshNum = 0; meshNum < xnaModel.Meshes.Count; meshNum++) { ModelMesh mesh = xnaModel.Meshes[meshNum]; Matrix meshMatrix = transforms[mesh.ParentBone.Index]; // Only the wheels have 2 mesh parts (gummi and chrome) if (mesh.MeshParts.Count == 2) { wheelNumber++; meshMatrix = Matrix.CreateRotationX( // Rotate left 2 wheels forward, the other 2 backward (wheelNumber == 2 || wheelNumber == 4 ? 1 : -1) * RacingGameManager.Player.CarWheelPos) * meshMatrix; } // Assign world matrix BaseGame.WorldMatrix = meshMatrix * renderMatrix; // Set all matrices simpleShader.SetParameters(); simpleShader.Update(); // And render (must be done without mesh.Draw, which would // just use the original shaders for the model) for (int partNum = 0; partNum < mesh.MeshParts.Count; partNum++) { ModelMeshPart part = mesh.MeshParts[partNum]; // Make sure vertex declaration is correct // Set vertex buffer and index buffer BaseGame.Device.SetVertexBuffer(part.VertexBuffer); BaseGame.Device.Indices = part.IndexBuffer; // And render all primitives BaseGame.Device.DrawIndexedPrimitives( PrimitiveType.TriangleList, part.VertexOffset, 0, part.NumVertices, part.StartIndex, part.PrimitiveCount); } } }); // And get outta here return; } // Usually use default color values Color ambientColor = Material.DefaultAmbientColor; Color diffuseColor = Material.DefaultDiffuseColor; EffectTechnique remCurrentTechnique = null; for (int alphaPass = 0; alphaPass < 2; alphaPass++) { int wheelNumber = 0; int effectParameterIndex = 0; int effectTechniqueIndex = 0; for (int meshNum = 0; meshNum < xnaModel.Meshes.Count; meshNum++) { ModelMesh mesh = xnaModel.Meshes[meshNum]; bool dontRender = false; for (int effectNum = 0; effectNum < mesh.Effects.Count; effectNum++) { Effect effect = mesh.Effects[effectNum]; if (effectNum == 0) { remCurrentTechnique = effect.CurrentTechnique; } // Find out if this is ReflectionSimpleGlass.fx, // NormalMapping.fx will also use reflection, but the techniques // are named in another way (SpecularWithReflection, etc.) if (cachedIsReflectionSpecularTechnique[effectTechniqueIndex++]) { if (alphaPass == 0) { dontRender = true; effectParameterIndex += 7; break; } // Skip the first 3 effect parameters effectParameterIndex += 3; } else { if (alphaPass == 1) { dontRender = true; effectParameterIndex += 7; break; } // To improve performance we only have to set this when it // changes! Doesn't do much, because this eats only 10% // performance, 5-10% are the matrices below and most of the // performance is just rendering the car with Draw! // Overwrite car diffuse textures depending on the car number // we want to render. cachedEffectParameters[effectParameterIndex++].SetValue( RacingGameManager.CarTexture(carNumber).XnaTexture); // Also set color cachedEffectParameters[effectParameterIndex++].SetValue( ambientColor.ToVector4()); cachedEffectParameters[effectParameterIndex++].SetValue( diffuseColor.ToVector4()); // Change shader to // VertexOutput_SpecularWithReflectionForCar20 // if we changed the color. if (RacingGameManager.currentCarColor != 0 && effectNum == 0) { effect.CurrentTechnique = effect.Techniques["SpecularWithReflectionForCar20"]; // And set carHueColorChange effect.Parameters["carHueColor"].SetValue( carColor.ToVector3()); } } Matrix meshMatrix = transforms[mesh.ParentBone.Index]; // Only the wheels have 2 mesh parts (gummi and chrome) if (mesh.MeshParts.Count == 2) { wheelNumber++; meshMatrix = Matrix.CreateRotationX( // Rotate left 2 wheels forward, the other 2 backward! (wheelNumber == 2 || wheelNumber == 4 ? 1 : -1) * RacingGameManager.Player.CarWheelPos) * meshMatrix; } // Assign world matrix BaseGame.WorldMatrix = meshMatrix * renderMatrix; // Set matrices cachedEffectParameters[effectParameterIndex++].SetValue( BaseGame.WorldMatrix); // These values should only be set once every frame (see above)! // to improve performance again, also we should access them // with EffectParameter and not via name! // But since we got only 1 car it doesn't matter so much .. cachedEffectParameters[effectParameterIndex++].SetValue( BaseGame.ViewProjectionMatrix); cachedEffectParameters[effectParameterIndex++].SetValue( BaseGame.InverseViewMatrix); // Set light direction cachedEffectParameters[effectParameterIndex++].SetValue( BaseGame.LightDirection); } // Render if (dontRender == false) { mesh.Draw(); } // Change shader back to default render technique. // We only have to do this if the color was changed if (RacingGameManager.currentCarColor != 0 && remCurrentTechnique != null) { mesh.Effects[0].CurrentTechnique = remCurrentTechnique; } } } }
/// <summary> /// Create landscape. /// This constructor should only be called /// from the RacingGame main class! /// </summary> /// <param name="setLevel">Level we want to load</param> internal Landscape(RacingGameManager.Level setLevel) { #region Load map height data #if OBS_DOESNT_WORK_ON_XBOX360 // Ok, load map grid heights. We can't load this as a Bitmap // because we don't have the System.Drawing namespace in XNA. // We also can't use BitmapContent or PixelBitmapContent<Color> from // the Microsoft.XNA.Framework.Content.Pipeline namespace because // our content is not compatible with that (its just a texture). Texture2D tex = BaseGame.Content.Load<Texture2D>( Path.Combine(Directories.ContentDirectory, "LandscapeGridHeights")); /*old Texture2D.FromFile(BaseGame.Device, "Textures\\LandscapeGridHeights.png"); */ if (tex.Width != GridWidth || tex.Height != GridHeight) throw new Exception(tex.Name + " has the resolution of " + tex.Width + "x" + tex.Height + ", but for the landscape we need " + GridWidth + "x" + GridHeight + "!"); // With help of GetData we can get to the data. Color[] texData = new Color[GridWidth * GridHeight]; tex.GetData<Color>(texData, 0, GridWidth * GridHeight); //tst: Log.Write("Pixel 0, 0=" + texData[0]); #endif FileStream file = FileHelper.LoadGameContentFile( "Content\\"+LandscapeHeightsDataFilename); byte[] heights = new byte[GridWidth * GridHeight]; file.Read(heights, 0, GridWidth*GridHeight); file.Close(); mapHeights = new float[GridWidth, GridHeight]; #endregion #region Build tangent vertices // Build our tangent vertices for (int x = 0; x < GridWidth; x++) for (int y = 0; y < GridHeight; y++) { // Step 1: Calculate position int index = x + y * GridWidth; Vector3 pos = CalcLandscapePos(x, y, heights);//texData); mapHeights[x, y] = pos.Z; vertices[index].pos = pos; //if (x == 0) // Log.Write("vertices " + y + ": " + pos); // Step 2: Calculate all edge vectors (for normals and tangents) // This involves quite complicated optimizations and mathematics, // hard to explain with just a comment. Read my book :D Vector3 edge1 = pos - CalcLandscapePos(x, y + 1, heights);//texData); Vector3 edge2 = pos - CalcLandscapePos(x + 1, y, heights);//texData); Vector3 edge3 = pos - CalcLandscapePos(x - 1, y + 1, heights);//texData); Vector3 edge4 = pos - CalcLandscapePos(x + 1, y + 1, heights);//texData); Vector3 edge5 = pos - CalcLandscapePos(x - 1, y - 1, heights);//texData); // Step 3: Calculate normal based on the edges (interpolate // from 3 cross products we build from our edges). vertices[index].normal = Vector3.Normalize( Vector3.Cross(edge2, edge1) + Vector3.Cross(edge4, edge3) + Vector3.Cross(edge3, edge5)); // Step 4: Set tangent data, just use edge1 vertices[index].tangent = Vector3.Normalize(edge1); // Step 5: Set texture coordinates, use full 0.0f to 1.0f range! vertices[index].uv = new Vector2( //x / (float)(GridWidth - 1), //y / (float)(GridHeight - 1)); y / (float)(GridHeight - 1), x / (float)(GridWidth - 1)); } // for for (int) #endregion #region Smooth normals // Smooth all normals, first copy them over, then smooth everything Vector3[,] normalsForSmoothing = new Vector3[GridWidth, GridHeight]; for (int x = 0; x < GridWidth; x++) for (int y = 0; y < GridHeight; y++) { int index = x + y * GridWidth; normalsForSmoothing[x, y] = vertices[index].normal; } // for for (int) // Time to smooth to normals we just saved for (int x = 1; x < GridWidth - 1; x++) for (int y = 1; y < GridHeight - 1; y++) { int index = x + y * GridWidth; // Smooth 3x3 normals, but still use old normal to 40% (5 of 13) Vector3 normal = vertices[index].normal * 4; for (int xAdd = -1; xAdd <= 1; xAdd++) for (int yAdd = -1; yAdd <= 1; yAdd++) normal += normalsForSmoothing[x+xAdd, y+yAdd]; vertices[index].normal = Vector3.Normalize(normal); // Also recalculate tangent to let it stay 90 degrees on the normal Vector3 helperVector = Vector3.Cross( vertices[index].normal, vertices[index].tangent); vertices[index].tangent = Vector3.Cross( helperVector, vertices[index].normal); } // for for (int) #endregion #region Set vertex buffer // Set vertex buffer vertexBuffer = new VertexBuffer( BaseGame.Device, typeof(TangentVertex), vertices.Length, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); #endregion #region Calc index buffer // Calc index buffer (Note: have to use uint, ushort is not sufficiant // in our case because we have MANY vertices ^^) uint[] indices = new uint[(GridWidth - 1) * (GridHeight - 1) * 6]; int currentIndex = 0; for (int x = 0; x < GridWidth - 1; x++) for (int y = 0; y < GridHeight - 1; y++) { // Set landscape data (Note: Right handed) indices[currentIndex + 0] = (uint)(x * GridHeight + y); indices[currentIndex + 2] = (uint)((x + 1) * GridHeight + (y + 1)); indices[currentIndex + 1] = (uint)((x + 1) * GridHeight + y); indices[currentIndex + 3] = (uint)((x + 1) * GridHeight + (y + 1)); indices[currentIndex + 5] = (uint)(x * GridHeight + y); indices[currentIndex + 4] = (uint)(x * GridHeight + (y + 1)); // Add indices currentIndex += 6; } // for for (int) #endregion #region Set index buffer indexBuffer = new IndexBuffer( BaseGame.Device, typeof(uint), (GridWidth - 1) * (GridHeight - 1) * 6, BufferUsage.WriteOnly); indexBuffer.SetData(indices); #endregion #region Load track (and replay inside ReloadLevel method) // Load track based on the level selection and set car pos with // help of the ReloadLevel method. ReloadLevel(setLevel); #endregion #region Add city planes // Just set one giant plane for the whole city! foreach (LandscapeObject obj in landscapeObjects) if (obj.IsBigBuilding) { cityPlane = new PlaneRenderer( obj.Position, new Plane(new Vector3(0, 0, 1), 0.1f), cityMat, Math.Min(obj.Position.X, obj.Position.Y));//); break; } // foreach if (obj.IsBigBuilding) #endregion }
/// <summary> /// Reload level /// </summary> /// <param name="setLevel">Level</param> internal void ReloadLevel(RacingGameManager.Level setLevel) { level = setLevel; // Load track based on the level selection, do this after // we got all the height data because the track might be adjusted. if (track == null) track = new Track("Track" + level.ToString(), this); else track.Reload("Track" + level.ToString(), this); // Load replay for this track to show best player bestReplay = new Replay((int)level, false, track); newReplay = new Replay((int)level, true, track); // Kill brake tracks brakeTracksVertices.Clear(); brakeTracksVerticesArray = null; // Set car at start pos SetCarToStartPosition(); }
/// <summary> /// Render game screen. Called each frame. /// </summary> public bool Render() { // This starts both menu and in game post screen shader! if (BaseGame.UI.PostScreenMenuShader != null) { BaseGame.UI.PostScreenMenuShader.Start(); } // Render background and black bar BaseGame.UI.RenderMenuBackground(); BaseGame.UI.RenderBlackBar(220, 280); // Track header int posX = 10; int posY = 18; if (Environment.OSVersion.Platform != PlatformID.Win32NT) { posX += 36; posY += 26; } BaseGame.UI.Headers.RenderOnScreenRelative1600( posX, posY, UIRenderer.HeaderSelectTrackGfxRect); // Little helper to keep track if mouse is actually over a button. // Required because buttons are selected even when not hovering over // them for GamePad support, but we still want the mouse only to // be apply when we are actually over the button. int mouseIsOverButton = -1; // If the user manipulated the mouse, stop ignoring the mouse // This allows the mouse to override the game pad or keyboard selection if (Input.HasMouseMoved || Input.MouseLeftButtonJustPressed) { ignoreMouse = false; } // Show buttons // Part 1: Calculate global variables for our buttons Rectangle activeRect = BaseGame.CalcRectangleCenteredWithGivenHeight( 0, 0, ActiveButtonWidth * ButtonRects[0].Height / ButtonRects[0].Width, ButtonRects[0]); Rectangle inactiveRect = BaseGame.CalcRectangleCenteredWithGivenHeight( 0, 0, InactiveButtonWidth * ButtonRects[0].Height / ButtonRects[0].Width, ButtonRects[0]); int totalWidth = activeRect.Width + 2 * inactiveRect.Width + 2 * BaseGame.XToRes(DistanceBetweenButtons); int xPos = BaseGame.XToRes(512) - totalWidth / 2; int yPos = BaseGame.YToRes(258); for (int num = 0; num < NumberOfButtons; num++) { // Is this button currently selected? bool selected = num == selectedButton; // Increase size if selected, decrease otherwise currentButtonSizes[num] += (selected ? 1 : -1) * BaseGame.MoveFactorPerSecond * 2; if (currentButtonSizes[num] < 0) { currentButtonSizes[num] = 0; } if (currentButtonSizes[num] > 1) { currentButtonSizes[num] = 1; } Rectangle thisRect = MainMenu. InterpolateRect(activeRect, inactiveRect, currentButtonSizes[num]); Rectangle renderRect = new Rectangle( xPos, yPos - (thisRect.Height - inactiveRect.Height) / 2, thisRect.Width, thisRect.Height); BaseGame.UI.Buttons.RenderOnScreen(renderRect, ButtonRects[num], selected ? Color.White : new Color(192, 192, 192, 192)); // Add border effect if selected if (selected) { BaseGame.UI.Buttons.RenderOnScreen(renderRect, UIRenderer.TrackButtonSelectionGfxRect); } // Also add text below button Rectangle textRenderRect = new Rectangle( xPos, renderRect.Bottom + BaseGame.YToRes(5), renderRect.Width, renderRect.Height * TextRects[0].Height / ButtonRects[0].Height); if (selected) { BaseGame.UI.Buttons.RenderOnScreen(textRenderRect, TextRects[num], selected ? Color.White : Color.Gray); } // Also check if the user hovers with the mouse over this button if (Input.MouseInBox(renderRect)) { mouseIsOverButton = num; } xPos += thisRect.Width + BaseGame.XToRes(DistanceBetweenButtons); } if (!ignoreMouse && mouseIsOverButton >= 0) { selectedButton = mouseIsOverButton; } // Handle GamePad input, and also allow keyboard input if (Input.GamePadLeftJustPressed || Input.KeyboardLeftJustPressed) { Sound.Play(Sound.Sounds.ButtonClick); selectedButton = (selectedButton + NumberOfButtons - 1) % NumberOfButtons; ignoreMouse = true; } else if (Input.GamePadRightJustPressed || Input.KeyboardRightJustPressed) { Sound.Play(Sound.Sounds.ButtonClick); selectedButton = (selectedButton + 1) % NumberOfButtons; ignoreMouse = true; } bool aButtonPressed = BaseGame.UI.RenderBottomButtons(false); // If user presses the mouse button or the game pad A or Space, // start the game screen for the currently selected game part. if ((mouseIsOverButton >= 0 && Input.MouseLeftButtonJustPressed) || aButtonPressed || Input.GamePadAJustPressed || Input.KeyboardSpaceJustPressed) { // Track selection is handled through SelectedTrackNumber RacingGameManager.AddGameScreen(new GameScreen()); } if (Input.KeyboardEscapeJustPressed || Input.GamePadBJustPressed || Input.GamePadBackJustPressed || BaseGame.UI.backButtonPressed) { return(true); } return(false); }
public void Awake() { RacingGameManager = GameObject.FindGameObjectWithTag("MinigameManager").GetComponent <RacingGameManager>(); }
/// <summary> /// Create landscape. /// This constructor should only be called /// from the RacingGame main class! /// </summary> /// <param name="setLevel">Level we want to load</param> internal Landscape(RacingGameManager.Level setLevel) { #region Load map height data Stream file = TitleContainer.OpenStream( "Content\\LandscapeHeights.data"); byte[] heights = new byte[GridWidth * GridHeight]; file.Read(heights, 0, GridWidth * GridHeight); file.Close(); mapHeights = new float[GridWidth, GridHeight]; #endregion #region Build tangent vertices // Build our tangent vertices for (int x = 0; x < GridWidth; x++) for (int y = 0; y < GridHeight; y++) { // Step 1: Calculate position int index = x + y * GridWidth; Vector3 pos = CalcLandscapePos(x, y, heights);//texData); mapHeights[x, y] = pos.Z; vertices[index].pos = pos; //if (x == 0) // Log.Write("vertices " + y + ": " + pos); // Step 2: Calculate all edge vectors (for normals and tangents) // This involves quite complicated optimizations and mathematics, // hard to explain with just a comment. Read my book :D Vector3 edge1 = pos - CalcLandscapePos(x, y + 1, heights); Vector3 edge2 = pos - CalcLandscapePos(x + 1, y, heights); Vector3 edge3 = pos - CalcLandscapePos(x - 1, y + 1, heights); Vector3 edge4 = pos - CalcLandscapePos(x + 1, y + 1, heights); Vector3 edge5 = pos - CalcLandscapePos(x - 1, y - 1, heights); // Step 3: Calculate normal based on the edges (interpolate // from 3 cross products we build from our edges). vertices[index].normal = Vector3.Normalize( Vector3.Cross(edge2, edge1) + Vector3.Cross(edge4, edge3) + Vector3.Cross(edge3, edge5)); // Step 4: Set tangent data, just use edge1 vertices[index].tangent = Vector3.Normalize(edge1); // Step 5: Set texture coordinates, use full 0.0f to 1.0f range! vertices[index].uv = new Vector2( //x / (float)(GridWidth - 1), //y / (float)(GridHeight - 1)); y / (float)(GridHeight - 1), x / (float)(GridWidth - 1)); } #endregion #region Smooth normals // Smooth all normals, first copy them over, then smooth everything Vector3[,] normalsForSmoothing = new Vector3[GridWidth, GridHeight]; for (int x = 0; x < GridWidth; x++) for (int y = 0; y < GridHeight; y++) { int index = x + y * GridWidth; normalsForSmoothing[x, y] = vertices[index].normal; } // Time to smooth to normals we just saved for (int x = 1; x < GridWidth - 1; x++) for (int y = 1; y < GridHeight - 1; y++) { int index = x + y * GridWidth; // Smooth 3x3 normals, but still use old normal to 40% (5 of 13) Vector3 normal = vertices[index].normal * 4; for (int xAdd = -1; xAdd <= 1; xAdd++) for (int yAdd = -1; yAdd <= 1; yAdd++) normal += normalsForSmoothing[x + xAdd, y + yAdd]; vertices[index].normal = Vector3.Normalize(normal); // Also recalculate tangent to let it stay 90 degrees on the normal Vector3 helperVector = Vector3.Cross( vertices[index].normal, vertices[index].tangent); vertices[index].tangent = Vector3.Cross( helperVector, vertices[index].normal); } #endregion #region Set vertex buffer // Set vertex buffer // fix //vertexBuffer = new VertexBuffer( // BaseGame.Device, // typeof(TangentVertex), // vertices.Length, // ResourceUsage.WriteOnly, // ResourceManagementMode.Automatic); //vertexBuffer.SetData(vertices); vertexBuffer = new VertexBuffer( BaseGame.Device, typeof(TangentVertex), vertices.Length, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); #endregion #region Calc index buffer // Calc index buffer (Note: have to use uint, ushort is not sufficiant // in our case because we have MANY vertices ^^) uint[] indices = new uint[(GridWidth - 1) * (GridHeight - 1) * 6]; int currentIndex = 0; for (int x = 0; x < GridWidth - 1; x++) for (int y = 0; y < GridHeight - 1; y++) { // Set landscape data (Note: Right handed) indices[currentIndex + 0] = (uint)(x * GridHeight + y); indices[currentIndex + 2] = (uint)((x + 1) * GridHeight + (y + 1)); indices[currentIndex + 1] = (uint)((x + 1) * GridHeight + y); indices[currentIndex + 3] = (uint)((x + 1) * GridHeight + (y + 1)); indices[currentIndex + 5] = (uint)(x * GridHeight + y); indices[currentIndex + 4] = (uint)(x * GridHeight + (y + 1)); // Add indices currentIndex += 6; } #endregion #region Set index buffer // fix //indexBuffer = new IndexBuffer( // BaseGame.Device, // typeof(uint), // (GridWidth - 1) * (GridHeight - 1) * 6, // ResourceUsage.WriteOnly, // ResourceManagementMode.Automatic); indexBuffer = new IndexBuffer( BaseGame.Device, typeof(uint), (GridWidth - 1) * (GridHeight - 1) * 6, BufferUsage.WriteOnly); indexBuffer.SetData(indices); #endregion #region Load track (and replay inside ReloadLevel method) // Load track based on the level selection and set car pos with // help of the ReloadLevel method. ReloadLevel(setLevel); #endregion #region Add city planes // Just set one giant plane for the whole city! foreach (LandscapeObject obj in landscapeObjects) if (obj.IsBigBuilding) { cityPlane = new PlaneRenderer( obj.Position, new Plane(new Vector3(0, 0, 1), 0.1f), cityMat, Math.Min(obj.Position.X, obj.Position.Y)); break; } #endregion }
/// <summary> /// Render game screen. Called each frame. /// </summary> public bool Render() { #region Background // This starts both menu and in game post screen shader! BaseGame.UI.PostScreenMenuShader.Start(); // Render background and black bar BaseGame.UI.RenderMenuBackground(); // Options header int posX = 10; int posY = 18; if (Environment.OSVersion.Platform != PlatformID.Win32NT) { posX += 36; posY += 26; } BaseGame.UI.Headers.RenderOnScreenRelative1600( posX, posY, UIRenderer.HeaderOptionsGfxRect); // Options background BaseGame.UI.OptionsScreen.RenderOnScreenRelative4To3( 0, 125, BaseGame.UI.OptionsScreen.GfxRectangle); #endregion #region Edit player name // Edit player name int xPos = BaseGame.XToRes(352); int yPos = BaseGame.YToRes768(125 + 65 - 20); TextureFont.WriteText(xPos, yPos, currentPlayerName + // Add blinking | ((int)(BaseGame.TotalTime / 0.35f) % 2 == 0 ? "|" : "")); Input.HandleKeyboardInput(ref currentPlayerName); #endregion #region Select resolution // Select resolution // Use inverted color for selection (see below for sprite blend mode) Color selColor = new Color(255, 156, 0, 160); Rectangle res0Rect = BaseGame.CalcRectangleKeep4To3( Resolution640x480GfxRect); res0Rect.Y += BaseGame.YToRes768(125); bool inRes0Rect = Input.MouseInBox(res0Rect); if (currentResolution == 0) { BaseGame.UI.OptionsScreen.RenderOnScreen( res0Rect, Resolution640x480GfxRect, selColor, BlendState.AlphaBlend); } if (inRes0Rect && Input.MouseLeftButtonJustPressed) { Sound.Play(Sound.Sounds.ButtonClick); currentResolution = 0; } Rectangle res1Rect = BaseGame.CalcRectangleKeep4To3( Resolution800x600GfxRect); res1Rect.Y += BaseGame.YToRes768(125); bool inRes1Rect = Input.MouseInBox(res1Rect); if (currentResolution == 1) { BaseGame.UI.OptionsScreen.RenderOnScreen( res1Rect, Resolution800x600GfxRect, selColor, BlendState.AlphaBlend); } if (inRes1Rect && Input.MouseLeftButtonJustPressed) { Sound.Play(Sound.Sounds.ButtonClick); currentResolution = 1; } Rectangle res2Rect = BaseGame.CalcRectangleKeep4To3( Resolution1024x768GfxRect); res2Rect.Y += BaseGame.YToRes768(125); bool inRes2Rect = Input.MouseInBox(res2Rect); if (currentResolution == 2) { BaseGame.UI.OptionsScreen.RenderOnScreen( res2Rect, Resolution1024x768GfxRect, selColor, BlendState.AlphaBlend); } if (inRes2Rect && Input.MouseLeftButtonJustPressed) { Sound.Play(Sound.Sounds.ButtonClick); currentResolution = 2; } Rectangle res3Rect = BaseGame.CalcRectangleKeep4To3( Resolution1280x1024GfxRect); res3Rect.Y += BaseGame.YToRes768(125); bool inRes3Rect = Input.MouseInBox(res3Rect); if (currentResolution == 3) { BaseGame.UI.OptionsScreen.RenderOnScreen( res3Rect, Resolution1280x1024GfxRect, selColor, BlendState.AlphaBlend); } if (inRes3Rect && Input.MouseLeftButtonJustPressed) { Sound.Play(Sound.Sounds.ButtonClick); currentResolution = 3; } Rectangle res4Rect = BaseGame.CalcRectangleKeep4To3( ResolutionAutoGfxRect); res4Rect.Y += BaseGame.YToRes768(125); bool inRes4Rect = Input.MouseInBox(res4Rect); if (currentResolution == 4) { BaseGame.UI.OptionsScreen.RenderOnScreen( res4Rect, ResolutionAutoGfxRect, selColor, BlendState.AlphaBlend); } if (inRes4Rect && Input.MouseLeftButtonJustPressed) { Sound.Play(Sound.Sounds.ButtonClick); currentResolution = 4; } #endregion #region Graphics options Rectangle fsRect = BaseGame.CalcRectangleKeep4To3( FullscreenGfxRect); fsRect.Y += BaseGame.YToRes768(125); bool inFsRect = Input.MouseInBox(fsRect); if (fullscreen) { BaseGame.UI.OptionsScreen.RenderOnScreen( fsRect, FullscreenGfxRect, selColor, BlendState.AlphaBlend); } if (inFsRect && Input.MouseLeftButtonJustPressed) { Sound.Play(Sound.Sounds.ButtonClick); fullscreen = !fullscreen; } Rectangle pseRect = BaseGame.CalcRectangleKeep4To3( PostScreenEffectsGfxRect); pseRect.Y += BaseGame.YToRes768(125); bool inPseRect = Input.MouseInBox(pseRect); if (usePostScreenShaders) { BaseGame.UI.OptionsScreen.RenderOnScreen( pseRect, PostScreenEffectsGfxRect, selColor, BlendState.AlphaBlend); } if (inPseRect && Input.MouseLeftButtonJustPressed) { Sound.Play(Sound.Sounds.ButtonClick); usePostScreenShaders = !usePostScreenShaders; } Rectangle smRect = BaseGame.CalcRectangleKeep4To3( ShadowsGfxRect); smRect.Y += BaseGame.YToRes768(125); bool inSmRect = Input.MouseInBox(smRect); if (useShadowMapping) { BaseGame.UI.OptionsScreen.RenderOnScreen( smRect, ShadowsGfxRect, selColor, BlendState.AlphaBlend); } if (inSmRect && Input.MouseLeftButtonJustPressed) { Sound.Play(Sound.Sounds.ButtonClick); useShadowMapping = !useShadowMapping; } Rectangle hdRect = BaseGame.CalcRectangleKeep4To3( HighDetailGfxRect); hdRect.Y += BaseGame.YToRes768(125); bool inHdRect = Input.MouseInBox(hdRect); if (useHighDetail) { BaseGame.UI.OptionsScreen.RenderOnScreen( hdRect, HighDetailGfxRect, selColor, BlendState.AlphaBlend); } if (inHdRect && Input.MouseLeftButtonJustPressed) { Sound.Play(Sound.Sounds.ButtonClick); useHighDetail = !useHighDetail; } #endregion #region Sound volume Rectangle soundRect = BaseGame.CalcRectangleKeep4To3( SoundGfxRect); soundRect.Y += BaseGame.YToRes768(125); if (Input.MouseInBox(soundRect)) { if (Input.MouseLeftButtonJustPressed) { currentSoundVolume = (Input.MousePos.X - soundRect.X) / (float)soundRect.Width; Sound.Play(Sound.Sounds.Highlight); } } // Handel controller input if (currentOptionsNumber == 0) { if (Input.GamePadLeftJustPressed || Input.KeyboardLeftJustPressed) { currentSoundVolume -= 0.1f; Sound.Play(Sound.Sounds.Highlight); } if (Input.GamePadRightJustPressed || Input.KeyboardRightJustPressed) { currentSoundVolume += 0.1f; Sound.Play(Sound.Sounds.Highlight); } if (currentSoundVolume < 0) { currentSoundVolume = 0; } if (currentSoundVolume > 1) { currentSoundVolume = 1; } } // Render slider handle Rectangle gfxRect = UIRenderer.SelectionRadioButtonGfxRect; BaseGame.UI.Buttons.RenderOnScreen(new Rectangle( soundRect.X + (int)(soundRect.Width * currentSoundVolume) - BaseGame.XToRes(gfxRect.Width) / 2, soundRect.Y, BaseGame.XToRes(gfxRect.Width), BaseGame.YToRes768(gfxRect.Height)), gfxRect); #endregion #region Music volume Rectangle musicRect = BaseGame.CalcRectangleKeep4To3( MusicGfxRect); musicRect.Y += BaseGame.YToRes768(125); if (Input.MouseInBox(musicRect)) { if (Input.MouseLeftButtonJustPressed) { currentMusicVolume = (Input.MousePos.X - musicRect.X) / (float)musicRect.Width; Sound.Play(Sound.Sounds.Highlight); } } // Handel controller input if (currentOptionsNumber == 1) { if (Input.GamePadLeftJustPressed || Input.KeyboardLeftJustPressed) { currentMusicVolume -= 0.1f; Sound.Play(Sound.Sounds.Highlight); } if (Input.GamePadRightJustPressed || Input.KeyboardRightJustPressed) { currentMusicVolume += 0.1f; Sound.Play(Sound.Sounds.Highlight); } if (currentMusicVolume < 0) { currentMusicVolume = 0; } if (currentMusicVolume > 1) { currentMusicVolume = 1; } } // Render slider handle BaseGame.UI.Buttons.RenderOnScreen(new Rectangle( musicRect.X + (int)(musicRect.Width * currentMusicVolume) - BaseGame.XToRes(gfxRect.Width) / 2, musicRect.Y, BaseGame.XToRes(gfxRect.Width), BaseGame.YToRes768(gfxRect.Height)), gfxRect); #endregion Sound.SetVolumes(currentSoundVolume, currentMusicVolume); #region Controller sensitivity Rectangle sensitivityRect = BaseGame.CalcRectangleKeep4To3( SensitivityGfxRect); sensitivityRect.Y += BaseGame.YToRes768(125); if (Input.MouseInBox(sensitivityRect)) { if (Input.MouseLeftButtonJustPressed) { currentSensitivity = (Input.MousePos.X - sensitivityRect.X) / (float)sensitivityRect.Width; Sound.Play(Sound.Sounds.Highlight); } } // Handel controller input if (currentOptionsNumber == 2) { if (Input.GamePadLeftJustPressed || Input.KeyboardLeftJustPressed) { currentSensitivity -= 0.1f; Sound.Play(Sound.Sounds.Highlight); } if (Input.GamePadRightJustPressed || Input.KeyboardRightJustPressed) { currentSensitivity += 0.1f; Sound.Play(Sound.Sounds.Highlight); } if (currentSensitivity < 0) { currentSensitivity = 0; } if (currentSensitivity > 1) { currentSensitivity = 1; } } // Render slider handle BaseGame.UI.Buttons.RenderOnScreen(new Rectangle( sensitivityRect.X + (int)(sensitivityRect.Width * currentSensitivity) - BaseGame.XToRes(gfxRect.Width) / 2, sensitivityRect.Y, BaseGame.XToRes(gfxRect.Width), BaseGame.YToRes768(gfxRect.Height)), gfxRect); #endregion #region Show selected line Rectangle[] lineArrowGfxRects = new Rectangle[] { Line4ArrowGfxRect, Line5ArrowGfxRect, Line6ArrowGfxRect, }; for (int num = 0; num < lineArrowGfxRects.Length; num++) { Rectangle lineRect = BaseGame.CalcRectangleKeep4To3( lineArrowGfxRects[num]); lineRect.Y += BaseGame.YToRes768(125); lineRect.X -= BaseGame.XToRes(8 + (int)Math.Round(8 * Math.Sin(BaseGame.TotalTime / 0.21212f))); // Draw selection arrow if (currentOptionsNumber == num) { BaseGame.UI.Buttons.RenderOnScreen( lineRect, UIRenderer.SelectionArrowGfxRect, Color.White); } } // Game pad selection if (Input.GamePadUpJustPressed || Input.KeyboardUpJustPressed) { Sound.Play(Sound.Sounds.Highlight); currentOptionsNumber = (lineArrowGfxRects.Length + currentOptionsNumber - 1) % lineArrowGfxRects.Length; } else if (Input.GamePadDownJustPressed || Input.KeyboardDownJustPressed) { Sound.Play(Sound.Sounds.Highlight); currentOptionsNumber = (currentOptionsNumber + 1) % lineArrowGfxRects.Length; } #endregion #region Bottom buttons //*** Added booth mode screen flow bool aButtonPressed = BaseGame.UI.RenderBottomButtons(!GameSettings.BoothMode); if ((Input.GamePadAJustPressed || //Input.KeyboardSpaceJustPressed || aButtonPressed) && GameSettings.BoothMode && !string.IsNullOrEmpty(currentPlayerName)) { //RacingGameManager.AddGameScreen(new CarSelection()); GameSettings.Default.PlayerName = currentPlayerName; RacingGameManager.AddGameScreen(new GameScreen()); switch (currentResolution) { case 0: GameSettings.Default.ResolutionWidth = 640; GameSettings.Default.ResolutionHeight = 480; break; case 1: GameSettings.Default.ResolutionWidth = 800; GameSettings.Default.ResolutionHeight = 600; break; case 2: GameSettings.Default.ResolutionWidth = 1024; GameSettings.Default.ResolutionHeight = 768; break; case 3: GameSettings.Default.ResolutionWidth = 1280; GameSettings.Default.ResolutionHeight = 1024; break; case 4: // Try to use best resolution available GameSettings.Default.ResolutionWidth = 0; GameSettings.Default.ResolutionHeight = 0; break; } GameSettings.Default.Fullscreen = fullscreen; GameSettings.Default.PostScreenEffects = usePostScreenShaders; GameSettings.Default.ShadowMapping = useShadowMapping; GameSettings.Default.HighDetail = useHighDetail; GameSettings.Default.MusicVolume = currentMusicVolume; GameSettings.Default.SoundVolume = currentSoundVolume; GameSettings.Default.ControllerSensitivity = currentSensitivity; // Save all GameSettings.Save(); // Update game settings BaseGame.CheckOptionsAndPSVersion(); } #endregion #region Apply settings when quitting if (Input.KeyboardEscapeJustPressed || Input.GamePadBJustPressed || Input.GamePadBackJustPressed || BaseGame.UI.backButtonPressed) { // Apply settings, for xbox only set music/sound and sensitivity! GameSettings.Default.PlayerName = currentPlayerName; switch (currentResolution) { case 0: GameSettings.Default.ResolutionWidth = 640; GameSettings.Default.ResolutionHeight = 480; break; case 1: GameSettings.Default.ResolutionWidth = 800; GameSettings.Default.ResolutionHeight = 600; break; case 2: GameSettings.Default.ResolutionWidth = 1024; GameSettings.Default.ResolutionHeight = 768; break; case 3: GameSettings.Default.ResolutionWidth = 1280; GameSettings.Default.ResolutionHeight = 1024; break; case 4: // Try to use best resolution available GameSettings.Default.ResolutionWidth = 0; GameSettings.Default.ResolutionHeight = 0; break; } GameSettings.Default.Fullscreen = fullscreen; GameSettings.Default.PostScreenEffects = usePostScreenShaders; GameSettings.Default.ShadowMapping = useShadowMapping; GameSettings.Default.HighDetail = useHighDetail; GameSettings.Default.MusicVolume = currentMusicVolume; GameSettings.Default.SoundVolume = currentSoundVolume; GameSettings.Default.ControllerSensitivity = currentSensitivity; // Save all GameSettings.Save(); // Update game settings BaseGame.CheckOptionsAndPSVersion(); return(true); } #endregion return(false); }