} // RocketCommanderXnaGame() /// <summary> /// Initialize textures and models for the game. /// </summary> protected override void Initialize() { base.Initialize(); // Load all available levels levels = Level.LoadAllLevels(); // Initialize asteroidManager and use last avialable level. asteroidManager = new GameAsteroidManager(levels[levels.Length - 1]); rocketModel = new Model("Rocket"); // Load menu textures mainMenuTexture = new Texture("MainMenu.png"); helperTexture = new Texture("ExtraButtons.png"); helpScreenTexture = new Texture("HelpScreen.png"); mouseCursorTexture = new Texture("MouseCursor.dds"); hudTexture = new Texture("Hud.png"); inGameTexture = new Texture("InGame.png"); lightEffectTexture = new Texture("LightEffect.dds"); explosionTexture = new AnimatedTexture("Explosion"); // Create main menu screen gameScreens.Push(new MainMenu()); //tst: //gameScreens.Push(new Mission(levels[0], asteroidManager)); //inGame = gameScreens.Peek().GetType() == typeof(Mission); //camera.InGame = inGame; } // Initialize()
} // ResetParameters() #endregion #region Get parameters /// <summary> /// Reload /// </summary> protected void GetParameters() { // Can't get parameters if loading failed! if (effect == null) { return; } windowSize = effect.Parameters["windowSize"]; sceneMap = effect.Parameters["sceneMap"]; // We need both windowSize and sceneMap. if (windowSize == null || sceneMap == null) { throw new NotSupportedException("windowSize and sceneMap must be " + "valid in PostScreenShader=" + Filename); } // Init additional stuff downsampleMap = effect.Parameters["downsampleMap"]; blurMap1 = effect.Parameters["blurMap1"]; blurMap2 = effect.Parameters["blurMap2"]; radialSceneMap = effect.Parameters["radialSceneMap"]; // Load screen border texture screenBorderFadeoutMap = effect.Parameters["screenBorderFadeoutMap"]; screenBorderFadeoutMapTexture = new Texture("ScreenBorderFadeout.dds"); // Set texture screenBorderFadeoutMap.SetValue( screenBorderFadeoutMapTexture.XnaTexture); // Glow shader lookup texture must exists (used for ps2.0) if (File.Exists(Directories.ContentDirectory + "\\GlowShaderLookup.xnb")) { radialBlurScaleFactor = effect.Parameters["radialBlurScaleFactor"]; // Load GlowShader helper texture, only used for ps_2_0 EffectParameter glowShaderLookup = effect.Parameters["GlowShaderLookup"]; if (glowShaderLookup != null) { glowShaderLookup.SetValue( new Texture("GlowShaderLookup.dds").XnaTexture); } // if (normalizeCubeTexture) } // if (Glow shader lookup texture must exists) } // GetParameters()
/// <summary> /// Create asteroid manager /// </summary> public GameAsteroidManager(Level setLevel) : base(setLevel) { // Load all items for (int num = 0; num < Level.NumOfItemTypes; num++) { // All items are animated, load with help of AnimatedModel. itemModels[num] = new AnimatedModel(ItemModelFilenames[num]); } // for (num) // Load hit direction texture hitDirectionTexture = new Texture("HitDirection.dds"); // Load goal model goalModel = new Model("Goal"); } // AsteroidManager()
} // IsVisible(point) #endregion #region Occlusion testing (not supported in XNA) /// <summary> /// Occlusion intensity /// </summary> /// <param name="tex">Tex</param> /// <param name="pos">Position</param> /// <param name="size">Size</param> /// <returns>Float</returns> public static float OcclusionIntensity(Texture tex, Point pos, int size) { return 0.0f; } // OcclusionIntensity(tex, pos, size)
/// <summary> /// Run game screen. Called each frame. /// </summary> /// <param name="game">Form for access to asteroid manager and co</param> public void Run(RocketCommanderGame game) { // Make sure the textures are linked correctly hudTexture = game.hudTexture; inGameTexture = game.inGameTexture; levelTexture = game.asteroidManager.CurrentLevel.Texture; // Enable alpha blending for all controls BaseGame.EnableAlphaBlending(); // Zoom into rocket for countdown time ZoomIntoRocket(RocketCommanderGame.camera, game.rocketModel); // Show target in z direction, it is very far away. ShowTarget(game.asteroidManager.CurrentLevel.Length); // Show on screen effects like explosion or item screen border colors. ShowOnScreenEffects(game.explosionTexture); // Always show hit direction effect if it is active (similar to screen // effects always on top). game.asteroidManager.ShowHitDirectionEffect(); // Show all hud controls // Don't display them in low resolution, we can't display any useful // information anyway. //obs, always display, is streched now: if (BaseGame.Width >= 640) ShowHudControls(); // Handle game stuff Player.HandleGameLogic(game.asteroidManager); // Show on screen helper messages ShowScreenMessages(game.asteroidManager); // End game if escape was pressed or game is over and space or mouse // button was pressed. if (Input.KeyboardEscapeJustPressed || Input.GamePadBackJustPressed || (Player.GameOver && (Input.Keyboard.IsKeyDown(Keys.Space) || Input.GamePadAPressed || Input.GamePadBPressed || Input.GamePadXPressed || Input.GamePadXPressed || Input.MouseLeftButtonPressed))) { // Upload new highscore (as we currently are in game, // no bonus or anything will be added, this score is low!) Player.SetGameOverAndUploadHighscore(); // Stop rocket sound if it still playing Sound.StopRocketMotorSound(); // Reset camera to origin and notify we are not longer in game mode RocketCommanderGame.camera.SetPosition(Vector3.Zero); RocketCommanderGame.camera.InGame = false; // Quit to the main menu quit = true; } // if }
/// <summary> /// Render, most performance critical method of the game. /// Renders all asteroids and handles all physics, updating, etc. /// We use instancing to speed up asteroid rendering! /// </summary> public void Render(Texture inGameTexture, Texture lightEffectTexture) { #region Initialize // Use alpha blending for blending out asteroids BaseGame.EnableAlphaBlending(); // Get camera position, no need to call the property 1 mio times. Vector3 cameraPos = BaseGame.CameraPos; // Empty display distance list remToDisplayDistance.Clear(); #endregion #region Show target behind asteroids // Show target icon behind all asteroids and items (only in game) if (inGameTexture != null) { // First find out where the target is. Point screenPos = BaseGame.Convert3DPointTo2D(TargetPosition); bool isVisible = BaseGame.IsInFrontOfCamera(TargetPosition); if (isVisible && screenPos.X >= 0 && screenPos.X < BaseGame.Width && screenPos.Y >= 0 && screenPos.Y < BaseGame.Height) { // From Mission.cs:70. Rectangle TargetIconRect = new Rectangle(106, 49, 61, 61); // Render target icon centered at screenPos // Note: This will be blurred because we render it before // the glow/bloom/motion blur shader is applied, but if we // render after that we can't render behind the asteroids. // See Mission.RenderTarget! inGameTexture.RenderOnScreen(new Rectangle( screenPos.X - TargetIconRect.Width / 2, screenPos.Y - TargetIconRect.Height / 2, TargetIconRect.Width, TargetIconRect.Height), TargetIconRect, Color.White, SpriteBlendMode.Additive); } // if (isVisible) } // if (inGameTexture) #endregion #region Show glow behind items // Show glow behind all items for (int num = 0; num < Level.NumOfItemTypes; num++) { // Go through all items of this type foreach (Vector3 pos in items[num]) { // Get distance to viewer float distance = (pos - cameraPos).Length(); // Skip if out of visible range * 6 if (distance > MaxViewDepth * 6 || BaseGame.IsInFrontOfCamera(pos) == false) continue; // Convert to screen coordinates Point screenPos = BaseGame.Convert3DPointTo2D(pos); int glowSize = 36 * BaseGame.Width / 1024; // If not visible, skip! if (screenPos.X < -glowSize || screenPos.Y < -glowSize || screenPos.X > BaseGame.Width + glowSize || screenPos.Y > BaseGame.Height + glowSize) continue; // Calculate alpha float alpha = 1.0f; if (distance > MaxViewDepth * 4) alpha = 1.0f - ((distance - MaxViewDepth * 4) / (MaxViewDepth * (6 - 4))); // Show glow with help of light effect if (lightEffectTexture != null) lightEffectTexture.RenderOnScreen( new Rectangle(screenPos.X - glowSize, screenPos.Y - glowSize, glowSize * 2, glowSize * 2), lightEffectTexture.GfxRectangle, ColorHelper.ApplyAlphaToColor(ItemColors[num], alpha * 0.5f), SpriteBlendMode.Additive); // And display distance to item below it (not here, see below). float textAlpha = alpha * 1.5f * (1.0f - (distance / (MaxViewDepth * 6))); AddDistanceToBeDisplayed(screenPos, distance, textAlpha < 1.0f ? textAlpha : 1.0f); } // foreach (pos) } // for (num) // Flush all glow sprites on the screen (before rendering asteroids!) SpriteHelper.DrawSprites(); #endregion #region Render 3d models, especially the asteroids // Draw goal at target position goalModel.Render(Matrix.CreateScale(100) * Matrix.CreateRotationX(-(float)Math.PI / 2.0f) * Matrix.CreateTranslation(TargetPosition)); // Call base render method, target and item glow is behind of the // asteroids. base.RenderAsteroids(); #endregion }
/// <summary> /// Create asteroid manager /// </summary> public GameAsteroidManager(Level setLevel) : base(setLevel) { // Load all items for (int num = 0; num < Level.NumOfItemTypes; num++) { // All items are animated, load with help of AnimatedModel. itemModels[num] = new AnimatedModel(ItemModelFilenames[num]); } // for (num) // Load hit direction texture hitDirectionTexture = new Texture("HitDirection.dds"); // Load goal model goalModel = new Model("Goal"); }
/// <summary> /// Load level, only allowed internally (by LoadAllLevels) /// </summary> /// <param name="fullFilename">Full path to level file</param> private Level(string fullFilename) { // Set level name, also used to upload highscore. name = StringHelper.ExtractFilename(fullFilename, true); // Load level //old: Bitmap levelBmp = new Bitmap(fullFilename); FileStream file = File.OpenRead("Content\\" + StringHelper.ExtractFilename(fullFilename, true) + ".level"); BinaryReader reader = new BinaryReader(file); width = reader.ReadInt32(); int height = reader.ReadInt32(); Color[,] levelColors = new Color[width, height]; for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) { byte r = reader.ReadByte(); byte g = reader.ReadByte(); byte b = reader.ReadByte(); levelColors[x, y] = new Color(r, g, b); } // for for file.Close(); // Load texture texture = new Texture(//"..\\Levels\\" + StringHelper.ExtractFilename(fullFilename, true)); // Copy over level height as length, but always use 20 as the levelWidth. // We will use all pixels at 0-39 and scale them down to 0-19. width = DefaultLevelWidth; length = height;// levelBmp.Height; // Initialize density array, used to generate sectors density = new float[width, length]; // Also load sun colors sunColor = new Color[length]; // Remember last density value in case we hit a item color, // this way we can set both the density and put the item into its list. float lastDensityValue = 0.0f; // Load everything in as 0-1 density values for (int y = 0; y < length; y++) { // Use inverted y position for the level, we start at the bottom. int yPos = length - (y + 1); // Load level data for (int x = 0; x < width; x++) { // Note: This is slow by using GetPixel, unsafe pointer handling // is much faster, but I didn't want to force you using unsafe. // In any other project I would use unsafe pointer code. // Profiler: This takes around 1 second for 4 levels to load, // with unsafe pointers we could optimize that up to 4 times faster. //Note: Invert x because our rendering is different from the // original RC code, righthanded messes everything up. Color loadedColor = levelColors[(width * 2 -1)-(x * 2), y]; Color loadedColor2 = levelColors[(width * 2 -1)-(x * 2 + 1), y]; float densityValue = lastDensityValue; // Check if it is any item color if (ColorHelper.SameColor(loadedColor, FuelItemColor) || ColorHelper.SameColor(loadedColor2, FuelItemColor)) items[FuelItemType].Add(GenerateItemPosition(x, yPos)); else if (ColorHelper.SameColor(loadedColor, HealthItemColor) || ColorHelper.SameColor(loadedColor2, HealthItemColor)) items[HealthItemType].Add(GenerateItemPosition(x, yPos)); else if (ColorHelper.SameColor(loadedColor, ExtraLifeItemColor) || ColorHelper.SameColor(loadedColor2, ExtraLifeItemColor)) items[ExtraLifeItemType].Add(GenerateItemPosition(x, yPos)); else if (ColorHelper.SameColor(loadedColor, SpeedItemColor) || ColorHelper.SameColor(loadedColor2, SpeedItemColor)) items[SpeedItemType].Add(GenerateItemPosition(x, yPos)); else if (ColorHelper.SameColor(loadedColor, BombItemColor) || ColorHelper.SameColor(loadedColor2, BombItemColor)) items[BombItemType].Add(GenerateItemPosition(x, yPos)); else // Just use the red component, should be a gray value anyway. densityValue = (float)loadedColor.R / 255.0f; // Apply density density[x, yPos] = densityValue; } // for (int) // Load sun color at this level position (just read pixel at x pos 50) sunColor[yPos] = levelColors[50, y]; } // for (int) // Finished! }
/// <summary> /// Initialize textures and models for the game. /// </summary> protected override void Initialize() { base.Initialize(); // Load all available levels levels = Level.LoadAllLevels(); // Initialize asteroidManager and use last avialable level. asteroidManager = new GameAsteroidManager(levels[levels.Length - 1]); rocketModel = new Model("Rocket"); // Load menu textures mainMenuTexture = new Texture("MainMenu.png"); helperTexture = new Texture("ExtraButtons.png"); helpScreenTexture = new Texture("HelpScreen.png"); mouseCursorTexture = new Texture("MouseCursor.dds"); hudTexture = new Texture("Hud.png"); inGameTexture = new Texture("InGame.png"); lightEffectTexture = new Texture("LightEffect.dds"); explosionTexture = new AnimatedTexture("Explosion"); // Create main menu screen gameScreens.Push(new MainMenu()); //tst: //gameScreens.Push(new Mission(levels[0], asteroidManager)); //inGame = gameScreens.Peek().GetType() == typeof(Mission); //camera.InGame = inGame; }
} // ShowAllItems(useShader) #endregion #region Render /// <summary> /// Render, most performance critical method of the game. /// Renders all asteroids and handles all physics, updating, etc. /// We use instancing to speed up asteroid rendering! /// </summary> public void Render(Texture inGameTexture, Texture lightEffectTexture) { #region Initialize // Use alpha blending for blending out asteroids BaseGame.EnableAlphaBlending(); // Get camera position, no need to call the property 1 mio times. Vector3 cameraPos = BaseGame.CameraPos; // Empty display distance list remToDisplayDistance.Clear(); #endregion #region Show target behind asteroids // Show target icon behind all asteroids and items (only in game) if (inGameTexture != null) { // First find out where the target is. Point screenPos = BaseGame.Convert3DPointTo2D(TargetPosition); bool isVisible = BaseGame.IsInFrontOfCamera(TargetPosition); if (isVisible && screenPos.X >= 0 && screenPos.X < BaseGame.Width && screenPos.Y >= 0 && screenPos.Y < BaseGame.Height) { // From Mission.cs:70. Rectangle TargetIconRect = new Rectangle(106, 49, 61, 61); // Render target icon centered at screenPos // Note: This will be blurred because we render it before // the glow/bloom/motion blur shader is applied, but if we // render after that we can't render behind the asteroids. // See Mission.RenderTarget! inGameTexture.RenderOnScreen(new Rectangle( screenPos.X - TargetIconRect.Width / 2, screenPos.Y - TargetIconRect.Height / 2, TargetIconRect.Width, TargetIconRect.Height), TargetIconRect, Color.White, SpriteBlendMode.Additive); } // if (isVisible) } // if (inGameTexture) #endregion #region Show glow behind items // Show glow behind all items for (int num = 0; num < Level.NumOfItemTypes; num++) { // Go through all items of this type foreach (Vector3 pos in items[num]) { // Get distance to viewer float distance = (pos - cameraPos).Length(); // Skip if out of visible range * 6 if (distance > MaxViewDepth * 6 || BaseGame.IsInFrontOfCamera(pos) == false) { continue; } // Convert to screen coordinates Point screenPos = BaseGame.Convert3DPointTo2D(pos); int glowSize = 36 * BaseGame.Width / 1024; // If not visible, skip! if (screenPos.X < -glowSize || screenPos.Y < -glowSize || screenPos.X > BaseGame.Width + glowSize || screenPos.Y > BaseGame.Height + glowSize) { continue; } // Calculate alpha float alpha = 1.0f; if (distance > MaxViewDepth * 4) { alpha = 1.0f - ((distance - MaxViewDepth * 4) / (MaxViewDepth * (6 - 4))); } // Show glow with help of light effect if (lightEffectTexture != null) { lightEffectTexture.RenderOnScreen( new Rectangle(screenPos.X - glowSize, screenPos.Y - glowSize, glowSize * 2, glowSize * 2), lightEffectTexture.GfxRectangle, ColorHelper.ApplyAlphaToColor(ItemColors[num], alpha * 0.5f), SpriteBlendMode.Additive); } // And display distance to item below it (not here, see below). float textAlpha = alpha * 1.5f * (1.0f - (distance / (MaxViewDepth * 6))); AddDistanceToBeDisplayed(screenPos, distance, textAlpha < 1.0f ? textAlpha : 1.0f); } // foreach (pos) } // for (num) // Flush all glow sprites on the screen (before rendering asteroids!) SpriteHelper.DrawSprites(); #endregion #region Render 3d models, especially the asteroids // Draw goal at target position goalModel.Render(Matrix.CreateScale(100) * Matrix.CreateRotationX(-(float)Math.PI / 2.0f) * Matrix.CreateTranslation(TargetPosition)); // Call base render method, target and item glow is behind of the // asteroids. base.RenderAsteroids(); #endregion } // Render()
/// <summary> /// Reload /// </summary> protected void GetParameters() { // Can't get parameters if loading failed! if (effect == null) return; windowSize = effect.Parameters["windowSize"]; sceneMap = effect.Parameters["sceneMap"]; // We need both windowSize and sceneMap. if (windowSize == null || sceneMap == null) throw new NotSupportedException("windowSize and sceneMap must be " + "valid in PostScreenShader=" + Filename); // Init additional stuff downsampleMap = effect.Parameters["downsampleMap"]; blurMap1 = effect.Parameters["blurMap1"]; blurMap2 = effect.Parameters["blurMap2"]; radialSceneMap = effect.Parameters["radialSceneMap"]; // Load screen border texture screenBorderFadeoutMap = effect.Parameters["screenBorderFadeoutMap"]; screenBorderFadeoutMapTexture = new Texture("ScreenBorderFadeout.dds"); // Set texture screenBorderFadeoutMap.SetValue( screenBorderFadeoutMapTexture.XnaTexture); // Glow shader lookup texture must exists (used for ps2.0) if (File.Exists(Directories.ContentDirectory + "\\GlowShaderLookup.xnb")) { radialBlurScaleFactor = effect.Parameters["radialBlurScaleFactor"]; // Load GlowShader helper texture, only used for ps_2_0 EffectParameter glowShaderLookup = effect.Parameters["GlowShaderLookup"]; if (glowShaderLookup != null) { glowShaderLookup.SetValue( new Texture("GlowShaderLookup.dds").XnaTexture); } // if (normalizeCubeTexture) } // if (Glow shader lookup texture must exists) }
} // GenerateItemPosition(xPos, zPos) #endregion #region Constructor /// <summary> /// Load level, only allowed internally (by LoadAllLevels) /// </summary> /// <param name="fullFilename">Full path to level file</param> private Level(string fullFilename) { // Set level name, also used to upload highscore. name = StringHelper.ExtractFilename(fullFilename, true); // Load level //old: Bitmap levelBmp = new Bitmap(fullFilename); FileStream file = File.OpenRead("Content\\" + StringHelper.ExtractFilename(fullFilename, true) + ".level"); BinaryReader reader = new BinaryReader(file); width = reader.ReadInt32(); int height = reader.ReadInt32(); Color[,] levelColors = new Color[width, height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { byte r = reader.ReadByte(); byte g = reader.ReadByte(); byte b = reader.ReadByte(); levelColors[x, y] = new Color(r, g, b); } // for for } file.Close(); // Load texture texture = new Texture( //"..\\Levels\\" + StringHelper.ExtractFilename(fullFilename, true)); // Copy over level height as length, but always use 20 as the levelWidth. // We will use all pixels at 0-39 and scale them down to 0-19. width = DefaultLevelWidth; length = height; // levelBmp.Height; // Initialize density array, used to generate sectors density = new float[width, length]; // Also load sun colors sunColor = new Color[length]; // Remember last density value in case we hit a item color, // this way we can set both the density and put the item into its list. float lastDensityValue = 0.0f; // Load everything in as 0-1 density values for (int y = 0; y < length; y++) { // Use inverted y position for the level, we start at the bottom. int yPos = length - (y + 1); // Load level data for (int x = 0; x < width; x++) { // Note: This is slow by using GetPixel, unsafe pointer handling // is much faster, but I didn't want to force you using unsafe. // In any other project I would use unsafe pointer code. // Profiler: This takes around 1 second for 4 levels to load, // with unsafe pointers we could optimize that up to 4 times faster. //Note: Invert x because our rendering is different from the // original RC code, righthanded messes everything up. Color loadedColor = levelColors[(width * 2 - 1) - (x * 2), y]; Color loadedColor2 = levelColors[(width * 2 - 1) - (x * 2 + 1), y]; float densityValue = lastDensityValue; // Check if it is any item color if (ColorHelper.SameColor(loadedColor, FuelItemColor) || ColorHelper.SameColor(loadedColor2, FuelItemColor)) { items[FuelItemType].Add(GenerateItemPosition(x, yPos)); } else if (ColorHelper.SameColor(loadedColor, HealthItemColor) || ColorHelper.SameColor(loadedColor2, HealthItemColor)) { items[HealthItemType].Add(GenerateItemPosition(x, yPos)); } else if (ColorHelper.SameColor(loadedColor, ExtraLifeItemColor) || ColorHelper.SameColor(loadedColor2, ExtraLifeItemColor)) { items[ExtraLifeItemType].Add(GenerateItemPosition(x, yPos)); } else if (ColorHelper.SameColor(loadedColor, SpeedItemColor) || ColorHelper.SameColor(loadedColor2, SpeedItemColor)) { items[SpeedItemType].Add(GenerateItemPosition(x, yPos)); } else if (ColorHelper.SameColor(loadedColor, BombItemColor) || ColorHelper.SameColor(loadedColor2, BombItemColor)) { items[BombItemType].Add(GenerateItemPosition(x, yPos)); } else { // Just use the red component, should be a gray value anyway. densityValue = (float)loadedColor.R / 255.0f; } // Apply density density[x, yPos] = densityValue; } // for (int) // Load sun color at this level position (just read pixel at x pos 50) sunColor[yPos] = levelColors[50, y]; } // for (int) // Finished! } // Level(fullFilename)