diff --git a/Android/Activity1.cs b/Android/Activity1.cs index 642662c..dd2c1da 100644 --- a/Android/Activity1.cs +++ b/Android/Activity1.cs @@ -31,9 +31,13 @@ namespace Android { protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); + // ad layout + var adLayout = new LinearLayout(this) {Orientation = Orientation.Vertical}; + adLayout.SetGravity(GravityFlags.Bottom); + // set up the game TextInputWrapper.Current = new TextInputWrapper.Mobile(); - this.game = new GameImpl(new AndroidAnalytics(this)); + this.game = new GameImpl(new AndroidPlatform(this, adLayout)); this.game.GraphicsDeviceManager.ResetWidthAndHeight(this.game.Window); this.game.GraphicsDeviceManager.IsFullScreen = true; this.game.OnLoadContent += game => { @@ -53,18 +57,6 @@ namespace Android { if (Build.VERSION.SdkInt >= BuildVersionCodes.P) this.Window.Attributes.LayoutInDisplayCutoutMode = LayoutInDisplayCutoutMode.ShortEdges; - // ad layout - var adLayout = new LinearLayout(this) {Orientation = Orientation.Vertical}; - adLayout.SetGravity(GravityFlags.Bottom); - var ad = new AdView(this) { - AdUnitId = "ca-app-pub-5754829579653773/7841535920", - AdSize = AdSize.SmartBanner - }; - ad.LoadAd(new AdRequest.Builder() - .AddTestDevice("14B965C6457E17D2808061ADF7E34923") - .Build()); - adLayout.AddView(ad); - // total layout that is displayed this.mainView = new LinearLayout(this) {Orientation = Orientation.Vertical}; this.mainView.LayoutParameters = new LinearLayout.LayoutParams(MatchParent, MatchParent); diff --git a/Android/Android.csproj b/Android/Android.csproj index afbda43..01b7a64 100644 --- a/Android/Android.csproj +++ b/Android/Android.csproj @@ -54,7 +54,7 @@ - + diff --git a/Android/AndroidAnalytics.cs b/Android/AndroidAnalytics.cs deleted file mode 100644 index d456b05..0000000 --- a/Android/AndroidAnalytics.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using Android.App; -using GameAnalyticsSDK; -using GameAnalyticsSDK.Utilities; -using TouchyTickets; - -namespace Android { - public class AndroidAnalytics : Analytics { - - private readonly Activity activity; - - public AndroidAnalytics(Activity activity) { - this.activity = activity; - } - - public override void Setup(Dictionary json) { - GameAnalytics.Initialize(this.activity, GA_MiniJSON.JsonEncode(new Hashtable(json))); - } - - public override void AddResourceEvent(bool sink, string currency, float amount, string itemType, string itemId) { - GameAnalytics.NewResourceEvent(sink ? GAResourceFlowType.Sink : GAResourceFlowType.Source, currency, amount, itemType, itemId); - } - - } -} \ No newline at end of file diff --git a/Android/AndroidPlatform.cs b/Android/AndroidPlatform.cs new file mode 100644 index 0000000..b508382 --- /dev/null +++ b/Android/AndroidPlatform.cs @@ -0,0 +1,41 @@ +using System.Collections; +using System.Collections.Generic; +using Android.App; +using Android.Gms.Ads; +using Android.Widget; +using GameAnalyticsSDK; +using GameAnalyticsSDK.Utilities; +using TouchyTickets; + +namespace Android { + public class AndroidPlatform : Platform { + + private readonly Activity activity; + private readonly LinearLayout adLayout; + + public AndroidPlatform(Activity activity, LinearLayout adLayout) { + this.activity = activity; + this.adLayout = adLayout; + } + + public override void SetupAds() { + var ad = new AdView(this.activity) { + AdUnitId = "ca-app-pub-5754829579653773/7841535920", + AdSize = AdSize.SmartBanner + }; + ad.LoadAd(new AdRequest.Builder() + .AddTestDevice("14B965C6457E17D2808061ADF7E34923") + .Build()); + this.adLayout.AddView(ad); + } + + public override void SetupAnalytics(Dictionary json) { + GameAnalytics.Initialize(this.activity, GA_MiniJSON.JsonEncode(new Hashtable(json))); + } + + public override void AddResourceEvent(bool sink, string currency, float amount, string itemType, string itemId) { + GameAnalytics.NewResourceEvent(sink ? GAResourceFlowType.Sink : GAResourceFlowType.Source, currency, amount, itemType, itemId); + } + + } +} \ No newline at end of file diff --git a/TouchyTickets/GameImpl.cs b/TouchyTickets/GameImpl.cs index 2ca52d0..dc0f377 100644 --- a/TouchyTickets/GameImpl.cs +++ b/TouchyTickets/GameImpl.cs @@ -12,23 +12,32 @@ namespace TouchyTickets { public static GameImpl Instance { get; private set; } public readonly ISet AppliedUpgrades = new HashSet(); - public readonly Tutorial Tutorial = new Tutorial(); - public bool ReadAnalyticsInfo; - public readonly Analytics Analytics; + public readonly Platform Platform; public BigInteger Tickets; public int TimesRestarted; public int Stars; public ParkMap Map; + public Tutorial Tutorial { get; private set; } public Camera Camera { get; private set; } public Ui Ui { get; private set; } public bool DrawMap; public DateTime LastUpdate; private double saveCounter; - public GameImpl(Analytics analytics) { - this.Analytics = analytics; + public GameImpl(Platform platform) { + this.Platform = platform; Instance = this; + } + protected override void LoadContent() { + base.LoadContent(); + + // start the load sequence + Ui.SetupUiSystem(this.UiSystem); + CoroutineHandler.Start(Ui.DisplaySplash(this.LoadGame)); + } + + private void LoadGame() { // set up analytics var settings = new Dictionary(); settings["InfoLog"] = true; @@ -39,15 +48,15 @@ namespace TouchyTickets { // ios comes first, then android. For now they're the same settings["GameKey"] = new[] {"cc18de06eebbc5d5e987c384fcd28000", "cc18de06eebbc5d5e987c384fcd28000"}; settings["SecretKey"] = new[] {"82ca1a930ee38e2383ffb02db7631e16033b511d", "82ca1a930ee38e2383ffb02db7631e16033b511d"}; - this.Analytics.Setup(settings); - } + this.Platform.SetupAnalytics(settings); + this.Platform.SetupAds(); - protected override void LoadContent() { - base.LoadContent(); + this.Tutorial = new Tutorial(); if (!SaveHandler.Load(this)) this.Map = new ParkMap(20, 20); + // load other stuff this.Ui = new Ui(this.UiSystem); this.Camera = new Camera(this.GraphicsDevice) { Scale = 4, @@ -56,32 +65,32 @@ namespace TouchyTickets { MaxScale = 24, MinScale = 2 }; - - CoroutineHandler.Start(this.Ui.DisplaySplash()); } protected override void DoUpdate(GameTime gameTime) { base.DoUpdate(gameTime); - var now = DateTime.Now; - if (this.LastUpdate != default) { - var passed = now - this.LastUpdate; - // if more than 1 second passed, the app is minimized or a save was loaded, so we penalize - if (passed.TotalSeconds >= 1) - passed = new TimeSpan(passed.Ticks / 2); - this.Map.Update(gameTime, passed); - } - this.LastUpdate = now; + if (this.Map != null) { + var now = DateTime.Now; + if (this.LastUpdate != default) { + var passed = now - this.LastUpdate; + // if more than 1 second passed, the app is minimized or a save was loaded, so we penalize + if (passed.TotalSeconds >= 1) + passed = new TimeSpan(passed.Ticks / 2); + this.Map.Update(gameTime, passed); + } + this.LastUpdate = now; - this.Ui.Update(gameTime); - this.Tutorial.Update(this); - - // save every 3 seconds - this.saveCounter += gameTime.ElapsedGameTime.TotalSeconds; - if (this.saveCounter >= 3) { - this.saveCounter = 0; - SaveHandler.Save(this); + // save every 3 seconds + this.saveCounter += gameTime.ElapsedGameTime.TotalSeconds; + if (this.saveCounter >= 3) { + this.saveCounter = 0; + SaveHandler.Save(this); + } } + + this.Ui?.Update(gameTime); + this.Tutorial?.Update(this); } protected override void DoDraw(GameTime gameTime) { diff --git a/TouchyTickets/Analytics.cs b/TouchyTickets/Platform.cs similarity index 55% rename from TouchyTickets/Analytics.cs rename to TouchyTickets/Platform.cs index a661394..e4142c9 100644 --- a/TouchyTickets/Analytics.cs +++ b/TouchyTickets/Platform.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; namespace TouchyTickets { - public abstract class Analytics { + public abstract class Platform { - public abstract void Setup(Dictionary json); + public abstract void SetupAds(); + + public abstract void SetupAnalytics(Dictionary json); public abstract void AddResourceEvent(bool sink, string currency, float amount, string itemType, string itemId); diff --git a/TouchyTickets/SaveHandler.cs b/TouchyTickets/SaveHandler.cs index a1a4b26..a90ccf4 100644 --- a/TouchyTickets/SaveHandler.cs +++ b/TouchyTickets/SaveHandler.cs @@ -25,8 +25,7 @@ namespace TouchyTickets { Stars = game.Stars, TimesRestarted = game.TimesRestarted, Upgrades = game.AppliedUpgrades.Select(u => u.Name).ToList(), - TutorialStep = game.Tutorial.CurrentStep, - ReadAnalyticsInfo = game.ReadAnalyticsInfo + TutorialStep = game.Tutorial.CurrentStep }; Serializer.Serialize(stream, data); } @@ -49,7 +48,6 @@ namespace TouchyTickets { foreach (var name in data.Upgrades) game.AppliedUpgrades.Add(Upgrade.Upgrades[name]); game.Tutorial.CurrentStep = data.TutorialStep; - game.ReadAnalyticsInfo = data.ReadAnalyticsInfo; // version 1 had smaller maps if (data.SaveVersion <= 1) { diff --git a/TouchyTickets/Ui.cs b/TouchyTickets/Ui.cs index 8e60000..afcd15e 100644 --- a/TouchyTickets/Ui.cs +++ b/TouchyTickets/Ui.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Numerics; using Coroutine; @@ -28,19 +29,7 @@ namespace TouchyTickets { private bool finishingSwipe; public Ui(UiSystem uiSystem) { - InputHandler.EnableGestures(GestureType.HorizontalDrag, GestureType.FreeDrag, GestureType.Pinch, GestureType.Tap); this.uiSystem = uiSystem; - this.uiSystem.GlobalScale = 4; - this.uiSystem.AutoScaleWithScreen = true; - this.uiSystem.AutoScaleReferenceSize = new Point(720, 1280); - this.uiSystem.Style.Font = new GenericSpriteFont(MlemGame.LoadContent("Fonts/Regular")); - this.uiSystem.Style.PanelTexture = this.uiSystem.Style.ScrollBarBackground = new NinePatch(Texture[2, 1], 4); - this.uiSystem.Style.ButtonTexture = this.uiSystem.Style.ScrollBarScrollerTexture = new NinePatch(Texture[3, 1], 4); - this.uiSystem.Style.TextScale = 0.1F; - this.uiSystem.TextFormatter.AddImage("ticket", Texture[2, 0]); - this.uiSystem.TextFormatter.AddImage("star", Texture[3, 0]); - foreach (var modifier in AttractionModifier.Modifiers.Values) - this.uiSystem.TextFormatter.AddImage(modifier.Name, modifier.Texture); // main ticket store ui var rainingTickets = new List(); @@ -174,7 +163,7 @@ namespace TouchyTickets { yesNoUi.AddChild(new Button(Anchor.AutoInlineIgnoreOverflow, new Vector2(0.5F, 30), Localization.Get("Place")) { OnPressed = e2 => { GameImpl.Instance.Tickets -= price; - GameImpl.Instance.Analytics.AddResourceEvent(true, "Tickets", price, "Attraction", attraction.Key); + GameImpl.Instance.Platform.AddResourceEvent(true, "Tickets", price, "Attraction", attraction.Key); map.Place(map.PlacingPosition, map.PlacingAttraction); this.FadeUi(false, () => this.uiSystem.Remove(e2.Root.Name)); @@ -241,7 +230,7 @@ namespace TouchyTickets { var price = attraction.GetModifierPrice(map.PlacingModifier); GameImpl.Instance.Tickets -= price; - GameImpl.Instance.Analytics.AddResourceEvent(true, "Tickets", price, "Modifier", modifier.Name); + GameImpl.Instance.Platform.AddResourceEvent(true, "Tickets", price, "Modifier", modifier.Name); attraction.ApplyModifier(map.PlacingModifier); }, @@ -305,8 +294,8 @@ namespace TouchyTickets { this.uiSystem.Remove(e2.Root.Name); var game = GameImpl.Instance; - game.Analytics.AddResourceEvent(true, "Tickets", (long) game.Tickets, "Restart", "Restart" + game.TimesRestarted); - game.Analytics.AddResourceEvent(false, "Stars", game.GetBuyableStars(), "Restart", "Restart" + game.TimesRestarted); + game.Platform.AddResourceEvent(true, "Tickets", (long) game.Tickets, "Restart", "Restart" + game.TimesRestarted); + game.Platform.AddResourceEvent(false, "Stars", game.GetBuyableStars(), "Restart", "Restart" + game.TimesRestarted); game.Stars += game.GetBuyableStars(); game.TimesRestarted++; @@ -381,41 +370,64 @@ namespace TouchyTickets { } } - public IEnumerator DisplaySplash() { + public static void SetupUiSystem(UiSystem uiSystem) { + InputHandler.EnableGestures(GestureType.HorizontalDrag, GestureType.FreeDrag, GestureType.Pinch, GestureType.Tap); + uiSystem.GlobalScale = 4; + uiSystem.AutoScaleWithScreen = true; + uiSystem.AutoScaleReferenceSize = new Point(720, 1280); + uiSystem.Style.Font = new GenericSpriteFont(MlemGame.LoadContent("Fonts/Regular")); + uiSystem.Style.PanelTexture = uiSystem.Style.ScrollBarBackground = new NinePatch(Texture[2, 1], 4); + uiSystem.Style.ButtonTexture = uiSystem.Style.ScrollBarScrollerTexture = new NinePatch(Texture[3, 1], 4); + uiSystem.Style.TextScale = 0.1F; + uiSystem.TextFormatter.AddImage("ticket", Texture[2, 0]); + uiSystem.TextFormatter.AddImage("star", Texture[3, 0]); + foreach (var modifier in AttractionModifier.Modifiers.Values) + uiSystem.TextFormatter.AddImage(modifier.Name, modifier.Texture); + } + + public static IEnumerator DisplaySplash(Action loadGame) { var splash = new Group(Anchor.TopLeft, Vector2.One, false) { OnDrawn = (e, time, batch, alpha) => batch.Draw(batch.GetBlankTexture(), e.DisplayArea, Color.Black * alpha) }; var center = splash.AddChild(new Group(Anchor.Center, new Vector2(0.5F, 0.5F), false) {DrawAlpha = 0}); center.AddChild(new Image(Anchor.AutoCenter, new Vector2(1, -1), Texture[4, 0])); center.AddChild(new Paragraph(Anchor.AutoCenter, 10000, "A game by Ellpeck", true)); - this.uiSystem.Add("Splash", splash).Priority = 100000; + GameImpl.Instance.UiSystem.Add("Splash", splash).Priority = 100000; while (center.DrawAlpha < 1) { center.DrawAlpha += 0.015F; yield return new WaitEvent(CoroutineEvents.Update); } - yield return new WaitSeconds(1); - while (center.DrawAlpha > 0) { - center.DrawAlpha -= 0.015F; - yield return new WaitEvent(CoroutineEvents.Update); - } - if (!GameImpl.Instance.ReadAnalyticsInfo) { + yield return new WaitSeconds(0.5); + + var analyticsFlag = new FileInfo(Path.Combine(SaveHandler.GetGameDirectory(true).FullName, "_ReadGdpr")); + if (!analyticsFlag.Exists) { var evt = new Event(); var panel = splash.AddChild(new Panel(Anchor.Center, new Vector2(0.8F), Vector2.Zero, true)); panel.AddChild(new Paragraph(Anchor.AutoLeft, 1, Localization.Get("GDPRInfo"))); panel.AddChild(new Button(Anchor.AutoLeft, new Vector2(1, 30), Localization.Get("Okay")) { OnPressed = e2 => { - GameImpl.Instance.ReadAnalyticsInfo = true; + // create the (empty) flag file + using (analyticsFlag.Create()) { + } splash.RemoveChild(panel); CoroutineHandler.RaiseEvent(evt); } }); yield return new WaitEvent(evt); } + + yield return new WaitSeconds(0.25); + loadGame(); + yield return new WaitSeconds(0.25); + while (center.DrawAlpha > 0) { + center.DrawAlpha -= 0.015F; + yield return new WaitEvent(CoroutineEvents.Update); + } while (splash.DrawAlpha > 0) { splash.DrawAlpha -= 0.015F; yield return new WaitEvent(CoroutineEvents.Update); } - this.uiSystem.Remove(splash.Root.Name); + splash.System.Remove(splash.Root.Name); } private void FadeUi(bool fadeOut, Action after = null) { @@ -481,7 +493,7 @@ namespace TouchyTickets { ChildPadding = new Vector2(4), OnPressed = e => { GameImpl.Instance.Stars -= upgrade.Price; - GameImpl.Instance.Analytics.AddResourceEvent(true, "Stars", upgrade.Price, "Upgrade", upgrade.Name); + GameImpl.Instance.Platform.AddResourceEvent(true, "Stars", upgrade.Price, "Upgrade", upgrade.Name); GameImpl.Instance.AppliedUpgrades.Add(upgrade); upgrade.OnApplied(); diff --git a/iOS/IosAnalytics.cs b/iOS/IosPlatform.cs similarity index 69% rename from iOS/IosAnalytics.cs rename to iOS/IosPlatform.cs index beab830..a4b2780 100644 --- a/iOS/IosAnalytics.cs +++ b/iOS/IosPlatform.cs @@ -5,9 +5,13 @@ using GameAnalyticsSDK.Utilities; using TouchyTickets; namespace iOS { - public class IosAnalytics : Analytics { + public class IosPlatform : Platform { - public override void Setup(Dictionary json) { + public override void SetupAds() { + throw new System.NotImplementedException(); + } + + public override void SetupAnalytics(Dictionary json) { GameAnalytics.Initialize(GA_MiniJSON.JsonEncode(new Hashtable(json))); } diff --git a/iOS/Program.cs b/iOS/Program.cs index 5af47fa..b2fd6ac 100644 --- a/iOS/Program.cs +++ b/iOS/Program.cs @@ -11,7 +11,7 @@ namespace iOS { private static void RunGame() { TextInputWrapper.Current = new TextInputWrapper.Mobile(); - game = new GameImpl(new IosAnalytics()); + game = new GameImpl(new IosPlatform()); game.Run(); } diff --git a/iOS/iOS.csproj b/iOS/iOS.csproj index 472652d..91f63fc 100644 --- a/iOS/iOS.csproj +++ b/iOS/iOS.csproj @@ -111,7 +111,7 @@ - +