-
-
Notifications
You must be signed in to change notification settings - Fork 655
MelonJS Core
MelonJS currently operates quite similar to that of most game frameworks. It manages the game loop for you, giving you update & draw/paint calls to work with.
MelonJS provides various named states to work with, in conjunction with ScreenObjects to better manage different views and controls for the game.
The states are:
| name | index |
|---|---|
| LOADING | 0 |
| MENU | 1 |
| READY | 2 |
| PLAY | 3 |
| GAMEOVER | 4 |
| GAME_END | 5 |
| SCORE | 6 |
| CREDITS | 7 |
| SETTINGS | 8 |
You can define if your own states as well.
MelonJS provides resource management to make it easy to load various images, sounds, etc.
There is also Tiled Map integration with MelonJS, the details on how to use are in the tutorial.
When you initialize melonjs via me.video.init, it sets up the camera, the world object (an instance of me.Container), and the game loop.
Since MelonJS is an HTML5 game engine, it depends on the requestAnimationFrame function that modern browsers provide. Mozilla Developer Network covers the details on the function pretty well, but the short of it is that the requestAnimationFrame tries to run at 60 frames per second. It accepts a function to execute each time a frame runs. So with melon, we tell it to update the game objects as we have defined and to execute all the draw calls.
The requestAnimationFrame is utilized to call two main operations: update & draw.
The update function invokes the update on the me.game.world object, which is a me.Container. The update function of the container loops through each of its child objects. If the child object is another container, then that container will invoke all its children's update functions, etc.
The container update function goes through a couple checks before updating the child object:
- Will skip the update if the game state is set to paused, and the object is not set to update when paused.
- The object must be either in viewport, floating or set to alwaysUpdate.
Delta time is passed to the update call since 1.0. If you are using 0.9.x and need to know the time change from the last frame. You can store a time object somewhere, and calculate the difference like so:
init : function() {
this.lastTime = me.timer.getTime();
},
update : function() {
var d = this.lastTime - me.timer.getTime();
this.lastTime = me.timer.getTime();
}The update method is expected to return a boolean or a falsey value. The update return value tells the engine if the particular object should be re-drawn. It is a good practice to only return true from your update methods when you absolutely need to, such as having your entity fall (this.body.vel.x !== 0) due to gravity. The tutorial mentions this with the HUD: https://github.com/melonjs/tutorial/blob/gh-pages/tutorial_step2/js/entities/HUD.js#L59.
Once all updates are complete, the draw cycle begins iff any of the update functions have returned true. If all update functions return some falsey value, all draws are skipped for this frame. This is an optimization for screens that have no activity.
The container draw function checks all of its child objects in the same way. Ensures the game is not paused, and that the object is either in view or set to always update. It also checks if the object is considered a renderable (isRenderable set to true). There may be some objects you want to have update in the game loop, but not draw anything.
Each child object's draw function calls the appropriate methods on the current renderer. 1.2.0 will be the first version of our WebGL renderer. The canvas renderer is still the default. The game engine itself makes its calls against me.video.renderer which is an instance of either me.CanvasRenderer or me.WebGLRenderer.
To learn more about the object types explained here, check out: