Giter Site home page Giter Site logo

Comments (22)

bberak avatar bberak commented on May 22, 2024 1

I've found the bug.. The GameEngine uses a timer to run the systems at ~60 fps. However, there is a bug with how I'm clearing subscribers during unmounting which means a reference to the update function (and potentially the entire GameEngine) was being kept in memory - hence multiple GameEngines could be running at the same time.

This bug has been fixed in version 0.9.5

from react-native-game-engine.

bberak avatar bberak commented on May 22, 2024

Hi @lupino22,

Thanks for getting in touch. One of the the things I'm not currently happy with in the React Native Game Engine API is how the entities are updated externally.

Currently, the game engine will hold a reference to your initial entities and only reload when the whole GameEngine unmounts and remounts or when the swap method is called this.refs.gameEngine.swap( { NEW_ENTITIES }). This isn't intuitive at all - and I'll try dedicate some effort into fixing this.

Back to your issue in particular.. When you navigate away from your game and back again, is the component that contains your <GameEngine ref="gameEngine" ... /> being unmounted and remounted? If not, it means that your entities are not refreshing and you will need to swap them manually this.refs.gameEngine.swap(...)

Another thing to keep in mind is that your setInterval callback will always and only have a reference to the entities that get passed into world_scale the first time it is called. If the entities get swapped - and the timer is not finished - it will still have a reference to the old entities.

Lastly, what version of RNGE are you using? I pushed an update about a week ago that clears the events every time the swap and start methods are called. I don't think this is related, but it might help us figure out what is going wrong here.

Cheers!

from react-native-game-engine.

vonqo avatar vonqo commented on May 22, 2024

Hi @bberak

Game Engine component is remounted when i navigate back and i use this.refs.engine.swap(new World()); when components is mounted.

Also i managed the way to interrupt the intervals when game engine is unmounted.
i am currently using version 0.9.0. I will update the package as soon as possible.

I'll keep in touch. Thanks for the response.

from react-native-game-engine.

vonqo avatar vonqo commented on May 22, 2024

Is there any way to make timed animation (like world_scale). So i can replace my function without doing external update for entities. And i updated my RNGE, still same. i appreciated that swap function update to clear events. No needed to clear events by manually.

from react-native-game-engine.

bberak avatar bberak commented on May 22, 2024

Hi @lupino22,

I've built an "animation" system for one of my games that avoids the need to use external timers and callbacks. Perhaps you can adapt it to your needs. Here is the source of the animation: https://github.com/bberak/react-native-donkey-kong/blob/master/src/systems/animation.js

And here is an example of how to use the system:

export default (entities, { events }) => {
	const mario = entities.mario

        //-- Make sure your entity has an "animations" component, other wise you will get an undefined error
	mario.animations.jump = {
		args: {},
		duration: 700,
		animate(mario, percent, args) {
			//-- This will be called every frame 
			//-- whilst the animation is running. 
			//-- "percent" indicates how much of the 700ms animation has been completed
		},
		complete(mario) {
			//-- This will be called when the animation is completed
		}
	}
}

See https://github.com/bberak/react-native-donkey-kong/blob/master/src/systems/platforms.js for the full usage.

from react-native-game-engine.

vonqo avatar vonqo commented on May 22, 2024

Thanks @bberak

I believe doing by your "animation" system is more proper way than mine. I'll try your "animation" system. Thanks for your effort.

from react-native-game-engine.

bberak avatar bberak commented on May 22, 2024

No worries @lupino22, let me know how it goes!

from react-native-game-engine.

vonqo avatar vonqo commented on May 22, 2024

Hello @bberak
I replaced my functions using "animation". But still same :(
Entities are recreated every time when i reload RNGE, seems fine there. But system functions still working with previous entities. Is this might be navigation related problem?

from react-native-game-engine.

bberak avatar bberak commented on May 22, 2024

Hi @lupino22,

Well at least we can cross the animations off the list :)

You mentioned that the component is unmounted and re-mounted during the navigation process? Can you show me your render function? In particular, if you have something like this:

<GameEngine 
    entities={new World()} //-- The engine will receive new World() when it mounts
 />

Or

<GameEngine 
    entities={this.state.currentLevel} //-- The engine will receive this.state.currentLevel when it mounts
 />

Also, what does new World() return? Can you share a quick snippet to indicate the general code?

If you're using a third party library like ThreeJS or something - you might need to clean up your scene.. If your scene is holding references to the old objects - it could still get rendered.

Another way we can debug this would be to add a distinct entity into your world { "test": "Find me" } when the navigation occurs, and find and log this entity in your systems - that way you can be sure whether or not your systems are receiving the new entities or not.

Also make sure your systems are not holding any references to the entities after they are done. The systems should always process the entities being passed into them by the engine.

from react-native-game-engine.

vonqo avatar vonqo commented on May 22, 2024

Redering

componentDidUpdate() { // -- when audio asset is ready i will load my engine
	if (this.isReady && !this.state.running) { // -- audio ready && game engine is not running
		this.prepareGameEngine();
	}
}

prepareGameEngine = () => { // -- load the entities
	this.refs.engine.swap(new World());
	this.setState({  // -- GameEngine 'running' property gets this state
		running: true
	});
};

isGameReady() {  // -- Return false until audio asset is ready
	if (this.props.audio_ready) { // -- comes from redux
		this.playBackgroundAudio();
		this.isReady = true;
		return this.isReady;
	}
	this.isReady = false;
	return this.isReady;
}

render() {
	if (this.isGameReady()) {
		return (
			<GameEngine
				ref={'engine'}
				systems={System}
				running={this.state.running}
				onEvent={this.handleEvent} >
				<StatusBar hidden />
			</GameEngine>
		);
	}
	return (
		<LoadingScreen />
	);
}

World:

export default () => {
    const starting_scale = 1;
    return {
        background: new Background(
          { x: 0,
            y: 0 },
          starting_scale, 'night', { opacity: 1 }
        ),
        treeStack1: new TreeStack(
          { x: 800,
            y: 200 },
          starting_scale
        ),
        bird1: new Bird(
          { x: 680,
            y: 300 },
          starting_scale,
          [{ rotate: '0 deg' }]
        ),
    };
};

from react-native-game-engine.

vonqo avatar vonqo commented on May 22, 2024

Also i made something like this :p

export default (entities, { events, dispatch }) => {
  ...
  some_function(entities, events, dispatch);
  return entities;
};

const some_function = (entities, events, dispatch) => {
  ...
  dispatch({ type: EV_CONTROL_CAMERA_SCALE, value: 2, duration });
  dispatch({ type: EV_CONTROL_CAMERA_MOVE, value: { x: -250, y: -50 }, duration });
}

from react-native-game-engine.

bberak avatar bberak commented on May 22, 2024

Hi @lupino22,

Can you try changing your code to (just for debugging) to something like this:

<GameEngine
				ref={'engine'}
				systems={System}
				running={this.state.running}
                               entities={new World()}
				onEvent={this.handleEvent} >
				<StatusBar hidden />
			</GameEngine>

I say this because if your component is mounting and unmounting the game engine - then you probably don't need to swap manually.

Also change your entities to:

export default () => {
    const starting_scale = 1;
    return {
       test: { date: new Date() }, //-- I added this..
        background: new Background(
          { x: 0,
            y: 0 },
          starting_scale, 'night', { opacity: 1 }
        ),
        treeStack1: new TreeStack(
          { x: 800,
            y: 200 },
          starting_scale
        ),
        bird1: new Bird(
          { x: 680,
            y: 300 },
          starting_scale,
          [{ rotate: '0 deg' }]
        ),
    };
};

Then check the value of test in your systems and see what is being printed:

export default (entities, { events, dispatch }) => {
  console.log(entities.test.date)
  return entities;
};

Hopefully that will get us more info for debugging..

from react-native-game-engine.

vonqo avatar vonqo commented on May 22, 2024

Hi @bberak

I made changes that you've made and debugging
First time console shows date:

20:07:19
20:07:19
20:07:19
...

When i re navigate into game component

20:07:19
20:07:44
20:07:19
20:07:44
20:07:19
20:07:44
...

Look like i'm having multiple test entity. If re-navigate the component n times, then i'll have n times of individual time.

from react-native-game-engine.

bberak avatar bberak commented on May 22, 2024

So I wonder if it's possible that you have multiple instances of the GameEngine running? Could it be that each time your are navigating, your navigation system is adding another GameEngine into the viewstack, and not popping off the current GameEngine when you are navigating away?

from react-native-game-engine.

vonqo avatar vonqo commented on May 22, 2024

Yes i think so. I'm about to change my navigation library which is react-native-router-flux to react-native-navigation. Because react-native-navigation is this is the most actively maintained navigation library implemented natively. That makes sense to me. Also i was put some variables in "system file" to save the story sequence state. I should've put those things as "entity".

from react-native-game-engine.

bberak avatar bberak commented on May 22, 2024

Yeah that makes sense @lupino22. It might be worthwhile to put the componentWillUnmount() function on your component to determine whether or not the unmounting is happening or not:

componentWillUnmount() {
   console.log("I am unmounting")
}

from react-native-game-engine.

vonqo avatar vonqo commented on May 22, 2024

That is the one thing make me so confused. Component life cycle is just fine. When i re-navigate componentWillMount is working. When i exit componentWillUnmount is working too.

from react-native-game-engine.

bberak avatar bberak commented on May 22, 2024

After the unmount happens, does you see logs in the console that indicate that the engine is still running?

Also, do you need the new keyword when setting up your entities? It looks like a regular function call World() will be sufficient (but I don't this this is related)..

Can you tell if componentWillMount() is being called once or multiple times?

from react-native-game-engine.

vonqo avatar vonqo commented on May 22, 2024

Once i unmount happens, game engine will be not running.

Just in case I put the new keyword to make sure creating new object. Yes it is irrelevant in JSX.

componentWillMount is called once like expected.

from react-native-game-engine.

bberak avatar bberak commented on May 22, 2024

Hmm, I'd suggest the following:

  • Stripping out the navigation and verifying that everything is working as expected (or not as expected) using vanilla react components.
  • Sharing a stripped down version of your code with me (either via a repo or zip file) and I'll see if I can debug it on my side
  • Having a chat over Skype or something to see if we can debug together.

from react-native-game-engine.

vonqo avatar vonqo commented on May 22, 2024

That sounds really nice. Let me talk with my team about sharing my source code.

How about I'll mail my response about this.

from react-native-game-engine.

bberak avatar bberak commented on May 22, 2024

Sounds good - @lupino22, if you do share some code - just completely strip out the proprietary stuff, a skeleton will do. Cheers.

from react-native-game-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.