Code Monkey home page Code Monkey logo

Comments (10)

alamboley avatar alamboley commented on May 22, 2024

Hi gsynuh,

swcs are very easy to use, but I use mostly code source to learn from the code ;)

In fact what you do at the moment is creating a new State and destroy it directly. The State hasn't got enough time to be created properly so you have an error.

It's really easy to create a new state :

public class Main extends StarlingCitrusEngine {

public function Main() {
    setUpStarling(true);
            state = new TiledMapGameState();

    setTimeout(otherState, 2000);
}

private function otherState():void {

    state = new TiledMapGameState2();
}

}

Also when you create a new state the previous one is automatically destroyed and garbage collected. Obviously you can destroy a state without associate a new one thanks to the destroy method.

The documentation is lacking on this part, I will create a code snippets right now!

No problem for the bug report. If it works well on your side now, I will close this issue. Just let me know.

Also it's very important for me to have feedbacks on the engine, so thanks again!

from citrus-engine.

gsynuh avatar gsynuh commented on May 22, 2024

I didn't know that destroy was called when a new state was created. this is obviously great news since I'm always looking to optimize the way memory is used etc... Thank you for this quick reply that solves my actual problem.

I did think of the fact that I was not letting it enough time, so I had tried to switch to another state when my hero was collecting a coin (leaving the state enough time to initialize and everything). But this led to another problem which you might be interested in :

following the tutorial, I learned about onBeginContact and the fact that I could add Functions.

//inside StateTest's initialize method
coin.onBeginContact.add(nextLevel) ;

where nextLevel is a method in my custom StarlingState calling a "switchstate" method through a reference to the main class extending StarlingCitrusEngine :

//inside StateTest
private function nextLevel(c:InteractionCallback):void
{
referenceToMain.switchstate();
}

//inside Main
public function switchstate():void
{
state.destroy();
state = new State2();
}

this threw a nape error which I'm not going talk about because I believe I'm already off topic.

But removing the call to the destroy function however, and simply creating a new state works as expected.

Like you said, creating a new state will destroy the previous one internally, and this is perfect for me, I'm not really used to have the work done on its own like that.

Is it simply because calling destroy before the creation of a new state is always too soon in any case (it seems counterintuitive though) and should/could never be done without having an error.

Anyway I'm probably overthinking it, maybe because it's exciting stuff.

You can close this Issue or even remove it for the sake of keeping this board clear (next time I'll think about what I'm doing twice, read more into it, and use the forums for more conceptual discussions).

Thank you again, have a nice day

from citrus-engine.

alamboley avatar alamboley commented on May 22, 2024

Glad to hear it solves your issue. I wrote a snippet there : https://gist.github.com/4030440

I tried to destroy the state and create a new one and it worked as expected. That's my code :
public function Main() {

state = new OsmosGameState();

setTimeout(toto, 2000);          

}

private function toto():void {

state.destroy();

state = new OsmosGameState();

setTimeout(toto, 2000);

}
Here it will make a loop on the same game state, destroy & recreate it every 2 seconds. It uses Nape too.

Maybe you can provide me some samples from your code so I can reproduce it?

from citrus-engine.

gsynuh avatar gsynuh commented on May 22, 2024

Here is the real code I'm using, the two files Main.as and states/StateTest.as
https://gist.github.com/4030917
based on the gotoandlearn tutorial but without graphics.

I'm actually refering to the main class by having a static var in the main class which points to its instance. I know this not pretty but it was just a way of setting this up very fast.

(is the setTimeout method you're using supposed to be in StarlingCitrusEngine?)

from citrus-engine.

gsynuh avatar gsynuh commented on May 22, 2024

I realise that it could have something to do with the fact that what's happening is this is trying to destroy a state "within the state" itself. But my main goal is that when some goal is achieved in one level, I'd want to tell the "main game" that I want to go to the next level. maybe there simply is a much better way of managing that.
this snippet still works when i remove the state.destroy(); line though.

from citrus-engine.

alamboley avatar alamboley commented on May 22, 2024

The setTimeout is provided by flash: import flash.utils.setTimeout;

The static is ok ;) You can always access to the Citrus Engine from anywhere using CitrusEngine.getInstance() that's a static too ;)

There was a bug on the Nape Hero, I've pushed a commit in the src code.
I've the bug too on destroying the State but only if I touch the coin. If I use a timer no problem.
If I don't use the destroy method and associate a new state when I touch the coin that's ok!
If I just destroy the state without associate a new one, I've the problem too.

That's weird, I think this is due to the main loop, update aren't finished that we have already destroyed the state.

from citrus-engine.

gsynuh avatar gsynuh commented on May 22, 2024

I guess I won't be bothering you for a while now :)
thank you !

edit : the loop still tries to fetch a citrus object no longer indexed in _objects in the update in question, I understand why this could be but maybe you are looking into it right now. I don't have enough knowledge of your engine yet to help ... (I'm not really happy about that...)

from citrus-engine.

alamboley avatar alamboley commented on May 22, 2024

I'd some time to look deeper. The problem comes from this line in the state method :
var n:Number = _objects.length;
for (var i:int = 0; i < n; i++) {
var object:CitrusObject = _objects[i];

If I change this way it works :
for (var i:int = 0; i < _objects.length; i++) {
var object:CitrusObject = _objects[i];

It means that objects have been destroyed during an update.

We could add a var justDestroyState:Boolean = false; to the Citrus Engine class.
Using it like this on a contact : CitrusEngine.getInstance().justDestroyState = true;
And modify the main loop this way :
protected function handleEnterFrame(e:Event):void
{

if (!justDestroyState) {

    //Change states if it has been requested
    if (_newState)
    {
        if (_newState is State) {

            if (_state) {

                _state.destroy();
                removeChild(_state as State);
            }
            _state = _newState;
            _newState = null;

            addChildAt(_state as State, _stateDisplayIndex);
            _state.initialize();                    
        }
    }

    //Update the state
    if (_state && _playing)
    {
        var nowTime:Number = new Date().time;
        var timeSinceLastFrame:Number = nowTime - _gameTime;
        var timeDelta:Number = timeSinceLastFrame * 0.001;
        _gameTime = nowTime;

        _state.update(timeDelta);
    }
} else {
    state.destroy();
}

}

Now it works well. Do you think that I should add this to the engine? We rarely destroy a state without adding a new one.

from citrus-engine.

gsynuh avatar gsynuh commented on May 22, 2024

Thanks for the "fix" with the for loop, because even if it doesn't change much for people, it is a more logical way of looping into a changing array of objects... and maybe this might correct a bug that would've occurred later on with someone messing around with the objects while they are getting updated.

I do not really see a reason to have "justDestroyState" implemented in the engine as 99% of people will not need that (maybe only I will?).

Here is a thought, related to the destroy() issue :

I was thinking of making some kind of level editor (using my own data structure) in which I could "simulate" the game after having built the level data with a simple flash graphic ui.

In such a case, it would be needed to actually stop and destroy the entire game before going back to the editor. However this leads to further problems . when destroyed, the game destroys the _input elements which turns _keysReleased to null... but the input.update loop comes in, and suddenly this line breaks everything :

_keysReleased.length = 0;

because keysReleased is null of course.
Other things start to happen which I will not mention, but always related to the updates happening after the actual destruction of things, when this should happen the other way around in a perfect world.

After changing a couple of lines, I managed to destroy the game when the coin was collected. But the nape ShapeDebug graphics were still on screen. this is where I stopped my little tests because it was getting too far.

The Level Editor idea with the capability to try the created level without having to switch application means the actual StarlingCitrusEngine will be at least "two levels down" with the main class, so having the ability to destroy the game to be tested with the created level and then starting the game back again would be great.

I know that I could forget about this idea and simply "leave the game running" in the background and simply hide it, and switch back to flash graphics, but it just feels wrong.

Those are really specific ideas that should be debated somewhere else, if I manage to do that someday I will approach the concepts on forums rather than on this issue reporter.

For now I guess this issue should be closed, I hope I made sense, thank you for your time !

from citrus-engine.

alamboley avatar alamboley commented on May 22, 2024

In fact, I haven't pushed the modification of the for loop. Concerning performances it isn't great to use _objects.length in a for loop. At each iterations, it will recalculate the length of the array.
We must not update objects while they are destroyed.

Concerning Nape ShapeDebug, it is not on Starling but on the flash display list. That's why it shouldn't be destroyed through the StarlingState but via the StarlingCitrusEngine. When we change the state it works fine. Again I'm not sure that state.destroy() is something which will be use.

I've not pushed the justDestroyState property. We will see if it's a problem for people. We may override the global update method the same way in our Main class.

I'm waiting for more feedbacks on this.

Well, we were thinking to a live editor mode too. For example on mobile, you could be able to move objects and then export an xml where you will have the new object positions and things like that.

Have you tried Flash Pro as a level editor? It is supported by the CE in a nice way.
Also the console helps to move objects and tests lots of things.

In fact, I think that you just need to refresh/reload your state and don't destroy the CE. This destroy method was made if the CE is just a game added in a website, to remove it properly.

Well this is a very interesting discussion with many good ideas. I close this issue and I invite you to continue the thread on Starling's forum to share ideas with the world ;)

from citrus-engine.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.