shuffle analytics and ad loading around after the gdpr message
This commit is contained in:
parent
c1438464cd
commit
6408be7646
11 changed files with 136 additions and 104 deletions
|
@ -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);
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Activity1.cs" />
|
||||
<Compile Include="AndroidAnalytics.cs" />
|
||||
<Compile Include="AndroidPlatform.cs" />
|
||||
<Compile Include="Resources\Resource.Designer.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -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<string, object> 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
41
Android/AndroidPlatform.cs
Normal file
41
Android/AndroidPlatform.cs
Normal file
|
@ -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<string, object> 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -12,23 +12,32 @@ namespace TouchyTickets {
|
|||
|
||||
public static GameImpl Instance { get; private set; }
|
||||
public readonly ISet<Upgrade> AppliedUpgrades = new HashSet<Upgrade>();
|
||||
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<string, object>();
|
||||
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) {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace TouchyTickets {
|
||||
public abstract class Analytics {
|
||||
public abstract class Platform {
|
||||
|
||||
public abstract void Setup(Dictionary<string, object> json);
|
||||
public abstract void SetupAds();
|
||||
|
||||
public abstract void SetupAnalytics(Dictionary<string, object> json);
|
||||
|
||||
public abstract void AddResourceEvent(bool sink, string currency, float amount, string itemType, string itemId);
|
||||
|
|
@ -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) {
|
||||
|
|
|
@ -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<SpriteFont>("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<RainingTicket>();
|
||||
|
@ -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<IWait> 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<SpriteFont>("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<IWait> 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();
|
||||
|
|
|
@ -5,9 +5,13 @@ using GameAnalyticsSDK.Utilities;
|
|||
using TouchyTickets;
|
||||
|
||||
namespace iOS {
|
||||
public class IosAnalytics : Analytics {
|
||||
public class IosPlatform : Platform {
|
||||
|
||||
public override void Setup(Dictionary<string, object> json) {
|
||||
public override void SetupAds() {
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override void SetupAnalytics(Dictionary<string, object> json) {
|
||||
GameAnalytics.Initialize(GA_MiniJSON.JsonEncode(new Hashtable(json)));
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
<Reference Include="Xamarin.iOS" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="IosAnalytics.cs" />
|
||||
<Compile Include="IosPlatform.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
|
Loading…
Reference in a new issue