HaxeFlixel - FlxSubState unexpected null object reference - haxe

Im trying to make simple ingame menu. Im using FlxSubState class. First im trying invoke substate in main game state with openSubState(gameMenu); after pressing Esc.
There is code in my substate class, this class inheriting FlxSubState:
override public function create():Void
{
super.create();
continueButton = new FlxButton(0,0, "Continue", continueGame);
continueButton.x = FlxG.width / 2 - continueButton.width / 2;
continueButton.y = FlxG.height / 2 - continueButton.height / 2;
add(continueButton);
}
private function continueGame():Void
{
close();
}
Problem is : everytime after click on continueButton game crash with null exception in FlxTypedGroup. I think its in close(); method but i really cannot figure it out. Can anyone help me ?
Or suggest better way to implement ingame menu ?

Figured it out by myself.
Looks like that after closing substate is destroyed. So something like this
override public function create():Void
{
super.create();
gameMenu = new MySubstate();
}
using with this
openSubState(gameMenu);
wont work.
Instead i need to create new substate directly
openSubState(new MySubstate());

Related

how to invoke an event on a key press

I am making a gambling game in graphics. There are three polygons on screen reading below 3, above 3 and throw a dice. I will incorporate random function generator in throw a dice area. And define two functions when a user enters the area of the rest of two polygons. But I am facing the problem of how to add functions here and how to invoke those function on keypress. Please suggest.
I think should have mentioned the language you are using to code, In case of java swing i have a good solution.
Depending on where you want to trap the "enter" key, you could use an ActionListener (on such components such as text components or buttons) or attach a key binding to your component.
Here is the link how to use Key binding
public class MyPanel extends JPanel {
public MyPanel() {
InputMap im = getInputMap(WHEN_FOCUSED);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "onEnter");
am.put("onEnter", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
// Enter pressed
}
});
}
}
Actually i didn't understand your question, secondly if you are trying to nesting the events you can use threading i have link --Threading with swing.
you can check your question context here and apply it.
Ok and this is all for java, if you are working with other prog. language then please comment.
Thanks..

Unity3D : Retry Menu (Scene Management)

I'm making a simple 2D game for Android using the Unity3D game engine. I created all the levels and everything but I'm stuck at making the game over/retry menu. So far I've been using new scenes as a game over menu. I used this simple script:
#pragma strict
var level = Application.LoadLevel;
function OnCollisionEnter(Collision : Collision)
{
if(Collision.collider.tag == "Player")
{
Application.LoadLevel("GameOver");
}
}
And this as a 'menu':
#pragma strict
var myGUISkin : GUISkin;
var btnTexture : Texture;
function OnGUI() {
GUI.skin = myGUISkin;
if (GUI.Button(Rect(Screen.width/2-60,Screen.height/2+30,100,40),"Retry"))
Application.LoadLevel("Easy1");
if (GUI.Button(Rect(Screen.width/2-90,Screen.height/2+100,170,40),"Main Menu"))
Application.LoadLevel("MainMenu");
}
The problem stands at the part where I have to create over 200 game over scenes, obstacles (the objects that kill the player) and recreate the same script over 200 times for each level. Is there any other way to make this faster and less painful?
Edit : If possible,please when you suggest your ideas,use javascript only,I don't understand C#,not even a little bit.I know Im asking too much but it realy confuses me.
Thank you.
There are several different solutions, but I would recommend using PlayerPrefs. This has the extra benefit of persisting even when the application is closed and then re-opened.
In your Awake() function of your Main Menu class, you can get the current level and store it in a static string of your Main Menu class. If it is the player's 1st time, use the name for level 1.
Something like this:
static string currentLevelName;
void Awake()
{
currentLevelName = PlayerPrefs.GetString("CurrentLevel");
if (currentLevelName == defaultValue)
{
currentLevelName = "Level1"
}
}
Then, modify your button to do this instead:
if (GUI.Button(Rect(Screen.width/2-60,Screen.height/2+30,100,40),"Retry"))
Application.LoadLevel(currentLevelName);
Whenever the player advances to the next level, set the string in PlayerPrefs to the new level name:
PlayerPrefs.SetString("CurrentLevel", Application.loadedLevelName);
You can create a class with static properties. For example (in c#)
public class GameOverInput
{
public static string name;
public static string retryLevel;
//all the info you need
}
Then you can easily read the input in your game over scene (only one is needed)
public class GameOverMenu : MonoBehavior
{
void Start()
{
Debug.Log("You were killed by " + GameOverInput.name);
Application.LoadLevel(GameOverInput.retryLevel);
}
}
And you set this info just before loading the game over scene
if (Collision.collider.tag == "Player")
{
GameOverInput.name = "Baddie";
Application.LoadLevel("GameOver");
}
Another option would be to make something like a singleton LevelManager MonoBehavior and add it to an object named "Level Manager". Use the DontDestroyOnLoad function to make the object persist even when you load another level.
class LevelManager : MonoBehavior
{
static LevelManager _instance;
public string currentLevelName;
public string killedBy;
function Awake ()
{
if (_instance == null)
{
_instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject); // Make sure we never have more than 1 Level Manager.
}
}
LevelManager Instance
{
get
{
if (_instance == null)
{
GameObject levelManagerObject = GameObject.Find("Level Manager");
_instance = levelManagerObject.GetComponent<LevelManager>();
}
return _instance
}
}
}
Then, from the main menu class, you can always access the Level Manager like so:
Debug.Log("Killed by " + LevelManager.Instance.killedBy);
or
LevelManager.Instance.currentLevelName = Application.loadedLevelName;

Dialog values with MvvmCross, ActionBarSherlock and DialogFragment

I have a bunch of different libraries trying to work together and I'm pretty close but there's just one issue.
I have created a class called SherlockDialogFragment inheriting from SherlockFragment (rather than using the SherlockListFragment - this is because of the issue with the keyboard that's covered here). Here is my code:
public class SherlockDialogFragment : SherlockFragment
{
public RootElement Root
{
get { return View.FindViewById<LinearDialogScrollView>(Android.Resource.Id.List).Root; }
set { View.FindViewById<LinearDialogScrollView>(Android.Resource.Id.List).Root = value; }
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignored = base.OnCreateView(inflater, container, savedInstanceState);
var layout = new LinearLayout(Activity) { Orientation = Orientation.Vertical };
var scroll_view = new LinearDialogScrollView(Activity)
{
Id = Android.Resource.Id.List,
LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.FillParent)
};
layout.AddView(scroll_view);
return layout;
}
}
I then do the regular thing of creating an eventsource class which inherits from this but also uses IMvxEventSourceFragment, then the actual fragment class (which I call MvxSherlockDialogFragment) which inherits the eventsource class, as well as IMvxFragmentView.
That all works fine (and indeed I've created a SherlockDialogActivity the same way and it's fine), however the one issue is when I use this fragment on a screen with tabs (i'm using a class I made similarly to above called MvxSherlockFragmentActivity). When switching to the tab with the dialog, the view appears fine, even with pre-populated data. However the issue is when I switch away from that fragment/tab, and then back to it, the dialog elements all have the same value.
In my particular example, it's a login page with a username and password. When I first go into the fragment, everything is fine. When I go out and back in, the password value is in both the username field and the password field.
I'm sure it's got something to do with the SherlockDialogFragment class - in the SherlockDialogActivity class I also have this bit:
public override void OnContentChanged()
{
base.OnContentChanged();
var list = FindViewById<LinearDialogScrollView>(Android.Resource.Id.List);
if (list == null)
{
throw new RuntimeException("Your content must have a ViewGroup whose id attribute is Android.Resource.Id.List and is of type LinearDialogScrollView");
}
list.AddViews();
}
However this doesn't work in a fragment because there's no OnContentChanged event. Also, another difference is that in the SherlockDialogActivity, the layout is being created ONCE in the OnCreate event - however in the SherlockFragmentActivity I've got it being created each time the fragment is viewed. I know that's probably not the best way, but I tried to do it in OnCreate and save it in a variable and then return that variable in OnCreateView, but android didn't like that...
Ok I feel like an idiot. I was creating/binding on OnViewCreated - however I need to do all my binding in OnStart - I think I was following some (possibly old) sample code from Stuart.
Obviously for a regular activity I'm using OnCreate but this doesn't work on a fragment, because the view is not initialised there - it's initialised at OnCreateView.
So for future reference - do all binding in OnStart!

WinForms Thread-safe Controls

I spend a lot of time working with Windows Forms controls but from a background worker thread - I suppose this is good practice really since you don't want your form to be locking up when people click buttons. To be honest, with just about everything GUI related action I normally do in a background worker thread, so the interface is nice an responsive to the user (Wish more people would do that!).
So my question is... every time I have to interact with controls I have to "Invoke" them, with something like:
if (control.InvokeRequired)
{
//
}
Standard practice right? However, this leads me to some terribly messy code, because just about every control type I have, I need a MethodInvoker delegate or something. It's adding thousands of lines of code to my protects, and its terribly time consuming.
I currently have hundreds of "property setting" methods like:
private void Safe_SetLableText(Label control, string text)
{
if (control.InvokeRequired)
{
control.Invoke((MethodInvoker)delegate
{
control.Text = text;
});
}
else
{
control.Text = text;
}
}
So, is there some other technique, or way to do this, or some way to being able to always alter a property of a control, no matter what the control is and no matter what thread im in?
something like: (pseudocode)
BackgroundWorker.RunWorkerAsync();
private void thing_to_do()
{
// We are in a background thread now
DoSomeDatabaseWorkThatTakesALongTime();
InvokeAnyControls();
// Do some stuff...
controlX.Text = "123"
controlY.Height = 300;
controlZ.text = ControlA.text;
RestoreAnyControls();
}
You could wrap your InvokeRequired code with a delegate, like so:
public static void Invoke2<TControl>(this TControl c, Action<TControl> code) where TControl : Control {
if( c.InvokeRequired ) c.Invoke( delegate() { code(c); } );
else code(c);
}
Then use it like so:
private void Safe_SetLableText(Label control, string text) {
control.Invoke2( c => c.Text = text );
}
Of course you might want better names than Invoke2, but I hope the idea sits will with you. Note that the lambda-expression syntax is a C# 3.0 feature, but the Action<T> delegate is part of .NET 2.0, so this will compile against the .NET Framework 2.0 so long as you're VS2008 or later.
I'm posting an answer to my own question because I think it will add value to the community.
1) I wanted to "simplify" my code, and one if the most important finds was that that the:
control.InvokeRequired
really isnt needed... its pretty much a given. Importantly, you CAN rely on the fact that the control will need to be invoked if you are in a background (or non-UI) thread.
2) The invocation travels "UP" the control tree, so if you have:
Form > Control > Control inside Control > etc > etc
You only need to invoke "Form" (top most), and then you can alter the properties of the child elements.
So here is my clean and simple solution to working with background workers (or non-UI threads). I have just tested this now and it works great.
public partial class Form1: Form
{
public Form1()
{
BackgroundWorker bgw = new BackgroundWorker();
bgw.DoWork += new DoWorkEventHandler(this.bgDoWork);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.bgComplete);
bgw.RunWorkerAsync();
}
private void bgComplete(object sender, EventArgs e)
{
// You are not in the UI thread now, so you can Invoke without error
this.Invoke((MethodInvoker)delegate
{
// Now you can change any property an any control within this form.
// Remember "this" refers to Form1.
this.label1.Text = "test123";
this.label2.Text = "test456";
this.label3.Text = this.label4.Text;
// You can set progress bars too, not just label text
}
}
private void bgDoWork(object sender, DoWorkEventArgs e)
{
// Do something that takes a long time
}
}
As you are already using the Background worker why don't you 'misuse' OnProgressChanged?
private void thing_to_do()
{
// We are in a background thread now
DoSomeDatabaseWorkThatTakesALongTime();
BackgroundWorker.ReportProgress(1, "state");
DoSomeMoreDatabaseWorkThatTakesALongTime();
BackgroundWorker.ReportProgress(2, YourObjectHere);
}
void OnProgressChanged(ProgressChangedEventArgs progressArgs)
{
switch(progressArgs.ProgressPercentage)
{
case 1:
// Do some stuff...
controlX.Text = "123"
controlY.Height = 300;
controlZ.text = ControlA.text;
break;
case 2:
// other stuff
YourObject obj = (YourObject) progressArgs.UserState;
// wahtever...
break;
default:
break;
}
}

Having trouble with AsyncTask using a recursive method

I've been reading about AsyncTasks and Hanlders and Loopers but I still can't figure out where I'm going wrong in my code. I'm trying to run code that will look over a Tic Tac Toe grid and determine the best move for the computer. I want this code to run in the background 'cause it can take some time and then I can update the UI level with a textbox that says something like "I'm Thinking". I've tried this a bunch of different ways, none with success.
private class PostTask extends AsyncTask<String, Integer, String> {
private Board _b;
private Welcome.Player _opp;
private int _depth;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
protected void SetVars(Board b, Player p, int depth){
_b = b;
_opp = p;
_depth = depth;
}
#Override
protected String doInBackground(String... params) {
Looper.prepare();
try{
_bestMove = _b.GetBestMove(_opp,_depth);
}
catch(Exception err){
_bestMove = -1;
}
return "All done";
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(_bestMove == -1){
TextView tv = (TextView) findViewById(R.id.tv_Score);
tv.setText("Had and error, couldn't make a move.");
}
FollowUpComputerMove(this);
}
The above code will work for exactly 5 moves and then it crashes. When I watch in the debugger I see new theads being created named Thread<#> AsyncTask #1. Once I get to five of those AsyncTasks it goes back to try and grab the first AsyncTask and crashes. When it crashes I'm shown the ThreadPoolExecutor.class file.
I've also read that I shouldn't be using both the AsyncTask and the Looper objects together so I've tried taking the Loooper.prepare() statement out, but then my AsyncTask fails immediately with the error message:
Can't create handler inside thread that has not called Looper.prepare() - AsyncTask inside a dialog
I've read repeatedly that you shouldn't be trying to update the UI from an AsyncTask and that often the above error is because of that, but GetBestMove isn't updating the UI thread. When I trace through to see where the error comes, it fails when calling a constructor saying it can't find the class.
Can anyone point me in the right direction? My end goal is to use one main thread and only one background thread, and just keep re-using the background thread whenever the computer needs to make a move. I know that the recursive method GetBestMove works when I run this program in a single-thread manner. But the screen freezes for too long on some moves as the method is being run. Thank you so much.
-NifflerX
Apologies for answering my own question, but the issue I was facing had nothing to do with recursion. The class I was calling was extending the class Activity, and while trying to call that from an AsyncTask the program was erroring out. When I removed the extends Activity from the class definition it started working again. Sorry for the post.
-NifflerX

Resources