Windows Phone - access HTML5/javascript game global variable in C# - c#

I have a Windows Phone 8 solution with the HTML5 template. My game is in a game.js file and I have a script in the webbrowser's body tag implementing my game. The game works as it should.
However, I have some problems with the hardware back button in Windows Phones. It closes my application, and I have tried overriding it, but I need to detect when the user is actually playing or is already in the menu screen, so I can let the app decide whether to go back to the menu or close the app.
I am thinking about using a global variable in my javascript/HTML5 game:
var IsPlaying = false
when the user clicks the start button on the main menu, IsPlaying becomes true.
When the user clicks the hardware back button, I want to evaluate the value of IsPlaying on my override method:
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
bool IsPlaying = //Get value from game
if (IsPlaying == true)
{
Browser.Navigate(new Uri(MainUri, UriKind.Relative)); //Restarts the game, thus bringing the user to the main menu
e.Cancel = true; //Cancels the default behavior.
}
}
So my question is, how can I retrieve the value of IsPlaying from the game?
Thanks

You can use the WebBrowser.InvokeScript method to execute a Javascript function from your C# code and retrieve the return value. So you can just write a function in your Javascript to return the value of the IsPlaying variable, then retrieve the value on the C# side by using InvokeScript.

Related

Xamarin Web container avoid back button close the application

I'm new to Xamarin, I'm using this example as a base for my on application.
I just noticed when I click back button the application get closed, I would like to avoid that.
do you have some hints and recommendations, maybe examples?
In your Content Page who will have to override the OnBackButtonPressed event and return true. You must return true because it signifies that the developer has handled the implementation of the back button click.
protected override bool OnBackButtonPressed()
{
return true;
}

Unity - Navigation for performance on mobile

In case of a Unity mobile app, would it be good (at all) for performance, to deactivate the navigation through canvas objects like TextFields and Buttons?
When selecting e.g. a Button or TextField in the sceneview, the inspector shows the option "Navigation", which can be set to different things and can also be visualized. This feature is usually used to tab through input fields, like you would expect it on a website. On my mobile game I don't need this "tabbing". Would there be any sort of performance increase if I deactivated it everywhere?
Would deactivating this rather be a waste of time, or even make
performance worse for some obscure reason?
Usually there are 3 ways to show and hide UI. I will list them from worst to best.
1.Instantiate (Show), Destroy (Hide).
public GameObject uiPanelPrefab;
void Start()
{
//Show
Instantiate(uiPanelPrefab);
//Hide
Destroy(uiPanelPrefab);
}
This creates and destroys Objects each time. (Not Recommended).
2.Activate (Show) or Deactivate (Hide) the GameObject of that UI.
public GameObject uiPanelPrefab;
void Start()
{
//Show
uiPanelPrefab.SetActive(true);
//Hide
uiPanelPrefab.SetActive(false);
}
This creates garbage each time it is set to active and also cause quick freezes. You will notice this a lot when making VR apps. Fine on Desktops. Not good or recommended on mobile devices.
3.Enable (Show) or Disable (Hide) the Component of that UI.
public GameObject uiPanelPrefab;
void Start()
{
//Show
uiPanelPrefab.GetComponent<Image>().enabled = true;
//Hide
uiPanelPrefab.GetComponent<Image>().enabled = false;
}
This simply enables and disables the components. This method requires a custom function for each UI Control such as Button, Text, InputField as each Control has different components attached to them. This is the recommended method especially on mobile devices.
After long experiment with these, I came to conclusion that #3 is the best and should be used.The downside is that you have to make a function that will disable every components of each UI Control.
For example, the Button Control has more than 1 components. Simply disabling the Button component will not do it. You have to write a simple function that will disable Button, Image and Text components. Something like below:
void showButton(GameObject button, bool show, bool includeInactive = false)
{
Button bt = button.GetComponentInChildren<Button>(includeInactive);
bt.enabled = show;
Text txt = button.GetComponentInChildren<Text>(includeInactive);
txt.enabled = show;
Image img = button.GetComponentInChildren<Image>(includeInactive);
img.enabled = show;
}
Usage:
//Show
showButton(uiPanelPrefab, true);
//Hide
showButton(uiPanelPrefab, false);
I can confirm, that deactivating the navigation of UI elements has no performance influence. Behind the scenes there's just a handler, that gets triggered, when you hit "tab" on pc, or analogeously on mobile.

Pressing toggle button in toggle group calls more than one button

In my unity game I have two toggle buttons that are both in a toggle group together. They are buttons that are labeled "On" and "Off" for turning the game music on and off.
The way I have it set up right now makes it behave very strange. If the music is on and I click the "Off" toggle, the music turns off. Then if I hit "On" again, I get a null object reference error and the check mark doesn't show up in the "On" toggle button until I hit "On" a second time and then the sound comes back on. The really weird part is that when it turns back on, a gameobject is created for the musicplayer, of course. When I try to turn it off again, the music stays on and a second musicplayer gameobject is created. I don't understand what is going on.
void Start ()
{
checkWhatsOn();
}
void checkWhatsOn()
{
bool sound = PlayerPrefs.GetInt("Sound Playing", 1) == 1;
//if (sound) soundToggle.isOn = true; //THESE TWO STATEMENTS
//else soundToggle.isOn = false; //ARE CAUSING THE ISSUE!!
}
public void switchSound()
{
print (string.Format("In switch method sound is {0}", PlayerPrefs.GetInt("Sound Playing", 6)));
bool sound = PlayerPrefs.GetInt("Sound Playing", 1) == 1;
if (sound)
{
if (GameObject.FindObjectOfType<MusicPlayer>() != null)
{
PlayerPrefs.SetInt("Sound Playing", 0);
PlayerPrefs.Save();
GameObject.FindObjectOfType<MusicPlayer>().GetComponent<MusicPlayer>().Disable();
}
else print ("Sound wasn't changed, MusicPlayer needs to be null.");
}
else if (!sound)
{
PlayerPrefs.SetInt("Sound Playing", 1);
PlayerPrefs.Save();
if (GameObject.FindObjectOfType<MusicPlayer>() == null)
{
musicPlayer = Instantiate (Resources.Load ("MusicPlayer")) as GameObject;
GameObject.DontDestroyOnLoad(musicPlayer);
}
else print ("Sound wasn't changed, MusicPlayer shouldn't be null.");
}
print (string.Format("After switch method sound is {0}", PlayerPrefs.GetInt("Sound Playing", 7)));
}
In the inspector I have the "On" button call the function above while passing in a 1. When "Off" pressed, it calls the same function with a 0.
9/2/14
I have updated my code using only one toggle button. The toggle button calls a method which checks the PlayerPrefs to see whether the sound should be on or not. I still end up with an issue when I move from one scene into the scene that has the toggle button in it. When I do that, the music stops. It is for some reason calling the method that should only be called when the toggle button is pressed. Any ideas?
9/4/15
After testing what Thaina had told me (code updated above), I narrowed my issue down to the fact that if I try to set my toggle button to on, it automatically calls the function that is attached to the toggle. I only want to have the function called if it is pressed, not when setting it's saved state. Is there a way to do this?
SOLUTION
I ended up just letting the toggle.isOn call the function that it was trying to access and used a static bool to only let it access certain code when I wanted it to. Thaina's answer is what got me far enough to get to that point so credit goes to Thaina.
I suggest you should use GameObject.FindObjectOfType<MusicPlayer>(). So you can be sure that it will get MusicPlayer in the scene
I suspect that your MusicPlayer object is actually named "MusicPlayer " not "MusicPlayer". Anyway get object by its name is bad idea in my opinion. It prone to error

Windows Phone alarm constantly turning itself back on

I'm trying to write an alarm clock app for Windows Phone that requires the user to solve a math problem upon the ringing of the alarm. Right now I'm stuck, I've got the MainPage containing the settings for turning on the alarm, and when the alarm rings the user is redirected to another xaml page, one that requires the user to enter the answer to a randomly generated math problem in order to turn off the alarm. My problem is, once the user solves the problem and taps the check box, the app is supposed to first set the alarmSet value to false, and redirect the user back to the mainPage:
private void Solve_Click(object sender, EventArgs e)
{
this.userSolve = Convert.ToInt32(answerInput.Text);
if (userSolve != answer)
{
MessageBox.Show("Incorrect");
//userAnswerInt = Convert.ToInt32(answerInput.Text);
}
else if (userSolve == answer)
{
MainPage.alarmSet.Value = false;
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
}
And then when the user arrives at the mainPage, the OnLoaded method is supposed to stop the alarm sound and reset everything back to normal:
public async void OnLoaded(object sender, EventArgs e)
{
this.timer.Stop();
this.alarmSound.Stop();
alarmSet.Value = false;
this.notificationSwitch.IsChecked = alarmSet.Value;
this.timePicker.Value = new DateTime(1, 1, 1,
alarmTime.Value.Hours,
alarmTime.Value.Minutes,
0
);
if (alarmSet.Value == true)
this.alarmTimeText.Text = alarmTimeString;
else if (alarmSet.Value == false)
this.alarmTimeText.Text = "alarm off";
But the problem is, every time the user solves the math problem, they're taken back to the main page and immediately redirected back to the alarm ringing page, because the alarm is still turned on. This creates an infinite loop of alarms overlapping each other, and I can't figure out why, even though I set alarmSet.Value to false before navigating back to the main page, the alarm is still seen as on... is there something more I need to be doing? How can I have the alarm on and set to the current minute the clock is at without it ringing immediately?
I do not see an "OnLoaded" event on the Application life cycle for Windows Phone.
Refer: http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff817008(v=vs.105).aspx
You may do the following:
In Mainpage.xaml, see if the alarm is running and if the alarmSet is true, redirect user to next page under onNavigatedTo Event.
In next page, set alarmSet as false and redirect user to MainPage.xaml. The onNavigatedTo will again be fired, however, since alarmSet is false, user wont be redirected anywhere. You may do the else case of stopping alarm or anything further here.

How does one navigate back to their desired page on WP8 after having the app run in the background?

I am currently writing a running tracker, and I want it to be possible for the user to have my application running in the background.
Everything is fine when running it in the background, but whenever I re-open the app, it puts me back at the main menu.
In the end, I want access to the RootFrame.BackStack, so that the user can pick up where they left off.
I tried the following code in my App.xaml.cs but it threw a "InvalidOperationException" at the attempt to access RootFrame.BackStack.GetEnumerator().Current.
Note: I checked, and all values before Current are non-null.
private void Application_Activated(object sender, ActivatedEventArgs e)
{
JournalEntry j;
if (RootFrame.BackStack.GetEnumerator().Current != null)
j = RootFrame.BackStack.GetEnumerator().Current;
RunningInBackground = false;
}
What you're looking for is called Fast App Resume:
Windows Phone 8 introduces the ability for apps to request that user
actions that would typically relaunch the app, such as tapping the
app’s Start Tile, instead resume the suspended instance of the
suspended app instance, if one exists. This feature is called Fast
Resume.
To enable Fast Resume for your app, add the ActivationPolicy attribute to the DefaultTask element in WMAppManifest.xml and set the value to “Resume”.
<DefaultTask Name="_default" NavigationPage="MainPage.xaml" ActivationPolicy="Resume"/>
try this sample link. I hope this is what you are looking for. http://code.msdn.microsoft.com/wpapps/Fast-app-resume-backstack-f16baaa6

Categories

Resources