protected override void OnNewParent() { base.OnNewParent(); thumb = Parent as GameThumbnail; thumb.MotionB.ScaleTarget = sz1; thumb.MotionB.ScaleSpeed = spd1; }
/// <summary> /// set state to loading game and display given game name /// </summary> /// <param name="g">game whose name/info to display while loading</param> public void SetLoadingGame(GardenItem g, GameThumbnail thumb) { SetNextState(new StateLoadingDisplay_Loading(this)); game = g; gameIcon.Texture = thumb.Texture; //gameIcon.Motion.Scale = thumb.Motion.Scale * 1.4f * g.ScaleIcon; gameIcon.Motion.Scale = Screen.Width / gameIcon.DrawInfo.Width; }
public GameThumbnailLoadTask(GameThumbnail th) { parent = th; }
public GameThumbnailLoadTask(GameThumbnail th) : base(th.Game) { parent = th; }
/// <summary> /// calculate the distance from cursor to given GameThumbnail in the grid /// </summary> /// <param name="g"></param> /// <returns></returns> public float DistanceTo(GameThumbnail g) { Vector2 v = g.Game.PositionXY - GridPosition; return(v.Length()); }
/// <summary> /// calculate the distance from cursor to given GameThumbnail in the grid /// </summary> /// <param name="g"></param> /// <returns></returns> public float DistanceTo(GameThumbnail g) { Vector2 v = g.Game.PositionXY - GridPosition; return v.Length(); }
public override void OnUserInput(GamesPanel.UserInput inp) { // HACK: for web games launch, make sure that music is turned back on upon next user input after play if (!isGameLaunchOngoing && !GardenGame.Instance.music.IsFadedIn && GardenGame.Instance.music.UserWantsMusic) { GardenGame.Instance.music.FadeIn(); } switch (inp) { case UserInput.DOWN: if (cursor.GridPosition.Y < GridMaxY - 1) { cursor.GridPosition.Y += 1f; SelectGameBelowCursor(); } break; case UserInput.UP: if (cursor.GridPosition.Y > 0) { cursor.GridPosition.Y -= 1f; SelectGameBelowCursor(); } break; case UserInput.LEFT: if (cursor.GridPosition.X > 0) { cursor.GridPosition.X -= 1f; SelectGameBelowCursor(); } break; case UserInput.RIGHT: if (cursor.GridPosition.X < GridMaxX - 1) { cursor.GridPosition.X += 1f; SelectGameBelowCursor(); } break; case UserInput.START_EXIT: isExiting = true; //selectionLevel = 0; Motion.ZoomTarget = PANEL_ZOOM_TARGET_QUITTING; Motion.ZoomSpeed = PANEL_ZOOM_SPEED_REGULAR; infoBox.Motion.TargetPos = INFOBOX_ALL_HIDDEN_POSITION; creditsBitmap.Motion.TargetPos = CREDITS_HIDDEN_POSITION; helpTextBitmap.Motion.TargetPos = HELPTEXT_HIDDEN_POSITION; //Motion.ZoomCenter = cursor.Motion.PositionAbs; //Motion.ZoomCenterTarget = cursor.Motion; break; case UserInput.STOP_EXIT: if (timeExiting < TIME_BEFORE_EXIT_CONTINUES) { isExiting = false; selectionLevel = 0; Motion.ZoomTarget = PANEL_ZOOM_REGULAR; Motion.ZoomSpeed = PANEL_ZOOM_SPEED_ABORTQUITTING; //Motion.ZoomCenter = cursor.Motion.PositionAbs; //Motion.ZoomCenterTarget = cursor.Motion; } break; case UserInput.START_SELECT: if (SelectedGame != null) { GameThumbnail th = null; try { th = thumbnailsCache[SelectedGame.GameID]; } catch (Exception) {; } if (th != null) { switch (selectionLevel) { case 0: // select once - zoom in on selected game Motion.ZoomTarget = PANEL_ZOOM_DETAILED_VIEW; Motion.ZoomSpeed = PANEL_ZOOM_SPEED_REGULAR; // 0.01f; Motion.ZoomCenterTarget = cursor.Motion; SelectedGame.Refresh(); selectionLevel++; break; case 1: // select again - install or launch game if selection key pressed long enough. isGameLaunchOngoing = true; break; } } } break; case UserInput.STOP_SELECT: // if not launched long enough, reset - no action if (timeLaunching < TIME_BEFORE_GAME_LAUNCH) { isGameLaunchConfirmed = false; } else { isGameLaunchConfirmed = true; } isGameLaunchOngoing = false; timeLaunching = 0f; break; case UserInput.LAUNCH_WEBSITE: isLaunchWebsite = true; break; case UserInput.TOGGLE_MUSIC: GardenGame.Instance.music.ToggleMusic(); break; } // switch(inp) if (!isExiting) { if (selectionLevel == 0) { infoBox.Motion.TargetPos = INFOBOX_DESCRIPTION_HIDDEN_POSITION; } if (selectionLevel == 1 && SelectedGame != null) { int lnCount = SelectedGame.DescriptionLineCount; infoBox.Motion.TargetPos = INFOBOX_SHOWN_POSITION - new Vector2(0f, 0.015f + 0.029f * (lnCount - 1)); } if (SelectedGame == null || SelectedGame.Name.Length == 0) { infoBox.Motion.TargetPos = INFOBOX_ALL_HIDDEN_POSITION; } } }
protected override void OnUpdate(ref UpdateParams p) { base.OnUpdate(ref p); GardenItem selGame = SelectedGame; // update info box if (selGame == null && infoBox != null) { infoBox.SetGameInfo(selGame); } // handle download/install/launching of a game if (selGame != null && isGameLaunchOngoing && timeLaunching < TIME_BEFORE_GAME_LAUNCH) { timeLaunching += p.Dt; GameThumbnail th = thumbnailsCache[selGame.GameID]; float sc = (1f + timeLaunching / 3f); th.Motion.ScaleTarget = THUMBNAIL_SCALE_SELECTED * sc; // blow up size of thumbnail while user requests launch cursor.Motion.ScaleTarget = sc; cursor.Motion.ScaleSpeed = th.Motion.ScaleSpeed / selGame.ScaleIcon; // TODO correct ScaleIcon? } if (!isGameLaunchOngoing) { cursor.Motion.ScaleTarget = CURSOR_SCALE_REGULAR; } // launch of a game if (isGameLaunchConfirmed && selGame != null) { cursor.Motion.ScaleTarget = CURSOR_SCALE_REGULAR; GameThumbnail thumb = thumbnailsCache[selGame.GameID]; if (selGame.IsIggClient) { if (selGame.IsInstalled) { GardenGame.Instance.music.FadeOut(); GardenGame.Instance.ActionLaunchGame(selGame, thumb); isExiting = true; timeExiting = TIME_BEFORE_EXIT; } else { GardenGame.Instance.ActionDownloadAndInstallGame(selGame); } } else { if (selGame.IsWebGame) { GardenGame.Instance.ActionLaunchWebsitePlayGame(selGame, thumb); } else if (!selGame.IsGrowable) { thumb.Motion.Add(new TemporaryScaleBlowup()); } else if (selGame.IsInstalled) { GardenGame.Instance.music.FadeOut(); GardenGame.Instance.ActionLaunchGame(selGame, thumb); } else // if (not installed) { GardenGame.Instance.ActionDownloadAndInstallGame(selGame); } } isGameLaunchOngoing = false; isGameLaunchConfirmed = false; timeLaunching = 0f; } // handle exit key if (isExiting) { GardenGame.Instance.music.FadeOut(); timeExiting += p.Dt; if (timeExiting > TIME_BEFORE_EXIT) { parentMenu.background.Motion.ScaleModifier = 1f / (1f + (timeExiting - TIME_BEFORE_EXIT) / 11f); if (!isExitingUnstoppable) { GardenGame.Instance.SignalExitGame(); isExitingUnstoppable = true; Motion.ZoomSpeed = PANEL_ZOOM_SPEED_QUITTING; } return; } } else { if (timeExiting > 0f) { if (GardenGame.Instance.music.UserWantsMusic) { GardenGame.Instance.music.FadeIn(); } timeExiting = 0f; } } //-- website launch if (isLaunchWebsite) { if (selGame != null) { GameThumbnail thumb = thumbnailsCache[selGame.GameID]; GardenGame.Instance.ActionLaunchWebsite(selGame, thumb); } isLaunchWebsite = false; } //-- loop all nearby games adapt their display properties where needed if (gl == null) { return; } GardenItem g; // upd cache with possibly new items around cursor List <GardenItem> c = gl.GetItemsAround((int)cursor.GridPosition.X, (int)cursor.GridPosition.Y, (int)CURSOR_DISCOVERY_RANGE); if (selGame != null) { c.Add(selGame); } for (int i = c.Count - 1; i >= 0; i--) { g = c[i]; // if GameThumbnail for current game does not exist yet, create it if (!thumbnailsCache.ContainsKey(g.GameID) && g.IsVisible && g.GameID.Length > 0) { // create now GameThumbnail th = new GameThumbnail(g); Add(0, th); thumbnailsCache.Add(g.GameID, th); //th.Position = new Vector2(RandomMath.RandomBetween(-0.4f,2.0f), RandomMath.RandomBetween(-0.4f,1.4f) ); //th.Scale = RandomMath.RandomBetween(0.01f, 0.09f); // create with new position and scale th.Motion.Position = Screen.Center; th.Motion.Scale = 0.05f; th.Motion.ScaleTarget = 0.05f; th.Motion.ScaleSpeed = 0.01f; // TODO const th.DrawInfo.LayerDepth = LAYER_GRID_ITEMS + ((float)th.ID) * float.Epsilon; th.Visible = false; th.ColorB.Intensity = 0.0f; // special case thumbnails if (g.GameID.Equals("igg_controls")) { th.Motion.Add(new MyFuncyModifier(delegate(float v) { return(v / 22.3f); }, "Rotate")); } } } // visit all cached items and adjust positions, visibility, etc. List <GameThumbnail> toRemoveFromCache = new List <GameThumbnail>(); foreach (GameThumbnail th in thumbnailsCache.Values) { g = th.Game; // check if out of range. If so, remove from cache later if (cursor.DistanceTo(th) > CURSOR_DESTRUCTION_RANGE) { toRemoveFromCache.Add(th); th.Delete = true; } else { // check if thnail invvisible but in range. If so, start loading it if (!th.Visible && cursor.DistanceTo(th) <= CURSOR_DISCOVERY_RANGE) { th.LoadInBackground(); th.ColorB.Intensity = 0f; } // check if thnail is loaded and still in range. If so, start displaying it (fade in) if (th.IsLoaded() && cursor.DistanceTo(th) <= CURSOR_DISCOVERY_RANGE) { if (th.Game.IsGrowable) { th.ColorB.FadeTarget = (0.65f + 0.35f * g.InstallProgress); } else { th.ColorB.FadeTarget = 1f; } } // check if thnail in range to fade out if (th.IsLoaded() && cursor.DistanceTo(th) > CURSOR_FADEOUT_RANGE) { th.ColorB.FadeTarget = 0f; } } th.Motion.ScaleTarget = THUMBNAIL_SCALE_UNSELECTED; th.ColorB.FadeSpeed = THUMBNAIL_FADE_SPEED; // TODO do this only once per th? // coordinate position where to move a game thumbnail to Vector2 targetPos = (g.Position - PanelShiftPos) * new Vector2(PANEL_DELTA_GRID_X, PANEL_DELTA_GRID_Y); th.Motion.TargetPos = targetPos; th.Motion.TargetPosSpeed = PANEL_SPEED_SHIFT; } // end for loop over all games foreach (GameThumbnail th in toRemoveFromCache) { thumbnailsCache.Remove(th.Game.GameID); } // --- for selected game only if (selGame != null) { g = selGame; // update text box with currently selected game info if (g != infoBox.game) { infoBox.SetGameInfo(g); } //-- helpful controls text if (g.GameID.Equals("igg_controls") && !isExiting) { helpTextBitmap.Motion.TargetPos = HELPTEXT_SHOWN_POSITION; if (g.Name.Length == 0) { string msg = GardenConfig.Instance.ServerMsg; string[] msgLines = msg.Split(new char[] { '\n' }, 2); g.Name = msgLines[0]; if (msgLines.Length > 1) { g.Description = msgLines[1]; } } } else { helpTextBitmap.Motion.TargetPos = HELPTEXT_HIDDEN_POSITION; } //-- credits text if (g.GameID.Equals("igg_credits") && !isExiting) { creditsBitmap.Motion.TargetPos = CREDITS_SHOWN_POSITION; Vector2 cpd = cursor.Motion.PositionAbsZoomed; if (cpd.Y <= 0.35f) // TODO const { float dxp = PANEL_SPEED_SHIFT * p.Dt; PanelShiftPos.Y -= dxp; } } else { creditsBitmap.Motion.TargetPos = CREDITS_HIDDEN_POSITION; } if (!isGameLaunchOngoing) { if (thumbnailsCache.ContainsKey(g.GameID)) { GameThumbnail th = thumbnailsCache[g.GameID]; if (g.IsInstalling) { // wobble the size of icon when installing. th.Motion.ScaleTarget = 1.0f + 0.1f * (float)Math.Sin(MathHelper.TwoPi * 0.16f * SimTime); } else { // displaying selected thumbnails larger if (g.IsGrowable) { th.Motion.ScaleTarget = THUMBNAIL_SCALE_SELECTED; } else { th.Motion.ScaleTarget = THUMBNAIL_SCALE_UNSELECTED; } } } } } // cursor where to move to cursor.Motion.TargetPos = (cursor.GridPosition - PanelShiftPos) * new Vector2(PANEL_DELTA_GRID_X, PANEL_DELTA_GRID_Y); cursor.Motion.TargetPosSpeed = PANEL_SPEED_SHIFT; // panel shift effect when cursor hits edges of panel Vector2 cp = cursor.Motion.PositionAbsZoomed; float chw = cursor.DrawInfo.WidthAbs / 2.0f; // cursor-half-width float chh = cursor.DrawInfo.HeightAbs / 2.0f; // cursor-half-height float dx = PANEL_SPEED_SHIFT * p.Dt; const float xMargin = CURSOR_MARGIN_X; // TODO into gui props const float yMargin = CURSOR_MARGIN_Y; if (cp.X <= chw + xMargin) { PanelShiftPos.X -= dx; } else if (cp.X >= PANEL_SIZE_X - chw - xMargin) { PanelShiftPos.X += dx; } if (cp.Y <= chh + yMargin) { PanelShiftPos.Y -= dx; } else if (cp.Y >= PANEL_SIZE_Y - chh - yMargin) { PanelShiftPos.Y += dx; } }
protected override void OnUpdate(ref UpdateParams p) { base.OnUpdate(ref p); GardenItem selGame = SelectedGame; // update info box if (selGame == null && infoBox != null) { infoBox.SetGameInfo(selGame); } // handle download/install/launching of a game if (selGame != null && isGameLaunchOngoing && timeLaunching < TIME_BEFORE_GAME_LAUNCH) { timeLaunching += p.Dt; GameThumbnail th = thumbnailsCache[selGame.GameID]; float sc = (1f + timeLaunching/3f); th.Motion.ScaleTarget = THUMBNAIL_SCALE_SELECTED * sc; // blow up size of thumbnail while user requests launch cursor.Motion.ScaleTarget = sc; cursor.Motion.ScaleSpeed = th.Motion.ScaleSpeed / selGame.ScaleIcon; // TODO correct ScaleIcon? } if (!isGameLaunchOngoing) { cursor.Motion.ScaleTarget = CURSOR_SCALE_REGULAR; } // launch of a game if (isGameLaunchConfirmed && selGame != null) { cursor.Motion.ScaleTarget = CURSOR_SCALE_REGULAR; GameThumbnail thumb = thumbnailsCache[selGame.GameID]; if (selGame.IsIggClient) { if (selGame.IsInstalled) { GardenGame.Instance.music.FadeOut(); GardenGame.Instance.ActionLaunchGame(selGame, thumb); isExiting = true; timeExiting = TIME_BEFORE_EXIT; } else { GardenGame.Instance.ActionDownloadAndInstallGame(selGame); } } else { if (selGame.IsWebGame) { GardenGame.Instance.ActionLaunchWebsitePlayGame(selGame, thumb); } else if (!selGame.IsGrowable) { thumb.Motion.Add(new TemporaryScaleBlowup()); } else if (selGame.IsInstalled) { GardenGame.Instance.music.FadeOut(); GardenGame.Instance.ActionLaunchGame(selGame, thumb); } else // if (not installed) { GardenGame.Instance.ActionDownloadAndInstallGame(selGame); } } isGameLaunchOngoing = false; isGameLaunchConfirmed = false; timeLaunching = 0f; } // handle exit key if (isExiting) { GardenGame.Instance.music.FadeOut(); timeExiting += p.Dt; if (timeExiting > TIME_BEFORE_EXIT) { parentMenu.background.Motion.ScaleModifier = 1f / (1f + (timeExiting-TIME_BEFORE_EXIT) / 11f); if (!isExitingUnstoppable) { GardenGame.Instance.SignalExitGame(); isExitingUnstoppable = true; Motion.ZoomSpeed = PANEL_ZOOM_SPEED_QUITTING; } return; } } else { if (timeExiting > 0f) { if(GardenGame.Instance.music.UserWantsMusic) GardenGame.Instance.music.FadeIn(); timeExiting = 0f; } } //-- website launch if (isLaunchWebsite) { if (selGame != null) { GameThumbnail thumb = thumbnailsCache[selGame.GameID]; GardenGame.Instance.ActionLaunchWebsite(selGame, thumb); } isLaunchWebsite = false; } //-- loop all nearby games adapt their display properties where needed if (gl == null) return; GardenItem g; // upd cache with possibly new items around cursor List<GardenItem> c = gl.GetItemsAround((int)cursor.GridPosition.X, (int)cursor.GridPosition.Y, (int) CURSOR_DISCOVERY_RANGE); if (selGame != null) c.Add(selGame); for (int i = c.Count - 1; i >= 0; i--) { g = c[i]; // if GameThumbnail for current game does not exist yet, create it if (!thumbnailsCache.ContainsKey(g.GameID) && g.IsVisible && g.GameID.Length > 0 ) { // create now GameThumbnail th = new GameThumbnail(g); Add(0, th); thumbnailsCache.Add(g.GameID, th); //th.Position = new Vector2(RandomMath.RandomBetween(-0.4f,2.0f), RandomMath.RandomBetween(-0.4f,1.4f) ); //th.Scale = RandomMath.RandomBetween(0.01f, 0.09f); // create with new position and scale th.Motion.Position = Screen.Center; th.Motion.Scale = 0.05f; th.Motion.ScaleTarget = 0.05f; th.Motion.ScaleSpeed = 0.01f; // TODO const th.DrawInfo.LayerDepth = LAYER_GRID_ITEMS + ((float)th.ID) * float.Epsilon; th.Visible = false; th.ColorB.Intensity = 0.0f; // special case thumbnails if (g.GameID.Equals("igg_controls")) th.Motion.Add(new MyFuncyModifier( delegate(float v) { return v/22.3f; }, "Rotate")); } } // visit all cached items and adjust positions, visibility, etc. List<GameThumbnail> toRemoveFromCache = new List<GameThumbnail>(); foreach(GameThumbnail th in thumbnailsCache.Values) { g = th.Game; // check if out of range. If so, remove from cache later if (cursor.DistanceTo(th) > CURSOR_DESTRUCTION_RANGE) { toRemoveFromCache.Add(th); th.Delete = true; } else { // check if thnail invvisible but in range. If so, start loading it if (!th.Visible && cursor.DistanceTo(th) <= CURSOR_DISCOVERY_RANGE) { th.LoadInBackground(); th.ColorB.Intensity = 0f; } // check if thnail is loaded and still in range. If so, start displaying it (fade in) if (th.IsLoaded() && cursor.DistanceTo(th) <= CURSOR_DISCOVERY_RANGE) { if (th.Game.IsGrowable) th.ColorB.FadeTarget = (0.65f + 0.35f * g.InstallProgress); else th.ColorB.FadeTarget = 1f; } // check if thnail in range to fade out if (th.IsLoaded() && cursor.DistanceTo(th) > CURSOR_FADEOUT_RANGE) th.ColorB.FadeTarget = 0f; } th.Motion.ScaleTarget = THUMBNAIL_SCALE_UNSELECTED; th.ColorB.FadeSpeed = THUMBNAIL_FADE_SPEED; // TODO do this only once per th? // coordinate position where to move a game thumbnail to Vector2 targetPos = (g.Position - PanelShiftPos) * new Vector2(PANEL_DELTA_GRID_X, PANEL_DELTA_GRID_Y); th.Motion.TargetPos = targetPos; th.Motion.TargetPosSpeed = PANEL_SPEED_SHIFT; } // end for loop over all games foreach (GameThumbnail th in toRemoveFromCache) { thumbnailsCache.Remove(th.Game.GameID); } // --- for selected game only if (selGame != null) { g = selGame; // update text box with currently selected game info if( g != infoBox.game) infoBox.SetGameInfo(g); //-- helpful controls text if (g.GameID.Equals("igg_controls") && !isExiting) { helpTextBitmap.Motion.TargetPos = HELPTEXT_SHOWN_POSITION; if (g.Name.Length == 0) { string msg = GardenConfig.Instance.ServerMsg; string[] msgLines = msg.Split(new char[] { '\n' },2); g.Name = msgLines[0]; if (msgLines.Length > 1) g.Description = msgLines[1]; } } else { helpTextBitmap.Motion.TargetPos = HELPTEXT_HIDDEN_POSITION; } //-- credits text if (g.GameID.Equals("igg_credits") && !isExiting) { creditsBitmap.Motion.TargetPos = CREDITS_SHOWN_POSITION; Vector2 cpd = cursor.Motion.PositionAbsZoomed; if (cpd.Y <= 0.35f) // TODO const { float dxp = PANEL_SPEED_SHIFT * p.Dt; PanelShiftPos.Y -= dxp; } } else { creditsBitmap.Motion.TargetPos = CREDITS_HIDDEN_POSITION; } if (!isGameLaunchOngoing) { if (thumbnailsCache.ContainsKey(g.GameID)) { GameThumbnail th = thumbnailsCache[g.GameID]; if (g.IsInstalling) { // wobble the size of icon when installing. th.Motion.ScaleTarget = 1.0f + 0.1f * (float)Math.Sin(MathHelper.TwoPi * 0.16f * SimTime); } else { // displaying selected thumbnails larger if (g.IsGrowable) { th.Motion.ScaleTarget = THUMBNAIL_SCALE_SELECTED; } else { th.Motion.ScaleTarget = THUMBNAIL_SCALE_UNSELECTED; } } } } } // cursor where to move to cursor.Motion.TargetPos = (cursor.GridPosition - PanelShiftPos) * new Vector2(PANEL_DELTA_GRID_X, PANEL_DELTA_GRID_Y); cursor.Motion.TargetPosSpeed = PANEL_SPEED_SHIFT; // panel shift effect when cursor hits edges of panel Vector2 cp = cursor.Motion.PositionAbsZoomed; float chw = cursor.DrawInfo.WidthAbs / 2.0f; // cursor-half-width float chh = cursor.DrawInfo.HeightAbs / 2.0f; // cursor-half-height float dx = PANEL_SPEED_SHIFT * p.Dt; const float xMargin = CURSOR_MARGIN_X; // TODO into gui props const float yMargin = CURSOR_MARGIN_Y; if (cp.X <= chw + xMargin) { PanelShiftPos.X -= dx; } else if (cp.X >= PANEL_SIZE_X - chw - xMargin) { PanelShiftPos.X += dx; } if (cp.Y <= chh + yMargin) { PanelShiftPos.Y -= dx; } else if (cp.Y >= PANEL_SIZE_Y - chh - yMargin) { PanelShiftPos.Y += dx; } }
/// <summary> /// called by a child GUI component to launch a game /// </summary> /// <param name="g">game to launch</param> public void ActionLaunchGame(GardenItem g, GameThumbnail thumb) { if (g.IsInstalled) { if (g.IsPlayable) { // if installed, then launch it if possible if ((launcher == null || launcher.IsFinished() == true) && (launchGameThread == null || launchGameThread.IsFinished())) { loadingDisplay.SetLoadingGame(g, thumb); // set state of game to 'game playing state' TreeRoot.SetNextState(new StatePlayingGame()); launcher = new GameLauncherTask(g); launchGameThread = new ThreadedTask(launcher); launchGameThread.TaskSuccessEvent += new TaskEventHandler(taskThread_TaskFinishedEvent); launchGameThread.TaskFailEvent += new TaskEventHandler(taskThread_TaskFinishedEvent); launchGameThread.Start(); } } if (g.IsMusic) { music.Play(g.ExeFilepath , 0.5f , 0f); // TODO vary audio volume per track. } } }
public void ActionLaunchWebsitePlayGame(GardenItem g, GameThumbnail thumb) { ITask t = new ThreadedTask(new SiteLauncherTask(g, g.ExeFile)); t.Start(); loadingDisplay.SetLoadingGame(g, thumb); music.FadeOut(); TreeRoot.SetNextState(new StatePlayingGame(2f,false)); }