display.lua 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. --[[
  2. Copyright (c) 2011-2014 chukong-inc.com
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. THE SOFTWARE.
  18. ]]
  19. local display = {}
  20. local director = cc.Director:getInstance()
  21. local view = director:getOpenGLView()
  22. if not view then
  23. local width = 960
  24. local height = 640
  25. if CC_DESIGN_RESOLUTION then
  26. if CC_DESIGN_RESOLUTION.width then
  27. width = CC_DESIGN_RESOLUTION.width
  28. end
  29. if CC_DESIGN_RESOLUTION.height then
  30. height = CC_DESIGN_RESOLUTION.height
  31. end
  32. end
  33. view = cc.GLViewImpl:createWithRect("Cocos2d-Lua", cc.rect(0, 0, width, height))
  34. director:setOpenGLView(view)
  35. end
  36. local framesize = view:getFrameSize()
  37. local textureCache = director:getTextureCache()
  38. local spriteFrameCache = cc.SpriteFrameCache:getInstance()
  39. local animationCache = cc.AnimationCache:getInstance()
  40. -- auto scale
  41. local function checkResolution(r)
  42. r.width = checknumber(r.width)
  43. r.height = checknumber(r.height)
  44. r.autoscale = string.upper(r.autoscale)
  45. assert(r.width > 0 and r.height > 0,
  46. string.format("display - invalid design resolution size %d, %d", r.width, r.height))
  47. end
  48. local function setDesignResolution(r, framesize)
  49. if r.autoscale == "FILL_ALL" then
  50. view:setDesignResolutionSize(framesize.width, framesize.height, cc.ResolutionPolicy.FILL_ALL)
  51. else
  52. local scaleX, scaleY = framesize.width / r.width, framesize.height / r.height
  53. local width, height = framesize.width, framesize.height
  54. if r.autoscale == "FIXED_WIDTH" then
  55. width = framesize.width / scaleX
  56. height = framesize.height / scaleX
  57. view:setDesignResolutionSize(width, height, cc.ResolutionPolicy.NO_BORDER)
  58. elseif r.autoscale == "FIXED_HEIGHT" then
  59. width = framesize.width / scaleY
  60. height = framesize.height / scaleY
  61. view:setDesignResolutionSize(width, height, cc.ResolutionPolicy.NO_BORDER)
  62. elseif r.autoscale == "EXACT_FIT" then
  63. view:setDesignResolutionSize(r.width, r.height, cc.ResolutionPolicy.EXACT_FIT)
  64. elseif r.autoscale == "NO_BORDER" then
  65. view:setDesignResolutionSize(r.width, r.height, cc.ResolutionPolicy.NO_BORDER)
  66. elseif r.autoscale == "SHOW_ALL" then
  67. view:setDesignResolutionSize(r.width, r.height, cc.ResolutionPolicy.SHOW_ALL)
  68. else
  69. printError(string.format("display - invalid r.autoscale \"%s\"", r.autoscale))
  70. end
  71. end
  72. end
  73. local function setConstants()
  74. local sizeInPixels = view:getFrameSize()
  75. display.sizeInPixels = {width = sizeInPixels.width, height = sizeInPixels.height}
  76. local viewsize = director:getWinSize()
  77. display.contentScaleFactor = director:getContentScaleFactor()
  78. display.size = {width = viewsize.width, height = viewsize.height}
  79. display.width = display.size.width
  80. display.height = display.size.height
  81. display.cx = display.width / 2
  82. display.cy = display.height / 2
  83. display.c_left = -display.width / 2
  84. display.c_right = display.width / 2
  85. display.c_top = display.height / 2
  86. display.c_bottom = -display.height / 2
  87. display.left = 0
  88. display.right = display.width
  89. display.top = display.height
  90. display.bottom = 0
  91. display.center = cc.p(display.cx, display.cy)
  92. display.left_top = cc.p(display.left, display.top)
  93. display.left_bottom = cc.p(display.left, display.bottom)
  94. display.left_center = cc.p(display.left, display.cy)
  95. display.right_top = cc.p(display.right, display.top)
  96. display.right_bottom = cc.p(display.right, display.bottom)
  97. display.right_center = cc.p(display.right, display.cy)
  98. display.top_center = cc.p(display.cx, display.top)
  99. display.top_bottom = cc.p(display.cx, display.bottom)
  100. printInfo(string.format("# display.sizeInPixels = {width = %0.2f, height = %0.2f}", display.sizeInPixels.width, display.sizeInPixels.height))
  101. printInfo(string.format("# display.size = {width = %0.2f, height = %0.2f}", display.size.width, display.size.height))
  102. printInfo(string.format("# display.contentScaleFactor = %0.2f", display.contentScaleFactor))
  103. printInfo(string.format("# display.width = %0.2f", display.width))
  104. printInfo(string.format("# display.height = %0.2f", display.height))
  105. printInfo(string.format("# display.cx = %0.2f", display.cx))
  106. printInfo(string.format("# display.cy = %0.2f", display.cy))
  107. printInfo(string.format("# display.left = %0.2f", display.left))
  108. printInfo(string.format("# display.right = %0.2f", display.right))
  109. printInfo(string.format("# display.top = %0.2f", display.top))
  110. printInfo(string.format("# display.bottom = %0.2f", display.bottom))
  111. printInfo(string.format("# display.c_left = %0.2f", display.c_left))
  112. printInfo(string.format("# display.c_right = %0.2f", display.c_right))
  113. printInfo(string.format("# display.c_top = %0.2f", display.c_top))
  114. printInfo(string.format("# display.c_bottom = %0.2f", display.c_bottom))
  115. printInfo(string.format("# display.center = {x = %0.2f, y = %0.2f}", display.center.x, display.center.y))
  116. printInfo(string.format("# display.left_top = {x = %0.2f, y = %0.2f}", display.left_top.x, display.left_top.y))
  117. printInfo(string.format("# display.left_bottom = {x = %0.2f, y = %0.2f}", display.left_bottom.x, display.left_bottom.y))
  118. printInfo(string.format("# display.left_center = {x = %0.2f, y = %0.2f}", display.left_center.x, display.left_center.y))
  119. printInfo(string.format("# display.right_top = {x = %0.2f, y = %0.2f}", display.right_top.x, display.right_top.y))
  120. printInfo(string.format("# display.right_bottom = {x = %0.2f, y = %0.2f}", display.right_bottom.x, display.right_bottom.y))
  121. printInfo(string.format("# display.right_center = {x = %0.2f, y = %0.2f}", display.right_center.x, display.right_center.y))
  122. printInfo(string.format("# display.top_center = {x = %0.2f, y = %0.2f}", display.top_center.x, display.top_center.y))
  123. printInfo(string.format("# display.top_bottom = {x = %0.2f, y = %0.2f}", display.top_bottom.x, display.top_bottom.y))
  124. printInfo("#")
  125. end
  126. function display.setAutoScale(configs)
  127. if type(configs) ~= "table" then return end
  128. checkResolution(configs)
  129. if type(configs.callback) == "function" then
  130. local c = configs.callback(framesize)
  131. for k, v in pairs(c or {}) do
  132. configs[k] = v
  133. end
  134. checkResolution(configs)
  135. end
  136. setDesignResolution(configs, framesize)
  137. printInfo(string.format("# design resolution size = {width = %0.2f, height = %0.2f}", configs.width, configs.height))
  138. printInfo(string.format("# design resolution autoscale = %s", configs.autoscale))
  139. setConstants()
  140. end
  141. if type(CC_DESIGN_RESOLUTION) == "table" then
  142. display.setAutoScale(CC_DESIGN_RESOLUTION)
  143. end
  144. display.COLOR_WHITE = cc.c3b(255, 255, 255)
  145. display.COLOR_BLACK = cc.c3b(0, 0, 0)
  146. display.COLOR_RED = cc.c3b(255, 0, 0)
  147. display.COLOR_GREEN = cc.c3b(0, 255, 0)
  148. display.COLOR_BLUE = cc.c3b(0, 0, 255)
  149. display.AUTO_SIZE = 0
  150. display.FIXED_SIZE = 1
  151. display.LEFT_TO_RIGHT = 0
  152. display.RIGHT_TO_LEFT = 1
  153. display.TOP_TO_BOTTOM = 2
  154. display.BOTTOM_TO_TOP = 3
  155. display.CENTER = cc.p(0.5, 0.5)
  156. display.LEFT_TOP = cc.p(0, 1)
  157. display.LEFT_BOTTOM = cc.p(0, 0)
  158. display.LEFT_CENTER = cc.p(0, 0.5)
  159. display.RIGHT_TOP = cc.p(1, 1)
  160. display.RIGHT_BOTTOM = cc.p(1, 0)
  161. display.RIGHT_CENTER = cc.p(1, 0.5)
  162. display.CENTER_TOP = cc.p(0.5, 1)
  163. display.CENTER_BOTTOM = cc.p(0.5, 0)
  164. display.SCENE_TRANSITIONS = {
  165. CROSSFADE = cc.TransitionCrossFade,
  166. FADE = {cc.TransitionFade, cc.c3b(0, 0, 0)},
  167. FADEBL = cc.TransitionFadeBL,
  168. FADEDOWN = cc.TransitionFadeDown,
  169. FADETR = cc.TransitionFadeTR,
  170. FADEUP = cc.TransitionFadeUp,
  171. FLIPANGULAR = {cc.TransitionFlipAngular, cc.TRANSITION_ORIENTATION_LEFT_OVER},
  172. FLIPX = {cc.TransitionFlipX, cc.TRANSITION_ORIENTATION_LEFT_OVER},
  173. FLIPY = {cc.TransitionFlipY, cc.TRANSITION_ORIENTATION_UP_OVER},
  174. JUMPZOOM = cc.TransitionJumpZoom,
  175. MOVEINB = cc.TransitionMoveInB,
  176. MOVEINL = cc.TransitionMoveInL,
  177. MOVEINR = cc.TransitionMoveInR,
  178. MOVEINT = cc.TransitionMoveInT,
  179. PAGETURN = {cc.TransitionPageTurn, false},
  180. ROTOZOOM = cc.TransitionRotoZoom,
  181. SHRINKGROW = cc.TransitionShrinkGrow,
  182. SLIDEINB = cc.TransitionSlideInB,
  183. SLIDEINL = cc.TransitionSlideInL,
  184. SLIDEINR = cc.TransitionSlideInR,
  185. SLIDEINT = cc.TransitionSlideInT,
  186. SPLITCOLS = cc.TransitionSplitCols,
  187. SPLITROWS = cc.TransitionSplitRows,
  188. TURNOFFTILES = cc.TransitionTurnOffTiles,
  189. ZOOMFLIPANGULAR = cc.TransitionZoomFlipAngular,
  190. ZOOMFLIPX = {cc.TransitionZoomFlipX, cc.TRANSITION_ORIENTATION_LEFT_OVER},
  191. ZOOMFLIPY = {cc.TransitionZoomFlipY, cc.TRANSITION_ORIENTATION_UP_OVER},
  192. }
  193. display.TEXTURES_PIXEL_FORMAT = {}
  194. display.DEFAULT_TTF_FONT = "Arial"
  195. display.DEFAULT_TTF_FONT_SIZE = 32
  196. local PARAMS_EMPTY = {}
  197. local RECT_ZERO = cc.rect(0, 0, 0, 0)
  198. local sceneIndex = 0
  199. function display.newScene(name, params)
  200. params = params or PARAMS_EMPTY
  201. sceneIndex = sceneIndex + 1
  202. local scene
  203. if not params.physics then
  204. scene = cc.Scene:create()
  205. else
  206. scene = cc.Scene:createWithPhysics()
  207. end
  208. scene.name_ = string.format("%s:%d", name or "<unknown-scene>", sceneIndex)
  209. if params.transition then
  210. scene = display.wrapSceneWithTransition(scene, params.transition, params.time, params.more)
  211. end
  212. return scene
  213. end
  214. function display.wrapScene(scene, transition, time, more)
  215. local key = string.upper(tostring(transition))
  216. if key == "RANDOM" then
  217. local keys = table.keys(display.SCENE_TRANSITIONS)
  218. key = keys[math.random(1, #keys)]
  219. end
  220. if display.SCENE_TRANSITIONS[key] then
  221. local t = display.SCENE_TRANSITIONS[key]
  222. time = time or 0.2
  223. more = more or t[2]
  224. if type(t) == "table" then
  225. scene = t[1]:create(time, scene, more)
  226. else
  227. scene = t:create(time, scene)
  228. end
  229. else
  230. error(string.format("display.wrapScene() - invalid transition %s", tostring(transition)))
  231. end
  232. return scene
  233. end
  234. function display.runScene(newScene, transition, time, more)
  235. if director:getRunningScene() then
  236. if transition then
  237. newScene = display.wrapScene(newScene, transition, time, more)
  238. end
  239. director:replaceScene(newScene)
  240. else
  241. director:runWithScene(newScene)
  242. end
  243. end
  244. function display.getRunningScene()
  245. return director:getRunningScene()
  246. end
  247. function display.newNode()
  248. return cc.Node:create()
  249. end
  250. function display.newLayer(...)
  251. local params = {...}
  252. local c = #params
  253. local layer
  254. if c == 0 then
  255. -- /** creates a fullscreen black layer */
  256. -- static Layer *create();
  257. layer = cc.Layer:create()
  258. elseif c == 1 then
  259. -- /** creates a Layer with color. Width and height are the window size. */
  260. -- static LayerColor * create(const Color4B& color);
  261. layer = cc.LayerColor:create(cc.convertColor(params[1], "4b"))
  262. elseif c == 2 then
  263. -- /** creates a Layer with color, width and height in Points */
  264. -- static LayerColor * create(const Color4B& color, const Size& size);
  265. --
  266. -- /** Creates a full-screen Layer with a gradient between start and end. */
  267. -- static LayerGradient* create(const Color4B& start, const Color4B& end);
  268. local color1 = cc.convertColor(params[1], "4b")
  269. local p2 = params[2]
  270. assert(type(p2) == "table" and (p2.width or p2.r), "display.newLayer() - invalid paramerter 2")
  271. if p2.r then
  272. layer = cc.LayerGradient:create(color1, cc.convertColor(p2, "4b"))
  273. else
  274. layer = cc.LayerColor:create(color1, p2.width, p2.height)
  275. end
  276. elseif c == 3 then
  277. -- /** creates a Layer with color, width and height in Points */
  278. -- static LayerColor * create(const Color4B& color, GLfloat width, GLfloat height);
  279. --
  280. -- /** Creates a full-screen Layer with a gradient between start and end in the direction of v. */
  281. -- static LayerGradient* create(const Color4B& start, const Color4B& end, const Vec2& v);
  282. local color1 = cc.convertColor(params[1], "4b")
  283. local p2 = params[2]
  284. local p2type = type(p2)
  285. if p2type == "table" then
  286. layer = cc.LayerGradient:create(color1, cc.convertColor(p2, "4b"), params[3])
  287. else
  288. layer = cc.LayerColor:create(color1, p2, params[3])
  289. end
  290. end
  291. return layer
  292. end
  293. function display.newSprite(source, x, y, params)
  294. local spriteClass = cc.Sprite
  295. local scale9 = false
  296. if type(x) == "table" and not x.x then
  297. -- x is params
  298. params = x
  299. x = nil
  300. y = nil
  301. end
  302. local params = params or PARAMS_EMPTY
  303. if params.scale9 or params.capInsets then
  304. spriteClass = ccui.Scale9Sprite
  305. scale9 = true
  306. params.capInsets = params.capInsets or RECT_ZERO
  307. params.rect = params.rect or RECT_ZERO
  308. end
  309. local sprite
  310. while true do
  311. -- create sprite
  312. if not source then
  313. sprite = spriteClass:create()
  314. break
  315. end
  316. local sourceType = type(source)
  317. if sourceType == "string" then
  318. if string.byte(source) == 35 then -- first char is #
  319. -- create sprite from spriteFrame
  320. if not scale9 then
  321. sprite = spriteClass:createWithSpriteFrameName(string.sub(source, 2))
  322. else
  323. sprite = spriteClass:createWithSpriteFrameName(string.sub(source, 2), params.capInsets)
  324. end
  325. break
  326. end
  327. -- create sprite from image file
  328. if display.TEXTURES_PIXEL_FORMAT[source] then
  329. cc.Texture2D:setDefaultAlphaPixelFormat(display.TEXTURES_PIXEL_FORMAT[source])
  330. end
  331. if not scale9 then
  332. sprite = spriteClass:create(source)
  333. else
  334. sprite = spriteClass:create(source, params.rect, params.capInsets)
  335. end
  336. if display.TEXTURES_PIXEL_FORMAT[source] then
  337. cc.Texture2D:setDefaultAlphaPixelFormat(cc.TEXTURE2_D_PIXEL_FORMAT_BGR_A8888)
  338. end
  339. break
  340. elseif sourceType ~= "userdata" then
  341. error(string.format("display.newSprite() - invalid source type \"%s\"", sourceType), 0)
  342. else
  343. sourceType = tolua.type(source)
  344. if sourceType == "cc.SpriteFrame" then
  345. if not scale9 then
  346. sprite = spriteClass:createWithSpriteFrame(source)
  347. else
  348. sprite = spriteClass:createWithSpriteFrame(source, params.capInsets)
  349. end
  350. elseif sourceType == "cc.Texture2D" then
  351. sprite = spriteClass:createWithTexture(source)
  352. else
  353. error(string.format("display.newSprite() - invalid source type \"%s\"", sourceType), 0)
  354. end
  355. end
  356. break
  357. end
  358. if sprite then
  359. if x and y then sprite:setPosition(x, y) end
  360. if params.size then sprite:setContentSize(params.size) end
  361. else
  362. error(string.format("display.newSprite() - create sprite failure, source \"%s\"", tostring(source)), 0)
  363. end
  364. return sprite
  365. end
  366. function display.newSpriteFrame(source, ...)
  367. local frame
  368. if type(source) == "string" then
  369. if string.byte(source) == 35 then -- first char is #
  370. source = string.sub(source, 2)
  371. end
  372. frame = spriteFrameCache:getSpriteFrame(source)
  373. if not frame then
  374. error(string.format("display.newSpriteFrame() - invalid frame name \"%s\"", tostring(source)), 0)
  375. end
  376. elseif tolua.type(source) == "cc.Texture2D" then
  377. frame = cc.SpriteFrame:createWithTexture(source, ...)
  378. else
  379. error("display.newSpriteFrame() - invalid parameters", 0)
  380. end
  381. return frame
  382. end
  383. function display.newFrames(pattern, begin, length, isReversed)
  384. local frames = {}
  385. local step = 1
  386. local last = begin + length - 1
  387. if isReversed then
  388. last, begin = begin, last
  389. step = -1
  390. end
  391. for index = begin, last, step do
  392. local frameName = string.format(pattern, index)
  393. local frame = spriteFrameCache:getSpriteFrame(frameName)
  394. if not frame then
  395. error(string.format("display.newFrames() - invalid frame name %s", tostring(frameName)), 0)
  396. end
  397. frames[#frames + 1] = frame
  398. end
  399. return frames
  400. end
  401. local function newAnimation(frames, time)
  402. local count = #frames
  403. assert(count > 0, "display.newAnimation() - invalid frames")
  404. time = time or 1.0 / count
  405. return cc.Animation:createWithSpriteFrames(frames, time),
  406. cc.Sprite:createWithSpriteFrame(frames[1])
  407. end
  408. function display.newAnimation(...)
  409. local params = {...}
  410. local c = #params
  411. if c == 2 then
  412. -- frames, time
  413. return newAnimation(params[1], params[2])
  414. elseif c == 4 then
  415. -- pattern, begin, length, time
  416. local frames = display.newFrames(params[1], params[2], params[3])
  417. return newAnimation(frames, params[4])
  418. elseif c == 5 then
  419. -- pattern, begin, length, isReversed, time
  420. local frames = display.newFrames(params[1], params[2], params[3], params[4])
  421. return newAnimation(frames, params[5])
  422. else
  423. error("display.newAnimation() - invalid parameters")
  424. end
  425. end
  426. function display.loadImage(imageFilename, callback)
  427. if not callback then
  428. return textureCache:addImage(imageFilename)
  429. else
  430. textureCache:addImageAsync(imageFilename, callback)
  431. end
  432. end
  433. local fileUtils = cc.FileUtils:getInstance()
  434. function display.getImage(imageFilename)
  435. local fullpath = fileUtils:fullPathForFilename(imageFilename)
  436. return textureCache:getTextureForKey(fullpath)
  437. end
  438. function display.removeImage(imageFilename)
  439. textureCache:removeTextureForKey(imageFilename)
  440. end
  441. function display.loadSpriteFrames(dataFilename, imageFilename, callback)
  442. if display.TEXTURES_PIXEL_FORMAT[imageFilename] then
  443. cc.Texture2D:setDefaultAlphaPixelFormat(display.TEXTURES_PIXEL_FORMAT[imageFilename])
  444. end
  445. if not callback then
  446. spriteFrameCache:addSpriteFrames(dataFilename, imageFilename)
  447. else
  448. spriteFrameCache:addSpriteFramesAsync(dataFilename, imageFilename, callback)
  449. end
  450. if display.TEXTURES_PIXEL_FORMAT[imageFilename] then
  451. cc.Texture2D:setDefaultAlphaPixelFormat(cc.TEXTURE2_D_PIXEL_FORMAT_BGR_A8888)
  452. end
  453. end
  454. function display.removeSpriteFrames(dataFilename, imageFilename)
  455. spriteFrameCache:removeSpriteFramesFromFile(dataFilename)
  456. if imageFilename then
  457. display.removeImage(imageFilename)
  458. end
  459. end
  460. function display.removeSpriteFrame(imageFilename)
  461. spriteFrameCache:removeSpriteFrameByName(imageFilename)
  462. end
  463. function display.setTexturePixelFormat(imageFilename, format)
  464. display.TEXTURES_PIXEL_FORMAT[imageFilename] = format
  465. end
  466. function display.setAnimationCache(name, animation)
  467. animationCache:addAnimation(animation, name)
  468. end
  469. function display.getAnimationCache(name)
  470. return animationCache:getAnimation(name)
  471. end
  472. function display.removeAnimationCache(name)
  473. animationCache:removeAnimation(name)
  474. end
  475. function display.removeUnusedSpriteFrames()
  476. spriteFrameCache:removeUnusedSpriteFrames()
  477. textureCache:removeUnusedTextures()
  478. end
  479. return display