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.canvas.setAttribute("width", width || 480); 183 cc.canvas.setAttribute("height", height || 320); 184 } else {//we must make a new canvas and place into this element 185 if (element.tagName != "DIV") { 186 cc.log("Warning: target element is not a DIV or CANVAS"); 187 } 188 width = width || element.clientWidth; 189 height = height || element.clientHeight; 190 191 cc.canvas = cc.$new("CANVAS"); 192 cc.canvas.addClass("gameCanvas"); 193 cc.canvas.setAttribute("width", width || 480); 194 cc.canvas.setAttribute("height", height || 320); 195 cc.container = element; 196 element.appendChild(cc.canvas); 197 cc.container.style.width = (width || 480) + "px"; 198 cc.container.style.height = (height || 320) + "px"; 199 } 200 cc.container.style.position = 'relative'; 201 cc.container.style.overflow = 'hidden'; 202 cc.container.top = '100%'; 203 204 if(cc.__renderDoesnotSupport) 205 return; 206 207 if (cc.Browser.supportWebGL) 208 cc.renderContext = cc.webglContext = cc.create3DContext(cc.canvas,{'stencil': true, 'preserveDrawingBuffer': true, 'alpha': false }); 209 if(cc.renderContext){ 210 cc.renderContextType = cc.WEBGL; 211 window.gl = cc.renderContext; // global variable declared in CCMacro.js 212 cc.drawingUtil = new cc.DrawingPrimitiveWebGL(cc.renderContext); 213 cc.TextureCache.getInstance()._initializingRenderer(); 214 } else { 215 cc.renderContext = cc.canvas.getContext("2d"); 216 cc.mainRenderContextBackup = cc.renderContext; 217 cc.renderContextType = cc.CANVAS; 218 cc.renderContext.translate(0, cc.canvas.height); 219 cc.drawingUtil = new cc.DrawingPrimitiveCanvas(cc.renderContext); 220 } 221 222 cc.originalCanvasSize = cc.size(cc.canvas.width, cc.canvas.height); 223 cc.gameDiv = cc.container; 224 225 cc.log(cc.ENGINE_VERSION); 226 cc.Configuration.getInstance(); 227 228 cc.setContextMenuEnable(false); 229 230 if(cc.Browser.isMobile){ 231 cc._addUserSelectStatus(); 232 cc._addBottomTag(); 233 } 234 235 var hidden, visibilityChange; 236 if (typeof document.hidden !== "undefined") { 237 hidden = "hidden"; 238 visibilityChange = "visibilitychange"; 239 } else if (typeof document.mozHidden !== "undefined") { 240 hidden = "mozHidden"; 241 visibilityChange = "mozvisibilitychange"; 242 } else if (typeof document.msHidden !== "undefined") { 243 hidden = "msHidden"; 244 visibilityChange = "msvisibilitychange"; 245 } else if (typeof document.webkitHidden !== "undefined") { 246 hidden = "webkitHidden"; 247 visibilityChange = "webkitvisibilitychange"; 248 } 249 250 function handleVisibilityChange() { 251 if (!document[hidden]) 252 cc.Director.getInstance()._resetLastUpdate(); 253 } 254 255 if (typeof document.addEventListener === "undefined" || 256 typeof hidden === "undefined") { 257 cc.isAddedHiddenEvent = false; 258 } else { 259 cc.isAddedHiddenEvent = true; 260 document.addEventListener(visibilityChange, handleVisibilityChange, false); 261 } 262 }; 263 264 cc._addUserSelectStatus = function(){ 265 var fontStyle = document.createElement("style"); 266 fontStyle.type = "text/css"; 267 document.body.appendChild(fontStyle); 268 269 fontStyle.textContent = "body,canvas,div{ -moz-user-select: none;-webkit-user-select: none;-ms-user-select: none;-khtml-user-select: none;" 270 +"-webkit-tap-highlight-color:rgba(0,0,0,0);}"; 271 }; 272 273 cc._addBottomTag = function () { 274 var bottom = document.createElement("div"); 275 bottom.id = "bottom"; 276 bottom.style.border = bottom.style.margin = bottom.style.padding = bottom.style.height = bottom.style.lineHeight = bottom.style.fontSize = "0px"; 277 document.body.appendChild(bottom); 278 window.location.href="#bottom"; 279 }; 280 281 cc._isContextMenuEnable = false; 282 /** 283 * enable/disable contextMenu for Canvas 284 * @param {Boolean} enabled 285 */ 286 cc.setContextMenuEnable = function (enabled) { 287 cc._isContextMenuEnable = enabled; 288 if (!cc._isContextMenuEnable) { 289 cc.canvas.oncontextmenu = function () { 290 return false; 291 }; 292 } else { 293 cc.canvas.oncontextmenu = function () { 294 }; 295 } 296 }; 297 298 /** 299 * Run main loop of game engine 300 * @class 301 * @extends cc.Class 302 */ 303 cc.Application = cc.Class.extend(/** @lends cc.Application# */{ 304 _animationInterval:null, 305 /** 306 * Constructor 307 */ 308 ctor:function () { 309 this._animationInterval = 0; 310 cc.Assert(!cc._sharedApplication, "CCApplication ctor"); 311 cc._sharedApplication = this; 312 }, 313 314 /** 315 * Callback by cc.Director for limit FPS. 316 * @param {Number} interval The time, which expressed in second, between current frame and next. 317 */ 318 setAnimationInterval:function (interval) { 319 this._animationInterval = interval; 320 }, 321 322 /** 323 * Get status bar rectangle in EGLView window. 324 * @param {cc.Rect} rect 325 * @deprecated 326 */ 327 statusBarFrame:function (rect) { 328 if (rect) { 329 // Windows doesn't have status bar. 330 rect = cc.rect(0, 0, 0, 0); 331 } 332 }, 333 334 getTargetPlatform:function(){ 335 return cc.Browser.isMobile ? cc.TARGET_PLATFORM.MOBILE_BROWSER : cc.TARGET_PLATFORM.PC_BROWSER; 336 }, 337 338 /** 339 * Run the message loop. 340 * @return {Number} 341 */ 342 run:function () { 343 // Initialize instance and cocos2d. 344 if (!this.applicationDidFinishLaunching()) 345 return 0; 346 347 var callback, director = cc.Director.getInstance(), w = window; 348 if (w.requestAnimFrame && this._animationInterval == 1 / 60) { 349 callback = function () { 350 director.mainLoop(); 351 w.requestAnimFrame(callback); 352 }; 353 //cc.log(window.requestAnimFrame); 354 w.requestAnimFrame(callback); 355 } else { 356 callback = function () { 357 director.mainLoop(); 358 }; 359 setInterval(callback, this._animationInterval * 1000); 360 } 361 return 0; 362 } 363 }); 364 365 /** 366 * Get current applicaiton instance. 367 * @return {cc.Application} Current application instance pointer. 368 */ 369 cc.Application.getInstance = function () { 370 cc.Assert(cc._sharedApplication, "sharedApplication"); 371 return cc._sharedApplication; 372 }; 373 374 /** 375 * Get current language config 376 * @return {Number} Current language config 377 */ 378 cc.Application.getCurrentLanguage = function () { 379 var ret = cc.LANGUAGE_ENGLISH; 380 381 var currentLang = navigator.language; 382 if(!currentLang) 383 currentLang = navigator.browserLanguage || navigator.userLanguage; 384 if(!currentLang) 385 return ret; 386 387 currentLang = currentLang.toLowerCase(); 388 switch (currentLang) { 389 case "zh-cn": 390 ret = cc.LANGUAGE_CHINESE; 391 break; 392 case "fr": 393 ret = cc.LANGUAGE_FRENCH; 394 break; 395 case "it": 396 ret = cc.LANGUAGE_ITALIAN; 397 break; 398 case "de": 399 ret = cc.LANGUAGE_GERMAN; 400 break; 401 case "es": 402 ret = cc.LANGUAGE_SPANISH; 403 break; 404 case "ru": 405 ret = cc.LANGUAGE_RUSSIAN; 406 break; 407 case "ko": 408 ret = cc.LANGUAGE_KOREAN; 409 break; 410 case "ja": 411 ret = cc.LANGUAGE_JAPANESE; 412 break; 413 case "hu": 414 ret = cc.LANGUAGE_HUNGARIAN; 415 break; 416 case "pt": 417 ret = cc.LANGUAGE_PORTUGUESE; 418 break; 419 case "ar": 420 ret = cc.LANGUAGE_ARABIC; 421 break; 422 case "no": 423 ret = cc.LANGUAGE_NORWEGIAN; 424 break; 425 case "pl": 426 ret = cc.LANGUAGE_POLISH; 427 break; 428 } 429 430 return ret; 431 }; 432 433 cc._sharedApplication = null; 434