I’m planning on creating a Mortal Kombat-inspired game in JavaScript. I’ve written a basic game engine that manages my game states and creates a game loop.
I just wondered if it could be improved at all? As I’m a web developer by trade and this is my first foray into programming games.
/**
* Game engine.
*/
function GameEngine() {
this.states = new Array();
this.currentState;
this.running = false;
};
GameEngine.prototype.init = function() {
this.running = true;
};
GameEngine.prototype.changeState = function(state) {
this.currentState = state;
};
GameEngine.prototype.isRunning = function() {
return this.running;
};
GameEngine.prototype.handleEvents = function() {
this.currentState.handleEvents(this);
};
GameEngine.prototype.update = function() {
this.currentState.update(this);
};
GameEngine.prototype.draw = function() {
this.currentState.draw(this);
};
/**
* Base game state state.
*/
function GameState() {};
/**
* Intro state.
*/
function IntroState() {};
IntroState.prototype = Object.create(GameState.prototype);
IntroState.prototype.handleEvents = function(game) {
console.log('IntroState::handleEvents');
};
IntroState.prototype.update = function(game) {
console.log('IntroState::update');
};
IntroState.prototype.draw = function(game) {
console.log('IntroState::draw');
};
/**
* Initialises the game.
*/
(function() {
var game = new GameEngine();
var gameLoop;
var frameLength = 500;
game.init();
game.changeState(new IntroState());
gameLoop = setInterval(function() {
game.handleEvents();
game.update();
game.draw();
}, frameLength);
})();
3 Answers 3
There's really not much to say about this code, so I'll quote a comment posted on this question:
[...] a basic game engine is a loop and a redraw/update system. So yes you are good. You should explore other game engines in javascript and see what they do. – Steven
Just one thing that's itching: you're declaring var frameLength = 500;
- I think this is going to bite you later, when you want to adjust frame rate (FPS).
My 2 cents:
GameEngine is most likely going to be a singleton, so there is no reason to add anything to it's prototype really. You can assign init etc. straight to GameEngine.
If you are going to have the GameEngine functions simply execute the currentState functions, you should at least return
this
, so that the caller can chain calls.I am very ambivalent towards
handleEvents
, I would simply listen to mouse clicks and keyboard presses in the old school way and update the data model in yourGameEngine
, then draw the data from the data model every n milliseconds.As retailcoder mentioned, you will probably have to think how you want to maintain a steady fps, just calling those functions every x milliseconds is not going to cut it most likely.
Just a general tip in regard to the comments...
It's not recommended to use /* */
comment blocks in your code. The reason for that is because in Javascript, that character pair can occur in regular expression literals as well. Comment blocks are therefore not safe for commenting blocks of code.
A better alternative is to generally stick to line comments (//
) whenever possible and save block comments for formal documentation and for commenting out.
-
\$\begingroup\$ I have to disagree with you about this. I see no reason to avoid
/* */
comments just because it can be occur in regex. \$\endgroup\$Simon Forsberg– Simon Forsberg2013年11月18日 17:30:45 +00:00Commented Nov 18, 2013 at 17:30 -
\$\begingroup\$ @SimonAndréForsberg I agree with you, but this question needs an upvoted answer :) \$\endgroup\$Mathieu Guindon– Mathieu Guindon2013年11月18日 18:05:53 +00:00Commented Nov 18, 2013 at 18:05
-
2\$\begingroup\$ @retailcoder I know, but upvoted answers should be useful answers :) Thanks for adding a better one. \$\endgroup\$Simon Forsberg– Simon Forsberg2013年11月18日 18:10:31 +00:00Commented Nov 18, 2013 at 18:10
-
\$\begingroup\$ So you say to avoid comments blocks, then say save them for formal documentation? Be consistent. Also, I’ve never had a problem with comments being interpreted as regular expression literals and vice versa. \$\endgroup\$Martin Bean– Martin Bean2013年11月18日 21:55:13 +00:00Commented Nov 18, 2013 at 21:55
Constructor.prototype
all the time, you should perhaps do something likeConstructor.prototype = { constructor: Constructor, someFn: function () {}, someOtherFn: function () {} }
. Also have a look at ibm.com/developerworks/library/wa-objectorientedjs \$\endgroup\$