rapidgame
Version:
A cross-platform commandline tool that prebuilds cocos2d-x libraries for Windows, Mac, Linux, Android and iOS. Also a game templating system.
603 lines (534 loc) • 14.8 kB
JavaScript
///
/// > Created using [RapidGame](https://github.com/natweiss/rapidgame). See the `LICENSE` file for the license governing this code.
///
///
/// The main Game object is a singleton providing boot code, main functions, and other commonly-used, globally-accessible methods.
///
/// 1. All code in this file is applicable to any game project in general.
/// 2. If you need to extend the Game object with project-specific code, use [TwoScene.js](TwoScene.html).
///
///
/// ### Game
///
/// Get or create the Game object.
///
var Game = Game || {};
///
/// ### Game.getTargetFrameRate
///
/// Return the target frame rate to use. Scale back in HTML5 mode to save a CPU fan somewhere.
///
Game.getTargetFrameRate = function() {
return this.isHtml5() ? 30 : 60;
};
///
/// ### Game.isHtml5
///
/// Return true if the game is running in HTML5 mode.
///
Game.isHtml5 = function() {
if (typeof this._isHtml5 === "undefined") {
Game.assert(cc.sys);
this._isHtml5 = cc.sys.isNative ? false : true;
}
return this._isHtml5;
};
///
/// ### Game.isDesktop
///
/// Return true if the game is running on a native desktop OS.
///
Game.isDesktop = function() {
if (typeof this._isDesktop === "undefined") {
if (this.isHtml5()) {
this._isDesktop = false;
} else {
this._isDesktop = (cc.sys.os === cc.sys.OS_OSX
|| cc.sys.os === cc.sys.OS_WINDOWS
|| cc.sys.os === cc.sys.OS_LINUX);
}
}
return this._isDesktop;
};
///
/// ### Game.rand
///
/// Return a random integer between 0 and the given value.
///
Game.rand = function(mod) {
var r = Math.random();
if (typeof mod !== 'undefined') {
r *= 0xffffff;
r = parseInt(r);
r %= mod;
}
return r;
};
///
/// ### Game.getWinSize
///
/// Return the current size of the window or screen.
///
Game.getWinSize = function() {
var size = cc.director.getWinSizeInPixels();
if (typeof this._winSize === 'undefined' || (size.width && size.height)) {
this._winSize = size;
}
return this._winSize;
};
///
/// ### Game.scale
///
/// Scale a number by a factor based on the screen size.
///
Game.scale = function(floatValue) {
if (typeof this._scaleFactor === "undefined")
this._scaleFactor = 1.0;
return floatValue * this._scaleFactor;
};
///
/// ### Game.centralize
///
/// Return a point relative to the center of the screen and scaled.
///
Game.centralize = function(x, y) {
var winSize = this.getWinSize();
return cc.p(Game.scale(x) + winSize.width * .5,
Game.scale(y) + winSize.height * .5);
};
///
/// ### Game.alert
///
/// Safely call `alert`.
///
Game.alert = function(msg) {
if(typeof alert === "function") {
alert(msg);
} else {
cc.log(msg);
}
};
///
/// ### Game.assert
///
/// Throw an error if the given object is undefined or boolean is false.
///
Game.assert = function(objOrBool, errMsg) {
if (typeof objOrBool === "undefined"
|| (typeof objOrBool === "boolean" && !objOrBool)
) {
errMsg = errMsg || "Couldn't load the game. Please try a newer browser.";
alert(errMsg);
debugger;
throw errMsg;
}
};
///
/// ### Game.clone
///
/// Clone an object or array so the original can remained unchanged. If passed an undefined value, an empty array is returned.
///
Game.clone = function(obj) {
if(typeof obj !== "undefined") {
return JSON.parse(JSON.stringify(obj));
}
return [];
};
///
/// ### Game.localizeCurrency
///
/// Return the currency amount localized. Currently the method only localizes to the United States currency format.
///
Game.localizeCurrency = function(amount) {
return "$" + parseFloat(amount).toFixed(2);
};
///
/// ### Game.getLanguageCode
///
/// Return the current language code. Example: `en`.
///
Game.getLanguageCode = function() {
var strings;
if (typeof this._language === "undefined") {
this._language = cc.sys.language;
strings = Game.config["strings"];
if (strings && typeof strings[this._language] === "undefined") {
cc.log("Don't have strings for language: " + this._language);
this._language = "en";
}
}
return this._language;
};
///
/// ### Game.getLocalizedString
///
/// Lookup and return a localized string. Configure localized strings in `Game.config["strings"][languageCode]`.
///
Game.getLocalizedString = function(key) {
var strings,
code = this.getLanguageCode();
strings = Game.config["strings"][code];
if (typeof strings[key] !== "undefined") {
return strings[key];
}
if (key && key.length) {
cc.log("Couldn't find string[" + code + "][" + key + "]");
}
return "";
};
///
/// ### Game.addTouchListeners
///
/// Add touch listeners. Callback will get eventType, touches and event parameters.
///
Game.addTouchListeners = function(layer, callback) {
cc.eventManager.addListener({
event: cc.EventListener.TOUCH_ALL_AT_ONCE,
onTouchesBegan: function(touches, event) {if(touches) {callback("began", touches, event);}},
onTouchesMoved: function(touches, event) {if(touches) {callback("moved", touches, event);}},
onTouchesEnded: function(touches, event) {if(touches) {callback("ended", touches, event);}},
onTouchesCancelled: function(touches, event) {if(touches) {callback("cancelled", touches, event);}}
}, layer);
};
///
/// ### Game.getRunningLayer
///
/// Returns the running scene's child layer.
///
/// Scenes can create a member variable named `layer` which will be used by this method.
///
Game.getRunningLayer = function() {
var node = cc.director.getRunningScene();
if (node) {
if (node.layer) {
node = node.layer;
}
}
return node;
};
///
/// ### Game.callRunningLayer
///
/// Call the running scene's layer's method.
///
Game.callRunningLayer = function(methodName, param1, param2, param3) {
var layer = this.getRunningLayer();
if (layer && layer[methodName]) {
layer[methodName](param1, param2, param3);
} else {
/*cc.log("Couldn't find method '" + methodName + "' in running scene or layer.");*/
}
};
///
/// ### Game.getResourcesToPreload
///
/// Return an array of files to preload.
///
Game.getResourcesToPreload = function() {
var dir = (typeof(Game.getResourceDir) === "function" ? Game.getResourceDir() : ""),
files = Game.config["preload"],
ret = [],
i;
if (files) {
for (i = 0; i < files.length; i += 1) {
if (files[i] && files[i].length) {
ret[i] = dir + files[i];
}
}
}
return ret;
};
///
/// ### Game.runInitialScene
///
/// Loads resources and calls the initial scene. Called by `Game.main`.
///
Game.runInitialScene = function() {
var Scene = window[cc.game.config.initialScene],
scene;
if (typeof Game.loadResources === "function")
Game.loadResources();
scene = new Scene;
scene.init();
cc.director.runScene(scene);
};
///
/// ### Game.setCanvasSize
///
/// Sets the size of the game canvas.
///
Game.setCanvasSize = function(e, w, h) {
var allowHtmlRetina = false;
this._pixelRatio = (allowHtmlRetina ? window.devicePixelRatio || 1 : 1);
e = e || document.getElementById(cc.game.config[cc.game.CONFIG_KEY.id]);
w = w || document.body.clientWidth; // or scrollWidth
h = h || document.body.clientHeight;
e.width = w * this._pixelRatio;
e.height = h * this._pixelRatio;
e.style.width = w + "px";
e.style.height = h + "px";
e.style.backgroundColor = document.body.style.backgroundColor;
cc.log("Set #" + e.getAttribute("id") + " pixel ratio " + this._pixelRatio +
", size " + e.width + "x" + e.height +
", style " + e.style.width + " x " + e.style.height +
", parent " + e.parentNode.getAttribute("id"));
if (typeof this._origCanvasSize === "undefined") {
this._origCanvasSize = {width: w, height: h};
}
};
///
/// ### Game.loadSoundEnabled
///
/// Load the `soundEnabled` preference from local storage.
///
Game.loadSoundEnabled = function() {
var enabled = cc.sys.localStorage.getItem("soundEnabled");
/*cc.log("Loaded sound enabled: " + enabled);*/
if (enabled === null || enabled === "") {
this.enableSound(true);
} else {
this._soundEnabled = (enabled === "true" || enabled === true);
}
/*cc.log("Sound enabled is now: " + this._soundEnabled);*/
};
///
/// ### Game.enableSound
///
/// Enable or disable sound.
///
Game.enableSound = function(enabled) {
this._soundEnabled = enabled ? true : false;
cc.sys.localStorage.setItem("soundEnabled", this._soundEnabled);
if (!this.isSoundEnabled()) {
cc.audioEngine.stopMusic();
/* Check that the music stopped (Chrome bug). */
cc.director.getRunningScene().schedule(function(){
if (!Game.isSoundEnabled()) {
cc.audioEngine.stopMusic();
}
}, 1, 15);
}
};
///
/// ### Game.toggleSoundEnabled
///
/// Toggle whether sound is enabled.
///
Game.toggleSoundEnabled = function() {
this.enableSound(!this.isSoundEnabled());
};
///
/// ### Game.isSoundEnabled
///
/// Return true if sound is enabled.
///
Game.isSoundEnabled = function() {
return this._soundEnabled ? true : false;
};
///
/// ### Game.playEffect
///
/// Plays the sound effect with the given filename if sound is enabled.
///
Game.playEffect = function(filename) {
if (this.isSoundEnabled()) {
/* Automatically prefix with resource path. */
if (cc.loader.resPath && filename.indexOf("/") < 0) {
filename = cc.loader.resPath + "/" + filename;
}
return cc.audioEngine.playEffect(filename);
}
return -1;
};
///
/// ### Game.stopEffect
///
/// Stops the sound effect with the given id.
///
Game.stopEffect = function(audioId) {
cc.audioEngine.stopEffect(audioId);
};
///
/// ### Game.playMusic
///
/// Plays the music file with the given filename if sound is enabled.
///
Game.playMusic = function(filename) {
if (this.isSoundEnabled()) {
/* Automatically prefix with resource path. */
if (cc.loader.resPath && filename.indexOf("/") < 0) {
filename = cc.loader.resPath + "/" + filename;
}
cc.audioEngine.stopMusic();
cc.audioEngine.playMusic(filename, true);
}
};
///
/// ### Game.stopMusic
///
/// Stop music.
///
Game.stopMusic = function() {
cc.audioEngine.stopMusic();
};
///
/// ### Game.startPhysics
///
/// Start the physics engine.
///
Game.startPhysics = function(gravity) {
if (this.space !== "undefined") {
this.space = null;
}
this.space = new cp.Space();
this.space.gravity = cp.v(gravity.x, gravity.y);
this._physicsAccumulator = 0;
if (cc.game.config.debugPhysics) {
this._physicsDebugNode = cc.PhysicsDebugNode.create(this.space);
cc.director.getRunningScene().addChild(this._physicsDebugNode, 100);
}
};
///
/// ### Game.stepPhysics
///
/// Step the physics engine.
///
Game.stepPhysics = function(delta) {
var step = 1 / 60;
this._physicsAccumulator += delta;
while (this._physicsAccumulator > step) {
Game.space.step(step);
this._physicsAccumulator -= step;
}
};
///
/// ### Game.createPhysicsBox
///
/// Create a static physics box.
///
Game.createPhysicsBox = function(_x1, _y1, _x2, _y2, elasticity, friction, collisionType) {
var w = (_x2 - _x1) || 2,
h = (_y2 - _y1) || 2,
box = new cp.BoxShape(this.space.staticBody, Math.abs(w), Math.abs(h));
box.body.setPos(cp.v(_x1 + w * .5, _y1 + h * .5));
box.setElasticity(elasticity || 1);
box.setFriction(friction || 0);
box.setCollisionType(collisionType || 0);
this.space.addStaticShape(box);
return box;
};
///
/// ### Game.createPhysicsSprite
///
/// Create a dynamic physics sprite.
///
Game.createPhysicsSprite = function(filename, elasticity, friction, isCircle, collisionType) {
var sprite = cc.PhysicsSprite.create(filename),
body,
shape,
w = sprite.width || 1,
h = sprite.height || 1;
body = new cp.Body(1, cp.momentForBox(1, w, h))
this.space.addBody(body);
if (isCircle) {
shape = new cp.CircleShape(body, w * .5, cp.v(0,0));
} else {
shape = new cp.BoxShape(body, w, h);
}
shape.setElasticity(elasticity || 1);
shape.setFriction(friction || 0);
shape.setCollisionType(collisionType || 0);
this.space.addShape(shape);
sprite.setBody(body);
return sprite;
};
///
/// ### Game.boot
///
/// Boot method. Different for HTML5 versus native. Called at the end of this file.
///
Game.boot = function(global) {
cc.loader.resPath = cc.game.config.resourcePath;
if (this.isHtml5()) {
Game.setCanvasSize();
Game.setCanvasSize(document.getElementById("gameDiv"),
this._origCanvasSize.width, this._origCanvasSize.height);
} else {
/* Implement timers. */
require(cc.loader.resPath + "/lib/timers.js");
this.timerLoop = makeWindowTimer(global, function(ms){});
cc.director.getScheduler().scheduleCallbackForTarget(this, this.timerLoop);
}
/*setTimeout(function(){cc.log("Confirmed setTimeout() works");}, 3333);*/
/* Embed the equivalent of main.js for faster loading. */
cc.game.onStart = function(){
Game.main();
};
/*
Native client boot happens like this:
1. cc.game.run() ->
2. cc.game.prepare() ->
3. jsb.js ->
4. jsb_cocos2d.js, etc...
*/
cc.game.run();
};
///
/// ### Game.main
///
/// The main method. Called by `cc.game.onStart`.
///
Game.main = function() {
var i,
size = {},
sheets,
cacher,
dirs = [];
/* Get config */
Game.config = Game.config || {};
for (i in cc.game.config) {
if (cc.game.config.hasOwnProperty(i)) {
Game.config[i] = Game.clone(cc.game.config[i]);
}
}
this.loadSoundEnabled();
cc.defineGetterSetter(Game, "winSize", Game.getWinSize);
Game.contentWidth = cc.game.config.designWidth || Game.winSize.width;
Game.contentHeight = cc.game.config.designHeight || Game.winSize.height;
if (Game.winSize.width > Game.winSize.height) {
size.width = (Game.contentHeight / Game.winSize.height) * Game.winSize.width;
size.height = Game.contentHeight;
Game.contentX = (size.width - Game.contentWidth) * .5;
Game.contentY = 0;
} else {
size.width = Game.contentWidth;
size.height = (Game.contentWidth / Game.winSize.width) * Game.winSize.height;
Game.contentX = 0;
Game.contentY = (size.height - Game.contentHeight) * .5;
}
cc.director.setDisplayStats(cc.game.config[cc.game.CONFIG_KEY.showFPS]);
cc.view.setDesignResolutionSize(size.width, size.height, cc.ResolutionPolicy.SHOW_ALL);
cc.view.resizeWithBrowserSize(true);
cc.director.setAnimationInterval(1.0 / this.getTargetFrameRate());
cc.log(parseInt(Game.winSize.width) + "x" + parseInt(Game.winSize.height)
+ " [" + parseInt(Game.contentX) + "," + parseInt(Game.contentY) + " "
+ parseInt(Game.contentWidth) + "x" + parseInt(Game.contentHeight) + "]"
+ ", language: " + Game.getLanguageCode()
+ ", " + parseInt(1.0 / cc.director.getAnimationInterval()) + " fps");
if (this.isHtml5()) {
Game.addImageData = function() {};
} else {
Game.config["font"] = cc.loader.resPath + "/" + Game.config["font"] + ".ttf";
}
if (typeof Game.initPro === "function") {
Game.initPro();
}
/* Preload. */
cc.LoaderScene.preload(Game.getResourcesToPreload(), Game.runInitialScene, this);
};
///
/// ### Boot
///
/// Call `Game.boot` passing in the global variable.
///
Game.boot(this);