/// <summary> /// creates two cameras and viewports for split-screen. /// </summary> public void InitCamera() { // Make two mutiple cameras ViewCamera followViewCamera = new ViewCamera(); FollowCamera[] followCamera = new FollowCamera[2] { new FollowCamera(), new FollowCamera(), }; int playerCount = GameLevel.PlayerCountInLevel; for (int i = 0; i < playerCount; i++) { GamePlayer player = GameLevel.GetPlayerInLevel(i); followCamera[i].SetPespective( MathHelper.ToRadians(this.GameLevel.Info.FOV), (float)FrameworkCore.ViewWidth, (float)FrameworkCore.ViewHeight / playerCount, 1.0f, 1000.0f); // Follow camera offset position setting followCamera[i].TargetOffset = player.SpecData.CameraTargetOffset; followCamera[i].PositionOffset = player.SpecData.CameraPositionOffset; int splitX = 0; int splitY = 0; int splitWidth = 0; int splitHeight = 0; // 1P viewport area if (i == 0) { splitX = 0; splitY = 0; } // 2P viewport area else if (i == 1) { splitX = 0; splitY = FrameworkCore.ViewHeight / playerCount; } splitWidth = FrameworkCore.ViewWidth; splitHeight = FrameworkCore.ViewHeight / playerCount; followViewCamera.Add(followCamera[i], new Rectangle(splitX, splitY, splitWidth, splitHeight)); } Viewer.AddCamera("Follow", followViewCamera); Viewer.SetCurrentCamera("Follow"); }
/// <summary> /// creates a player character. /// </summary> /// <param name="specFileName">player spec file(.spec)</param> /// <param name="sceneParent">3D scene parent node</param> protected void CreatePlayer(string specFileName, NodeBase sceneParent) { GamePlayerSpec spec = new GamePlayerSpec(); spec = (GamePlayerSpec)GameDataSpecManager.Load(specFileName, spec.GetType()); GamePlayer player = null; switch (GameLevel.PlayerCountInLevel) { case 0: { player = new GamePlayer(ref spec, PlayerIndex.One); RobotGameGame.SinglePlayer = player; FrameworkCore.GameEventManager.TargetScene = player; } break; case 1: { player = new GamePlayer(ref spec, PlayerIndex.Two); } break; default: throw new InvalidOperationException( "Added player count is overflow"); } // Entry enemies in 3D Scene root node sceneParent.AddChild(player); // Create rotation axis Matrix rot = Matrix.CreateRotationX(MathHelper.ToRadians(-90.0f)); player.SetRootAxis(rot); // Set material RenderMaterial material = new RenderMaterial(); material.alpha = 1.0f; material.diffuseColor = new Color(210, 210, 210); material.specularColor = new Color(60, 60, 60); material.emissiveColor = new Color(30, 30, 30); material.specularPower = 24; material.vertexColorEnabled = false; material.preferPerPixelLighting = false; player.Material = material; player.ActiveFog = true; player.ActiveLighting = true; // Create collision data Vector3 centerPos = Vector3.Transform( new Vector3(0.0f, spec.MechRadius, 0.0f), Matrix.Invert(rot)); CollideSphere collide = new CollideSphere(centerPos, spec.MechRadius); player.EnableCulling = true; player.SetCollide(collide); player.ActionIdle(); // Add collide RobotGameGame.CurrentGameLevel.CollisionVersusTeam[ GameLevel.PlayerCountInLevel].AddCollide(collide); RobotGameGame.CurrentGameLevel.CollisionLayerAllMech.AddCollide(collide); // Set the respawn position if (player.PlayerIndex == PlayerIndex.One) { int count = GameLevel.Info.RespawnInLevelList.Count; int rndIndex = HelperMath.Randomi(0, count); RespawnInLevel respawn = GameLevel.Info.RespawnInLevelList[rndIndex]; player.SpawnPoint = Matrix.CreateRotationY(MathHelper.ToRadians(respawn.SpawnAngle)) * Matrix.CreateTranslation(respawn.SpawnPoint); } else if (player.PlayerIndex == PlayerIndex.Two) { GamePlayer gamePlayerOne = GameLevel.GetPlayerInLevel(0); RespawnInLevel respawn = GameLevel.FindRespawnMostFar(gamePlayerOne.SpawnPoint.Translation); player.SpawnPoint = Matrix.CreateRotationY(MathHelper.ToRadians(respawn.SpawnAngle)) * Matrix.CreateTranslation(respawn.SpawnPoint); } GameLevel.AddPlayer(player); }
/// <summary> /// checks the winning condition of the versus play. /// Any player who has destroyed the other as many as the kill point wins. /// </summary> protected override void CheckMission(GameTime gameTime) { if (isFinishedVersus == false) { for (int i = 0; i < GameLevel.PlayerCountInLevel; i++) { GamePlayer player = GameLevel.GetPlayerInLevel(i); // Whoever wins the set points first, the versus mode will end. if (RobotGameGame.VersusGameInfo.killPoint <= player.KillPoint) { isFinishedVersus = true; } } } if (isFinishedVersus) { // Visible mission result image if (missionResultElapsedTime > MissionResultVisibleTime) { this.spriteObjHudVersusWin.Visible = true; this.spriteObjHudVersusLose.Visible = true; } else { if (missionResultElapsedTime < MissionResultVisibleTime) { missionResultElapsedTime += (float)gameTime.ElapsedGameTime.TotalSeconds; } this.spriteObjHudVersusWin.Visible = false; this.spriteObjHudVersusLose.Visible = false; } if (GameSound.IsPlaying(soundBGM)) { float scaleFactor = 1.0f; if (GameLevel.Info.GamePlayType == GamePlayTypeId.Versus) { scaleFactor = 0.8f; } // Scale the image size and position for screen resolution Vector2 sizeScale = new Vector2((float)FrameworkCore.ViewWidth * scaleFactor / (float)ViewerWidth.Width1080, (float)FrameworkCore.ViewHeight * scaleFactor / (float)ViewerHeight.Height1080); for (int i = 0; i < GameLevel.PlayerCountInLevel; i++) { GamePlayer player = GameLevel.GetPlayerInLevel(i); // Player sound and action stop player.MissionEnd(); // Win!! if (RobotGameGame.VersusGameInfo.killPoint <= player.KillPoint) { int scaledWidth = (int)((float)imageWinWidth * sizeScale.X); int scaledHeight = (int)((float)imageWinHeight * sizeScale.Y); int posX = (int)((FrameworkCore.ViewWidth / 2) - (scaledWidth / 2)); int posY = (int)((FrameworkCore.ViewHeight / 2) - (scaledHeight / 2)); if (player.PlayerIndex == PlayerIndex.One) { posY -= FrameworkCore.ViewHeight / 4; } else if (player.PlayerIndex == PlayerIndex.Two) { posY += FrameworkCore.ViewHeight / 4; } this.spriteObjHudVersusWin.ScreenRectangle = new Rectangle( posX, posY, scaledWidth, scaledHeight); } // Lose!! else { int scaledWidth = (int)((float)imageLoseWidth * sizeScale.X); int scaledHeight = (int)((float)imageLoseHeight * sizeScale.Y); int posX = (int)((FrameworkCore.ViewWidth / 2) - (scaledWidth / 2)); int posY = (int)((FrameworkCore.ViewHeight / 2) - (scaledHeight / 2)); if (player.PlayerIndex == PlayerIndex.One) { posY -= FrameworkCore.ViewHeight / 4; } else if (player.PlayerIndex == PlayerIndex.Two) { posY += FrameworkCore.ViewHeight / 4; } this.spriteObjHudVersusLose.ScreenRectangle = new Rectangle( posX, posY, scaledWidth, scaledHeight); } } // Stop background music GameSound.Stop(soundBGM); // Play success music GameSound.Play(SoundTrack.MissionClear); // Invisible all of the Hud SetVisibleHud(false); // Go to main menu NextScreen = new VersusReadyScreen(); TransitionOffTime = TimeSpan.FromSeconds(8.0f); ExitScreen(); } } else { // Respawns a destroyed player in the game. for (int i = 0; i < GameLevel.PlayerCountInLevel; i++) { GamePlayer player = GameLevel.GetPlayerInLevel(i); if (player.IsFinishedDead) { int otherSidePlayerIndex = -1; if (i == 0) { otherSidePlayerIndex = 1; } else if (i == 1) { otherSidePlayerIndex = 0; } GamePlayer otherSidePlayer = GameLevel.GetPlayerInLevel(otherSidePlayerIndex); // Find the farthest positions for enemy positions. RespawnInLevel respawn = GameLevel.FindRespawnMostFar( otherSidePlayer.WorldTransform.Translation); // Set to respawn position player.SpawnPoint = Matrix.CreateRotationY( MathHelper.ToRadians(respawn.SpawnAngle)) * Matrix.CreateTranslation(respawn.SpawnPoint); // Reset the player info player.Reset(true); } } } }
/// <summary> /// calling when screen size has changed. /// changes the sizes of camera and Hud when the screen size is changed. /// </summary> /// <param name="viewRect">new view area</param> public override void OnSize(Rectangle newRect) { base.OnSize(newRect); int playerCount = GameLevel.PlayerCountInLevel; Viewport viewport = FrameworkCore.CurrentViewport; // split-screen Camera ViewCamera followViewCamera = Viewer.GetViewCamera("Follow"); for (int i = 0; i < playerCount; i++) { GamePlayer player = GameLevel.GetPlayerInLevel(i); int splitX = 0; int splitY = 0; int splitWidth = 0; int splitHeight = 0; // 1P viewport area if (i == 0) { splitX = 0; splitY = 0; } // 2P viewport area else if (i == 1) { splitX = 0; splitY = viewport.Height / playerCount; } splitWidth = viewport.Width; splitHeight = viewport.Height / playerCount; // Resizing camera followViewCamera.Resize(i, splitX, splitY, splitWidth, splitHeight); } // Resize Hud { int posX = 0, posY = 0, scaledWidth = 0, scaledHeight = 0, offsetY = 0; ViewCamera viewCamera = FrameworkCore.CurrentCamera; int viewCount = viewCamera.Count; float scaleFactor = 1.0f; if (GameLevel.Info.GamePlayType == GamePlayTypeId.Versus) { scaleFactor = 0.8f; } // Scaling image size and positioning for screen resolution Vector2 sizeScale = new Vector2( (float)FrameworkCore.ViewWidth * scaleFactor / (float)ViewerWidth.Width1080, (float)FrameworkCore.ViewHeight * scaleFactor / (float)ViewerHeight.Height1080); Vector2 posScale = new Vector2( (float)FrameworkCore.ViewWidth * scaleFactor / (float)ViewerWidth.Width1080, (float)FrameworkCore.ViewHeight * scaleFactor / (float)ViewerHeight.Height1080); // if versus mode, apply width offset rate if (GameLevel.Info.GamePlayType == GamePlayTypeId.Versus) { posScale.X *= 1.3f; } for (int i = 0; i < viewCount; i++) { Viewport view = viewCamera.GetViewport(i); offsetY = (int)view.Y; // kill score and condition score this.textKillScore[i].PosX = (int)(215 * posScale.X); this.textKillScore[i].PosY = (int)((float)view.Height * 0.68f) + offsetY; this.textKillConditionScore[i].PosX = (int)(300 * posScale.X); this.textKillConditionScore[i].PosY = (int)((float)view.Height * 0.76f) + offsetY; this.textKillScore[i].Scale = 1.6f; this.textKillConditionScore[i].Scale = 0.8f; float textScale = 1.4f * (float)FrameworkCore.ViewWidth / (float)ViewerWidth.Width720; this.textKillScore[i].Scale *= textScale; this.textKillConditionScore[i].Scale *= textScale; } // 1P image this.spriteObjHudVersus1P.SourceRectangle = new Rectangle( 82, 560, image1PWidth, image1PHeight); this.spriteObjHudVersus1P.ScreenRectangle = new Rectangle( (int)(FrameworkCore.ViewWidth * 0.05f), (int)(FrameworkCore.ViewHeight / 2 * 0.76f), (int)((float)image1PWidth * sizeScale.X), (int)((float)image1PHeight * sizeScale.Y)); // 2P image this.spriteObjHudVersus2P.SourceRectangle = new Rectangle( 532, 560, image1PWidth, image1PHeight); offsetY = (FrameworkCore.ViewHeight / 2); this.spriteObjHudVersus2P.ScreenRectangle = new Rectangle( (int)(FrameworkCore.ViewWidth * 0.05f), (int)((FrameworkCore.ViewHeight / 2 * 0.76f) + offsetY), (int)((float)image1PWidth * sizeScale.X), (int)((float)image1PHeight * sizeScale.Y)); this.spriteObjHudVersusWin.SourceRectangle = new Rectangle(108, 55, imageWinWidth, imageWinHeight); this.spriteObjHudVersusLose.SourceRectangle = new Rectangle(48, 370, imageLoseWidth, imageLoseHeight); if (this.isFinishedVersus) { for (int i = 0; i < GameLevel.PlayerCountInLevel; i++) { GamePlayer player = GameLevel.GetPlayerInLevel(i); // You win if (RobotGameGame.VersusGameInfo.killPoint <= player.KillPoint) { scaledWidth = (int)((float)imageWinWidth * sizeScale.X); scaledHeight = (int)((float)imageWinHeight * sizeScale.Y); posX = (int)((FrameworkCore.ViewWidth / 2) - (scaledWidth / 2)); posY = (int)((FrameworkCore.ViewHeight / 2) - (scaledHeight / 2)); if (player.PlayerIndex == PlayerIndex.One) { posY -= FrameworkCore.ViewHeight / 4; } else if (player.PlayerIndex == PlayerIndex.Two) { posY += FrameworkCore.ViewHeight / 4; } this.spriteObjHudVersusWin.ScreenRectangle = new Rectangle( posX, posY, scaledWidth, scaledHeight); } // You lose else { scaledWidth = (int)((float)imageLoseWidth * sizeScale.X); scaledHeight = (int)((float)imageLoseHeight * sizeScale.Y); posX = (int)((FrameworkCore.ViewWidth / 2) - (scaledWidth / 2)); posY = (int)((FrameworkCore.ViewHeight / 2) - (scaledHeight / 2)); if (player.PlayerIndex == PlayerIndex.One) { posY -= FrameworkCore.ViewHeight / 4; } else if (player.PlayerIndex == PlayerIndex.Two) { posY += FrameworkCore.ViewHeight / 4; } this.spriteObjHudVersusLose.ScreenRectangle = new Rectangle(posX, posY, scaledWidth, scaledHeight); } } } // Resizing Hud ResizeHud(); } }
/// <summary> /// checks the mission objective during the game play. /// Moves to the next stage after the mission gets cleared, /// and when the mission is failed, returns to the main menu. /// </summary> /// <param name="gameTime"></param> protected override void CheckMission(GameTime gameTime) { // Checking mission if (IsMissionFailed == false) { IsMissionFailed = GameLevel.IsMissionFailed(); } if (IsMissionClear == false) { IsMissionClear = gameLevel.IsMissionClear(); } // Mission complete!! if (IsMissionClear ) { if (GameSound.IsPlaying(soundBGM)) { SetVisibleHud(false); // The volume for the sound effects besides the // background music will be lowered. FrameworkCore.SoundManager.SetVolume( SoundCategory.Default.ToString(), 0.4f); FrameworkCore.SoundManager.SetVolume( SoundCategory.Effect.ToString(), 0.4f); FrameworkCore.SoundManager.SetVolume( SoundCategory.Music.ToString(), 1.0f); // Stop background music GameSound.Stop(soundBGM); // Play victory music GameSound.Play(SoundTrack.MissionClear); // Player stop for (int i = 0; i < GameLevel.PlayerCountInLevel; i++) { GamePlayer player = GameLevel.GetPlayerInLevel(i); player.MissionEnd(); } if (NextScreen == null) throw new InvalidOperationException("Please set to next screen"); // Go to next stage ExitScreen(); } // display the clear image if (missionResultElapsedTime > MissionResultVisibleTime) { this.spriteObjMissionClear.Visible = true; } else { if (missionResultElapsedTime < MissionResultVisibleTime) { missionResultElapsedTime += (float)gameTime.ElapsedGameTime.TotalSeconds; } this.spriteObjMissionClear.Visible = false; } } // Mission failed else if (IsMissionFailed ) { if (GameSound.IsPlaying(soundBGM)) { SetVisibleHud(false); // The volume for the sound effects besides the // background music will be lowered. FrameworkCore.SoundManager.SetVolume( SoundCategory.Default.ToString(), 0.4f); FrameworkCore.SoundManager.SetVolume( SoundCategory.Effect.ToString(), 0.4f); FrameworkCore.SoundManager.SetVolume( SoundCategory.Music.ToString(), 1.0f); // Stop background music GameSound.Stop(soundBGM); // Play fail music GameSound.Play(SoundTrack.MissionFail); // Player sound and action stop for (int i = 0; i < GameLevel.PlayerCountInLevel; i++) { GamePlayer player = GameLevel.GetPlayerInLevel(i); player.MissionEnd(); } // Go to main menu NextScreen = new MainMenuScreen(); TransitionOffTime = TimeSpan.FromSeconds(8.0f); ExitScreen(); } // display the failed image if (missionResultElapsedTime > MissionResultVisibleTime) { this.spriteObjMissionFailed.Visible = true; } else { if (missionResultElapsedTime < MissionResultVisibleTime) { missionResultElapsedTime += (float)gameTime.ElapsedGameTime.TotalSeconds; } this.spriteObjMissionFailed.Visible = false; } } }