1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 Copyright (c) 2008-2010 Ricardo Quesada 4 Copyright (c) 2011 Zynga Inc. 5 6 http://www.cocos2d-x.org 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy 9 of this software and associated documentation files (the "Software"), to deal 10 in the Software without restriction, including without limitation the rights 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the Software is 13 furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 THE SOFTWARE. 25 ****************************************************************************/ 26 27 /** 28 * Device type 29 * @constant 30 * @type {Object} 31 */ 32 cc.TARGET_PLATFORM = { 33 WINDOWS:0, 34 LINUX:1, 35 MACOS:2, 36 ANDROID:3, 37 IPHONE:4, 38 IPAD:5, 39 BLACKBERRY:6, 40 NACL:7, 41 EMSCRIPTEN:8, 42 MOBILE_BROWSER:100, 43 PC_BROWSER:101 44 }; 45 46 /** 47 * Device oriented vertically, home button on the bottom 48 * @constant 49 * @type Number 50 */ 51 cc.ORIENTATION_PORTRAIT = 0; 52 53 /** 54 * Device oriented vertically, home button on the top 55 * @constant 56 * @type Number 57 */ 58 cc.ORIENTATION_PORTRAIT_UPSIDE_DOWN = 1; 59 60 /** 61 * Device oriented horizontally, home button on the right 62 * @constant 63 * @type Number 64 */ 65 cc.ORIENTATION_LANDSCAPE_LEFT = 2; 66 67 /** 68 * Device oriented horizontally, home button on the left 69 * @constant 70 * @type Number 71 */ 72 cc.ORIENTATION_LANDSCAPE_RIGHT = 3; 73 74 //engine render type 75 76 /** 77 * Canvas of render type 78 * @constant 79 * @type Number 80 */ 81 cc.CANVAS = 0; 82 83 /** 84 * WebGL of render type 85 * @constant 86 * @type Number 87 */ 88 cc.WEBGL = 1; 89 90 /** 91 * drawing primitive of game engine 92 * @type cc.DrawingPrimitive 93 */ 94 cc.drawingUtil = null; 95 96 /** 97 * main Canvas 2D/3D Context of game engine 98 * @type CanvasRenderingContext2D|WebGLRenderingContext 99 */ 100 cc.renderContext = null; 101 102 /** 103 * main Canvas of game engine 104 * @type HTMLCanvasElement 105 */ 106 cc.canvas = null; 107 108 /** 109 * This Div element contain all game canvas 110 * @type HTMLDivElement 111 */ 112 cc.gameDiv = null; 113 114 /** 115 * current render type of game engine 116 * @type Number 117 */ 118 cc.renderContextType = cc.CANVAS; 119 120 /** 121 * save original size of canvas, use for resize canvas 122 * @type cc.Size 123 */ 124 cc.originalCanvasSize = cc.size(0, 0); 125 126 window.requestAnimFrame = (function () { 127 return window.requestAnimationFrame || 128 window.webkitRequestAnimationFrame || 129 window.mozRequestAnimationFrame || 130 window.oRequestAnimationFrame || 131 window.msRequestAnimationFrame 132 })(); 133 134 135 if (!window.console) { 136 window.console = {}; 137 window.console.log = function () { 138 }; 139 window.console.assert = function () { 140 }; 141 } 142 143 cc.isAddedHiddenEvent = false; 144 145 /** 146 * <p> 147 * setup game main canvas,renderContext,gameDiv and drawingUtil with argument <br/> 148 * <br/> 149 * can receive follow type of arguemnt: <br/> 150 * - empty: create a canvas append to document's body, and setup other option <br/> 151 * - string: search the element by document.getElementById(), <br/> 152 * if this element is HTMLCanvasElement, set this element as main canvas of engine, and set it's ParentNode as cc.gameDiv.<br/> 153 * if this element is HTMLDivElement, set it's ParentNode to cc.gameDiv, and create a canvas as main canvas of engine. <br/> 154 * </p> 155 * @function 156 * @example 157 * //setup with null 158 * cc.setup(); 159 * 160 * // setup with HTMLCanvasElement, gameCanvas is Canvas element 161 * // declare like this: <canvas id="gameCanvas" width="800" height="450"></canvas> 162 * cc.setup("gameCanvas"); 163 * 164 * //setup with HTMLDivElement, gameDiv is Div element 165 * // declare like this: <div id="Cocos2dGameContainer" width="800" height="450"></div> 166 * cc.setup("Cocos2dGameContainer"); 167 */ 168 cc.setup = function (el, width, height) { 169 var element = cc.$(el) || cc.$('#' + el); 170 if (element.tagName == "CANVAS") { 171 width = width || element.width; 172 height = height || element.height; 173 174 //it is already a canvas, we wrap it around with a div 175 cc.container = cc.$new("DIV"); 176 cc.canvas = element; 177 cc.canvas.parentNode.insertBefore(cc.container, cc.canvas); 178 cc.canvas.appendTo(cc.container); 179 cc.container.style.width = (width || 480) + "px"; 180 cc.container.style.height = (height || 320) + "px"; 181 cc.container.setAttribute('id', 'Cocos2dGameContainer'); 182 cc.container.style.margin = "0 auto"; 183 cc.canvas.setAttribute("width", width || 480); 184 cc.canvas.setAttribute("height", height || 320); 185 } else {//we must make a new canvas and place into this element 186 if (element.tagName != "DIV") { 187 cc.log("Warning: target element is not a DIV or CANVAS"); 188 } 189 width = width || element.clientWidth; 190 height = height || element.clientHeight; 191 192 cc.canvas = cc.$new("CANVAS"); 193 cc.canvas.addClass("gameCanvas"); 194 cc.canvas.setAttribute("width", width || 480); 195 cc.canvas.setAttribute("height", height || 320); 196 cc.container = element; 197 element.appendChild(cc.canvas); 198 cc.container.style.width = (width || 480) + "px"; 199 cc.container.style.height = (height || 320) + "px"; 200 cc.container.style.margin = "0 auto"; 201 } 202 cc.container.style.position = 'relative'; 203 cc.container.style.overflow = 'hidden'; 204 cc.container.top = '100%'; 205 206 if(cc.__renderDoesnotSupport) 207 return; 208 209 if (cc.Browser.supportWebGL) 210 cc.renderContext = cc.webglContext = cc.create3DContext(cc.canvas,{'stencil': true, 'preserveDrawingBuffer': true, 'alpha': false }); 211 if(cc.renderContext){ 212 cc.renderContextType = cc.WEBGL; 213 window.gl = cc.renderContext; // global variable declared in CCMacro.js 214 cc.drawingUtil = new cc.DrawingPrimitiveWebGL(cc.renderContext); 215 cc.TextureCache.getInstance()._initializingRenderer(); 216 } else { 217 cc.renderContext = cc.canvas.getContext("2d"); 218 cc.mainRenderContextBackup = cc.renderContext; 219 cc.renderContextType = cc.CANVAS; 220 cc.renderContext.translate(0, cc.canvas.height); 221 cc.drawingUtil = new cc.DrawingPrimitiveCanvas(cc.renderContext); 222 } 223 224 cc.originalCanvasSize = cc.size(cc.canvas.width, cc.canvas.height); 225 cc.gameDiv = cc.container; 226 227 cc.log(cc.ENGINE_VERSION); 228 cc.Configuration.getInstance(); 229 230 cc.setContextMenuEnable(false); 231 232 if(cc.Browser.isMobile){ 233 cc._addUserSelectStatus(); 234 cc._addBottomTag(); 235 } 236 237 var hidden, visibilityChange; 238 if (typeof document.hidden !== "undefined") { 239 hidden = "hidden"; 240 visibilityChange = "visibilitychange"; 241 } else if (typeof document.mozHidden !== "undefined") { 242 hidden = "mozHidden"; 243 visibilityChange = "mozvisibilitychange"; 244 } else if (typeof document.msHidden !== "undefined") { 245 hidden = "msHidden"; 246 visibilityChange = "msvisibilitychange"; 247 } else if (typeof document.webkitHidden !== "undefined") { 248 hidden = "webkitHidden"; 249 visibilityChange = "webkitvisibilitychange"; 250 } 251 252 function handleVisibilityChange() { 253 if (!document[hidden]) 254 cc.Director.getInstance()._resetLastUpdate(); 255 } 256 257 if (typeof document.addEventListener === "undefined" || 258 typeof hidden === "undefined") { 259 cc.isAddedHiddenEvent = false; 260 } else { 261 cc.isAddedHiddenEvent = true; 262 document.addEventListener(visibilityChange, handleVisibilityChange, false); 263 } 264 }; 265 266 cc._addUserSelectStatus = function(){ 267 var fontStyle = document.createElement("style"); 268 fontStyle.type = "text/css"; 269 document.body.appendChild(fontStyle); 270 271 fontStyle.textContent = "body,canvas,div{ -moz-user-select: none;-webkit-user-select: none;-ms-user-select: none;-khtml-user-select: none;" 272 +"-webkit-tap-highlight-color:rgba(0,0,0,0);}"; 273 }; 274 275 cc._addBottomTag = function () { 276 var bottom = document.createElement("div"); 277 bottom.id = "bottom"; 278 bottom.style.border = bottom.style.margin = bottom.style.padding = bottom.style.height = bottom.style.lineHeight = bottom.style.fontSize = "0px"; 279 document.body.appendChild(bottom); 280 window.location.href="#bottom"; 281 }; 282 283 cc._isContextMenuEnable = false; 284 /** 285 * enable/disable contextMenu for Canvas 286 * @param {Boolean} enabled 287 */ 288 cc.setContextMenuEnable = function (enabled) { 289 cc._isContextMenuEnable = enabled; 290 if (!cc._isContextMenuEnable) { 291 cc.canvas.oncontextmenu = function () { 292 return false; 293 }; 294 } else { 295 cc.canvas.oncontextmenu = function () { 296 }; 297 } 298 }; 299 300 /** 301 * Run main loop of game engine 302 * @class 303 * @extends cc.Class 304 */ 305 cc.Application = cc.Class.extend(/** @lends cc.Application# */{ 306 _animationInterval:null, 307 /** 308 * Constructor 309 */ 310 ctor:function () { 311 this._animationInterval = 0; 312 if(cc._sharedApplication) 313 throw "Application has been initialized"; 314 cc._sharedApplication = this; 315 }, 316 317 /** 318 * Callback by cc.Director for limit FPS. 319 * @param {Number} interval The time, which expressed in second, between current frame and next. 320 */ 321 setAnimationInterval:function (interval) { 322 this._animationInterval = interval; 323 }, 324 325 /** 326 * Get status bar rectangle in EGLView window. 327 * @param {cc.Rect} rect 328 * @deprecated 329 */ 330 statusBarFrame:function (rect) { 331 if (rect) { 332 // Windows doesn't have status bar. 333 rect = cc.rect(0, 0, 0, 0); 334 } 335 }, 336 337 getTargetPlatform:function(){ 338 return cc.Browser.isMobile ? cc.TARGET_PLATFORM.MOBILE_BROWSER : cc.TARGET_PLATFORM.PC_BROWSER; 339 }, 340 341 /** 342 * Run the message loop. 343 * @return {Number} 344 */ 345 run:function () { 346 // Initialize instance and cocos2d. 347 if (!this.applicationDidFinishLaunching()) 348 return 0; 349 350 var callback, director = cc.Director.getInstance(), w = window; 351 if (w.requestAnimFrame && this._animationInterval == 1 / 60) { 352 callback = function () { 353 director.mainLoop(); 354 w.requestAnimFrame(callback); 355 }; 356 //cc.log(window.requestAnimFrame); 357 w.requestAnimFrame(callback); 358 } else { 359 callback = function () { 360 director.mainLoop(); 361 }; 362 setInterval(callback, this._animationInterval * 1000); 363 } 364 return 0; 365 } 366 }); 367 368 /** 369 * Get current application instance. 370 * @return {cc.Application} Current application instance pointer. 371 */ 372 cc.Application.getInstance = function () { 373 return cc._sharedApplication; 374 }; 375 376 /** 377 * Get current language config 378 * @return {Number} Current language config 379 */ 380 cc.Application.getCurrentLanguage = function () { 381 var ret = cc.LANGUAGE_ENGLISH; 382 383 var currentLang = navigator.language; 384 if(!currentLang) 385 currentLang = navigator.browserLanguage || navigator.userLanguage; 386 if(!currentLang) 387 return ret; 388 389 currentLang = currentLang.toLowerCase(); 390 switch (currentLang) { 391 case "zh-cn": 392 ret = cc.LANGUAGE_CHINESE; 393 break; 394 case "fr": 395 ret = cc.LANGUAGE_FRENCH; 396 break; 397 case "it": 398 ret = cc.LANGUAGE_ITALIAN; 399 break; 400 case "de": 401 ret = cc.LANGUAGE_GERMAN; 402 break; 403 case "es": 404 ret = cc.LANGUAGE_SPANISH; 405 break; 406 case "ru": 407 ret = cc.LANGUAGE_RUSSIAN; 408 break; 409 case "ko": 410 ret = cc.LANGUAGE_KOREAN; 411 break; 412 case "ja": 413 ret = cc.LANGUAGE_JAPANESE; 414 break; 415 case "hu": 416 ret = cc.LANGUAGE_HUNGARIAN; 417 break; 418 case "pt": 419 ret = cc.LANGUAGE_PORTUGUESE; 420 break; 421 case "ar": 422 ret = cc.LANGUAGE_ARABIC; 423 break; 424 case "no": 425 ret = cc.LANGUAGE_NORWEGIAN; 426 break; 427 case "pl": 428 ret = cc.LANGUAGE_POLISH; 429 break; 430 } 431 432 return ret; 433 }; 434 435 cc._sharedApplication = null; 436